庄懂TA Lesson9
matcap 代码实现
Shader "Shader/Matcap" { Properties { _NormalMap("normalmap",2D) = "bump" {} //面板需要的参数 _Matcap("matcap",2D) = "gray" {} _FresnelPow("FresnelPow",Range(0,10)) = 1 _EnvSpecInt("EnvSpecInt",Range(0,5)) = 1 } SubShader { Tags { "RenderType"="Opaque" } Pass { Name "FORWARD" Tags { "LightMode"="ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #pragma multi_compile_fwdbase_fullshadows #pragma target 3.0 uniform sampler2D _NormalMap; //声明变量 uniform sampler2D _Matcap; uniform float _FresnelPow; uniform float _EnvSpecInt; struct vertexInput { float4 vertex : POSITION; float3 normal : NORMAL; float2 uv0 : TEXCOORD0; float4 tangent : TANGENT; //切线信息 }; struct vertexOutput { float4 pos :SV_POSITION; //注意!此处必须命名为pos,需要和Unity封装好的方法的参数对应 float4 posWS : TEXCOORD0; float3 nDirWS : TEXCOORD1; float3 tDirWS : TEXCOORD2; float3 bDirWS : TEXCOORD3; //世界副切线方向 float2 uv : TEXCOORD4; }; vertexOutput vert (vertexInput v) { vertexOutput o = (vertexOutput)0;; o.pos = UnityObjectToClipPos(v.vertex); o.posWS = mul(unity_ObjectToWorld, v.vertex); o.nDirWS = UnityObjectToWorldNormal(v.normal); o.uv = v.uv0; o.tDirWS = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz,0.0)).xyz); o.bDirWS = normalize(cross(o.nDirWS, o.tDirWS) * v.tangent.w);//切线和法线方向叉乘 return o; } fixed4 frag (vertexOutput i) : SV_Target { float3 nDirTS = UnpackNormal(tex2D(_NormalMap, i.uv)).rgb; float3x3 TBN = float3x3(i.tDirWS, i.bDirWS, i.nDirWS); float3 nDirWS = normalize(mul(nDirTS, TBN)); float3 nDirVS = mul(UNITY_MATRIX_V, nDirWS); float3 vDirWS = normalize(_WorldSpaceCameraPos.xyz-i.posWS.xyz); float3 vrDirWS = reflect(-vDirWS, nDirWS); //中间变量 float2 matcapUV = nDirWS.rg * 0.5+0.5; float ndotv = dot(vDirWS, nDirWS); //光照 float3 matcap = tex2D(_Matcap, matcapUV); float fresnel = pow(max(0.0, 1.0- ndotv), _FresnelPow); float3 envSpecLighting = matcap * fresnel * _EnvSpecInt; return float4(envSpecLighting, 1.0); } ENDCG } } FallBack "Diffuse" }