ShaderLab学习小结(十六)泡泡
  5WVVrgL6K2nc 2023年11月02日 19 0

一个球体,不论从哪去看,都是中心透明,向边上越来越不透,最后纯白,大概就像个泡泡一样 效果如下图: 先看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 OneMinusSrcAlpha    //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 OneMinusSrcAlpha    //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 OneMinusSrcAlpha
			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

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  jo5M4GCiOHdG   2023年11月12日   18   0   0 Unity教程Unity
5WVVrgL6K2nc