The texture and normal of the inner edge of the model

There are a lot of work and study tasks recently, and I haven't written a blog for a long time.

Today, I wrote a Shader of "the texture and normal of the edge light band in the model". Share it with everyone here, you can use it directly if you need it. The flaw is that the point light source has not been calculated yet.

Shader "Custom/RimLight_UV_Bump" {
	Properties{
		_Color("Color Tint",Color)=(1,1,1,1)
		_MainTex("Main Tex",2D)="white"{}
		_BumpMap("Normal Map",2D)="bump"{}
		_BumpScale("Bump Scale",Float)=1
		_Specular("Specular",Color)=(1,1,1,1)
		_Gloss("Gloss",Range(8,256))=20
		_RimColor("RimColor", color) = (1,1,1,1)
		_RimStrength("RimStrength", Range(0.0001,3.0))=0.1
	}
	SubShader{
	Pass{
		Tags{"LightMode"="ForwardBase"}
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#include "Lighting.cginc"

		fixed4 _Color;
		sampler2D _MainTex;
		float4 _MainTex_ST;
		sampler2D _BumpMap;
		float4 _BumpMap_ST;
		float _BumpScale;
		fixed4 _Specular;
		float _Gloss;
		float3 wo;
		fixed4 _RimColor;
		float _RimStrength;

		//Appction To Vertex
		struct a2v{
			float4 vertex:POSITION;
			float3 normal:NORMAL;
			float4 tangent:TANGENT;
			float4 texcoord:TEXCOORD0;
		};
		//Vertex To Fragment
		struct v2f{
			float4 pos:SV_POSITION;
			float4 uv:TEXCOORD0;
			float4 TtoW0:TEXCOORD1;
			float4 TtoW1:TEXCOORD2;
			float4 TtoW2:TEXCOORD3;
		};

		v2f vert(a2v v){
			v2f o;
			o.pos=UnityObjectToClipPos(v.vertex);
			o.uv.xy=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
			o.uv.zw=v.texcoord.xy*_BumpMap_ST.xy+_BumpMap_ST.zw;

			//世界坐标下顶点、法线、切线、副切线位置
			float3 worldpos=mul(unity_ObjectToWorld,v.vertex).xyz;
			float3 worldNormal = UnityObjectToWorldNormal(v.normal);
			float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
			float3 worldBinormal = cross(worldNormal,worldTangent)*v.tangent.w;

			//按列排序得到一个切线到世界空间转换矩阵 ,位置信息也顺带存在后面了
			o.TtoW0=float4(worldTangent.x,worldBinormal.x,worldNormal.x,worldpos.x);
			o.TtoW1=float4(worldTangent.y,worldBinormal.y,worldNormal.y,worldpos.y);
			o.TtoW2=float4(worldTangent.z,worldBinormal.z,worldNormal.z,worldpos.z);

			return o;
		}

		float4 frag(v2f i):SV_TARGET{
			//世界坐标下的位置、灯光方向、摄像机方向等信息
			float3 worldPos= float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w);
			float3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
			float3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));

			//取得纹素
			fixed3 bump = UnpackNormal(tex2D(_BumpMap,i.uv.zw));
			bump.xy*=_BumpScale;
			bump.z=sqrt(1.0-saturate(dot(bump.xy,bump.xy)));
			//用点乘与每一组相乘,得到的是每个分量位移到该空间的位置
			//这句其实相当于:mul(half3X3(i.TtoW0.xyz,i.TtoW1.xyz,(i.TtoW2.xyz),bump)
			bump=normalize(half3(dot(i.TtoW0.xyz,bump),dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump)));

			//取主图的颜色*影响色
			fixed3 albedo=tex2D(_MainTex,i.uv).rgb*_Color.rgb;
			//环境光颜色*albedo
			fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;
			//灯光一颜色*环境色*亮度
			fixed3 diffuse=_LightColor0.rgb*albedo*max(0,dot(bump,lightDir));

			//中线:点到灯光方向+点到摄像机方向:取的是中线
			fixed3 halfDir = normalize(lightDir+viewDir);
			//中线与法线越相似则越亮
			fixed3 specular =_LightColor0.rgb*_Specular.rgb*pow(max(0,dot(bump,halfDir)),_Gloss);

			//世界坐标顶点法线向量
			fixed3 worldNormal = normalize(float3(i.TtoW0.z,i.TtoW1.z,i.TtoW2.z));
			//世界坐标摄像机视角
			fixed3 worldViewDir = normalize(viewDir);
			//法向量与摄像机视角越垂直边缘光越亮
			float rim = 1 - max(0, dot(worldViewDir,worldNormal));
			fixed3 rimColor = _RimColor * pow(rim, 1 / _RimStrength);

			//得到最终色值
			return fixed4(rimColor +diffuse+ambient+specular,1.0);
		}
		ENDCG
	}
	}
}

Guess you like

Origin blog.csdn.net/ww1351646544/article/details/102506808