庄懂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"
}

 

 

posted @ 2023-02-07 12:22  LOFU  阅读(13)  评论(0编辑  收藏  举报