气泡shader_ShaderLab学习小结(十六)泡泡

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值