unity shader 菲尼尔 模拟水晶透明

用菲尼尔模拟透明水晶效果,实际上并没有透明

具体思路看shader注释:

Shader "Fresnel_ShuiJingLong"
{
	Properties
	{
		_CubeTex ("CubeTex", CUBE) = "white" {}
		_FresnelBias("FresnelBias", range(0,1)) = 0
		_FresnelScale("FresnelScale", range(0,1)) = 0
		_FresnelPow("FresnelPow", range(0,5)) = 1
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			tags{"lightmode" = "forwardbase"}//能与一个平行光或者点光源进行计算

			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"
			
			#include "UnityCG.cginc"

			/*
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;

			};
			*/

			struct v2f
			{
				float3 refr_r : TEXCOORD0;
				float3 refr_g : TEXCOORD1;
				float3 refr_b : TEXCOORD2;

				float3 L : TEXCOORD3;//光向量
				float3 N : TEXCOORD4;//法向量
				float3 V : TEXCOORD5;//视向量
				
				float4 vertex : SV_POSITION;
			};

			samplerCUBE _CubeTex;

			float _FresnelBias;
			float _FresnelScale;
			float _FresnelPow;
			
			v2f vert (appdata_base v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);//UnityObjectToClipPos(v.vertex);
				float3 i = WorldSpaceViewDir(v.vertex);//传入的是模型顶点 - 模型顶点指向眼睛的向量 - 世界空间
				i = -normalize(i);

				o.V = -i;

				float3 n = mul(float4(v.normal,0), unity_WorldToObject).xyz;
				n = normalize(n);

				o.N = n;//世界空间

				o.refr_r = refract(i,n, 0.96);//入射- 眼睛到顶点的向量,法向量,偏转率
				o.refr_g = refract(i,n, 0.98);
				o.refr_b = refract(i,n, 1);
				
				o.L = normalize( WorldSpaceLightDir(v.vertex));//得到光向量

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target//插值,顶点中规范化的向量仍然要再规范化
			{
				// sample the texture
				fixed4 col;
				col.r = texCUBE(_CubeTex, i.refr_r).r;
				col.g = texCUBE(_CubeTex, i.refr_g).g;
				col.b = texCUBE(_CubeTex, i.refr_b).b;

				float diff = max(0, dot(i.N, i.L));

				float3 H = normalize(i.L + i.V);//半角向量
				float spec = pow(max(0, dot(i.N, H)) , 64);

				

				col.a = 1;
				col = col * _LightColor0 * diff + _LightColor0 * spec;

				float fresnel = _FresnelBias + _FresnelScale * pow(1+dot(-H, i.N), _FresnelPow);
				col = lerp(col, _LightColor0, fresnel);

				return col;
			}
			ENDCG
		}



		
		//######################### add通道


		Pass
		{
			tags{"lightmode" = "forwardadd"}//能与一个平行光或者点光源进行计算
			blend one one
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"
			
			#include "UnityCG.cginc"

			/*
			struct appdata
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;

			};
			*/

			struct v2f
			{
				float3 refr_r : TEXCOORD0;
				float3 refr_g : TEXCOORD1;
				float3 refr_b : TEXCOORD2;

				float3 L : TEXCOORD3;//光向量
				float3 N : TEXCOORD4;//法向量
				float3 V : TEXCOORD5;//视向量
				
				float4 vertex : SV_POSITION;
			};

			samplerCUBE _CubeTex;

			float _FresnelBias;
			float _FresnelScale;
			float _FresnelPow;
			
			v2f vert (appdata_base v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);//UnityObjectToClipPos(v.vertex);
				float3 i = WorldSpaceViewDir(v.vertex);//传入的是模型顶点 - 模型顶点指向眼睛的向量 - 世界空间
				i = -normalize(i);

				o.V = -i;

				float3 n = mul(float4(v.normal,0), unity_WorldToObject).xyz;
				n = normalize(n);

				o.N = n;//世界空间

				o.refr_r = refract(i,n, 0.96);//入射- 眼睛到顶点的向量,法向量,偏转率
				o.refr_g = refract(i,n, 0.98);
				o.refr_b = refract(i,n, 1);
				
				o.L = normalize( WorldSpaceLightDir(v.vertex));//得到光向量

				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target//插值,顶点中规范化的向量仍然要再规范化
			{
				// sample the texture
				fixed4 col;
				col.r = texCUBE(_CubeTex, i.refr_r).r;
				col.g = texCUBE(_CubeTex, i.refr_g).g;
				col.b = texCUBE(_CubeTex, i.refr_b).b;

				float diff = max(0, dot(i.N, i.L));

				float3 H = normalize(i.L + i.V);//半角向量
				float spec = pow(max(0, dot(i.N, H)) , 64);

				

				col.a = 1;
				col = col * _LightColor0 * diff + _LightColor0 * spec;

				float fresnel = _FresnelBias + _FresnelScale * pow(1+dot(-H, i.N), _FresnelPow);
				col = lerp(col, _LightColor0, fresnel);

				return col;
			}
			ENDCG
		}
		
	}
}

你可能感兴趣的:(unity shader 菲尼尔 模拟水晶透明)