ShaderLab学习小结(十六)泡泡
发布时间:2020-06-08 07:02:02
来源:51CTO
阅读:1874
一个球体,不论从哪去看,都是中心透明,向边上越来越不透,最后纯白,大概就像个泡泡一样
效果如下图:
先看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