庄懂TA Lesson10

Shader "Shader/OldschoolPlus"
{
    Properties
    {
        [Header(Texture)]                           //面板需要的参数
            _MainTex ("color texture", 2D) = "white"{}
            _NormTex ("normal texture",2D) = "bump" {}    
            _SpecTex ("specular texture", 2D) = "gray" {}
            _Cubemap ("cubemap",cube) = "_Skybox" {}
        [Header(Diffuse)]
            _MainCol ("main color", color) = (0.5, 0.5, 0.5, 1.0)
            _EnvDiffInt("diffuse intense", Range(0,1)) = 0.2
            _EnvUpCol   ("up color", Color) = (1.0, 1.0, 1.0, 1.0)
            _EnvSideCol ("sude color", Color)  = (0.5, 0.5, 0.5, 1.0)
            _EnvDownCol ("ground color", Color)  = (0.0, 0.0, 0.0, 0.0)
        [Header(Specular)]
            _SpecPow    ("specular power", Range(1, 90))  = 30
            _FresnelPow("FresnelPow",Range(0,10)) = 1
            _EnvSpecInt("EnvSpecInt",Range(0,5)) = 1
            _CubemapMip ("cubemap Mip", Range(1, 7)) = 1
        
    }
    SubShader
    {
        Tags {
            "RenderType"="Opaque"
        }
        
        Pass
        {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            // 追加投影相关包含文件
            #include "AutoLight.cginc"
            #include "Lighting.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0

            uniform sampler2D _MainTex;
            uniform sampler2D _NormTex;
            uniform sampler2D _SpecTex;
            uniform samplerCUBE _Cubemap;

            uniform float3 _MainCol;
            uniform float _EnvDiffInt;
            uniform float3 _EnvUpCol;
            uniform float3 _EnvSideCol;
            uniform float3 _EnvDownCol;

            uniform float _SpecPow;
            uniform float _FresnelPow;
            uniform float _EnvSpecInt;
            uniform float _CubemapMip;
            

            struct vertexInput
            {
                float4 vertex : POSITION;
                float4 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;
                LIGHTING_COORDS(5,6)
            };

            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);//切线和法线方向叉乘
                TRANSFER_VERTEX_TO_FRAGMENT(o)
                return o;
            }

            fixed4 frag (vertexOutput i) : SV_Target
            {
                // 准备向量
                float3 nDirTS = UnpackNormal(tex2D(_NormTex, i.uv)).rgb;
                float3x3 TBN = float3x3(i.tDirWS, i.bDirWS, i.nDirWS);
                float3 nDirWS = normalize(mul(nDirTS, TBN));
                float3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.posWS.xyz);
                float3 vrDirWS = reflect(-vDirWS, nDirWS);
                float3 lDirWS = _WorldSpaceLightPos0.xyz;
                float3 lrDirWS = reflect(-lDirWS, nDirWS);

                // 准备点积结果
                float ndotl = dot(nDirWS, lDirWS);
                float vdotr = dot(vDirWS, lrDirWS);
                float vdotn = dot(vDirWS, nDirWS);

                // 采样纹理
                float4 var_MainTex = tex2D(_MainTex, i.uv);
                float4 var_SpecTex = tex2D(_SpecTex, i.uv);
                float3 var_Cubemap = texCUBElod(_Cubemap, float4(vrDirWS, lerp(_CubemapMip, 0.0, var_SpecTex.a))).rgb;   
                //随着var_SpecTex.a的值cubemap的mip值在0到给定的_CubemapMip之间变化,如果var_SpecTex.a=0,那就是_CubemapMip,var_SpecTex.a=1,那就是0

                //直接光照           
                float3 baseCol = var_MainTex.rgb * _MainCol;
                float3 lambert = max(0.0, ndotl);

                float specCol = var_SpecTex.rgb;
                float specPow = lerp(1, _SpecPow, var_SpecTex.a);
                float phong = pow(max(0.0, vdotr),specPow);
                float shadow = LIGHT_ATTENUATION(i);
                float3 dirLighting = (baseCol * lambert + specCol * phong) * _LightColor0 * shadow;

                //环境光照
                float upMask = max(0.0, nDirWS.g);          // 获取朝上部分遮罩
                float downMask = max(0.0, -nDirWS.g);       // 获取朝下部分遮罩
                float sideMask = 1.0 - upMask - downMask;   // 获取侧面部分遮罩
                float3 envCol = _EnvUpCol * upMask +
                                _EnvSideCol * sideMask +
                                _EnvDownCol * downMask;     // 混合环境色

                float fresnel = pow(max(0.0, 1.0 - vdotn), _FresnelPow);    // 菲涅尔

                float occlusion = var_MainTex.a;

                float3 envLighting = (baseCol * envCol * _EnvDiffInt + var_Cubemap * fresnel * _EnvSpecInt * var_SpecTex.a) * occlusion;

                // 返回结果
                float3 finalRGB = dirLighting + envLighting;
                return float4(finalRGB, 1.0);
            }
            ENDCG
        }
    }
    FallBack  "Diffuse"
}

 

posted @ 2023-02-08 13:16  LOFU  阅读(29)  评论(0编辑  收藏  举报