一个球体,不论从哪去看,都是中心透明,向边上越来越不透,最后纯白,大概就像个泡泡一样
效果如下图:

先看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