ShaderLab学习小结(十六)泡泡
一个球体,不论从哪去看,都是中心透明,向边上越来越不透,最后纯白,大概就像个泡泡一样
效果如下图:
先看shader代码:
Shader "Custom/PaoPao" { //1. Properties{ _MainColor("Main",color)=(1,1,1,1) _Scale("Scale",range(1,8))=1 } SubShader { Tags{"queue"="Transparent"} //2. pass{ blend SrcAlpha OneMinu***cAlpha //3. CGPROGRAM #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" #include "lighting.cginc" fixed4 _MainColor; float _Scale; struct v2f{ float4 pos:POSITION; float3 normal:NORMAL; float3 wpos:TEXCOORD0; }; v2f vert(appdata_base v) { v2f o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.normal=v.normal; o.wpos=mul(unity_ObjectToWorld,v.vertex).xyz; //4. return o; } fixed4 frag(v2f IN):COLOR { float3 N = UnityObjectToWorldNormal(IN.normal); float3 V = normalize(UnityWorldSpaceViewDir(IN.wpos)); //5. float bright = pow(1-saturate(dot(N,V)),_Scale); //6. fixed4 col=_MainColor; col.a*=bright; //7. return col; } ENDCG } }}
按照代码中的注释
1定义一个主颜色和一个系数
//1. Properties{ _MainColor("Main",color)=(1,1,1,1) _Scale("Scale",range(1,8))=1 }
2、3
很明显,物体是半透明的,所以
Tags{"queue"="Transparent"} //2.
blend SrcAlpha OneMinu***cAlpha //3.
不用多解释
4求个世界坐标
o.wpos=mul(unity_ObjectToWorld,v.vertex).xyz; //4.
5
计算世界空间中的视向量V
float3 V = normalize(UnityWorldSpaceViewDir(IN.wpos)); //5.
6、7
获取透明度alpha的系数,本例中是1乘这个系数,可以认为这个就是alpha
float bright = pow(1-saturate(dot(N,V)),_Scale); //6.
col.a*=bright; //7.
泡泡的形成主要就看这一句了
据我的理解(未必准确)
我们的视线是垂直屏幕的,视向量方向垂直屏幕向外
再看球体
球体的法线方向是垂直球体表面向外的,那么不论我们从哪个角度去看一个球体,它中心的法线是垂直屏幕向外的
即和我们的视向量平行,且方向一至
根据向量点积的定义,两个向量点积等于两个向量长度相乘再乘上两个向量的夹角余弦
既然两个向量方向一样,夹角余弦得1,而两个向量都是单位向量,所以结果就是夹角余弦。
我们要让中心的透明度为0,所以就得1-saturate(dot(N,V)),然后pow函数求得0的_Scale次方还是0
最后乘以主颜色的alpha值,还是为0,最终得到的颜色是全透明的
同样,球体边缘的法向量平行于屏幕,也就是和视向量垂直,那么两个的点积得0,被1减得1
1的_Scale次方还是1,最后边缘的alpha值就是1,也就是不透明
这样就形成了这个泡泡,而且不论从什么方向看都一样
当然,如果想让这个泡泡接收平行光和环境光的影响,也可以
代码:
Shader "Custom/PaoPao" { Properties{ _MainColor("Main",color)=(1,1,1,1) _Scale("Scale",range(1,8))=1 } SubShader { Tags{"queue"="Transparent"} pass{ tags{"lightmode"="forwardbase"} //1. blend SrcAlpha OneMinu***cAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" #include "lighting.cginc" fixed4 _MainColor; float _Scale; struct v2f{ float4 pos:POSITION; float3 normal:NORMAL; float3 wpos:TEXCOORD0; }; v2f vert(appdata_base v) { v2f o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.normal=v.normal; o.wpos=mul(unity_ObjectToWorld,v.vertex).xyz; return o; } fixed4 frag(v2f IN):COLOR { float3 N = UnityObjectToWorldNormal(IN.normal); float3 V = normalize(UnityWorldSpaceViewDir(IN.wpos)); float bright = pow(1-saturate(dot(N,V)),_Scale); fixed4 col=_MainColor; float3 L = normalize(UnityWorldSpaceLightDir(IN.wpos));//2. col*=_LightColor0*saturate(dot(N,L)); //3. col+=UNITY_LIGHTMODEL_AMBIENT; //4。 col.a*=bright; //5. return col; } ENDCG } }}
1
光照模式forwardbase
2世界坐标系光向量
3平行光照
4加上环境光
5乘上alpha系数
效果如下图:
我们转动平行光
我们拖动材质的_Scale
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。