一个基础的光照模型(Phong,BlinnPhong,MatCap,CubeMap)

Shader "Unlit/AP12"
{
    Properties
    {
        [NoScaleOffset] _MainTex("MainTex",2D) = "white"{}
        [NoScaleOffset] _NormalTex("NormalTex",2D) = "Bump"{}
        [NoScaleOffset] _AmbientTex    ("AoTex",2D) = "White"{} 
        [NoScaleOffset] _CubeMap  ("CubeMap",Cube) = "Cube"
        [NoScaleOffset] _MatCap   ("MatCap",2D) = "White"{}
        _BaseColor("BaseColor",Color) = (1.0,1.0,1.0,1.0)
        [KeywordEnum(Phong,BlinnPhong)] _SpecularMode("SpecularMode",float) = 0
        _SpecularPow("SpecularPow",Range(1,80)) = 1
        _SpecularStrength("_SpecularStrength",Range(0,1)) = 0
        [KeywordEnum(CubeMap,MatCap)] _ReflectionMode("ReflectionMode",float) = 0
        _ReflectionColor("ReflectionColor",Color) = (1.0,1.0,1.0,1.0)
        _ReflectionMip("ReflectionMip",Range(0,8)) = 0
        _EnvironmentStrength("EnvironmentStrength",Range(0,1)) = 0
        _FresnelPow("FresnelPow",Range(0,10)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100
        CGINCLUDE
        //着色器入口
        #pragma vertex vert
        #pragma fragment frag
        //库调用
        #include "UnityCG.cginc"
        #include "Lighting.cginc"
        #include "AutoLight.cginc"
        //变量声明
        //----------------------------------------
        
        //贴图采样
        uniform sampler2D _MainTex;
        uniform sampler2D _NormalTex;
        uniform sampler2D _AmbientTex;
        uniform sampler2D _MatCap;
        uniform samplerCUBE _CubeMap;
        //----------------------------
        uniform float4 _BaseColor;
        //-----------------------------
        uniform float _SpecularPow;
        uniform float _SpecularStrength;
        //-----------------------------
        uniform float4 _ReflectionColor;
        uniform float _ReflectionMip;
        uniform float _FresnelPow;
        uniform float _EnvironmentStrength;

        //变体声明
        #pragma multi_compile_fog
        #pragma multi_compile_fwdbase
        #pragma shader_feature _SPECULARMODE_PHONG _SPECULARMODE_BLINNPHONG
        #pragma shader_feature _REFLECTIONMODE_CUBEMAP _REFLECTIONMODE_MATCAP
        ENDCG
        Pass
        {
            CGPROGRAM
            
            // make fog work
            



            struct appdata
            {
                float4 posOS : POSITION;
                float2 uv : TEXCOORD0;
                float3 normalOS:NORMAL;
                float4 tangentOS:TANGENT;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 pos : SV_POSITION;
                float3 posWS :TEXCOORD2;
                float3 normalOS:NORMAL;
                float4 tangentOS:TANGENT;
                SHADOW_COORDS(3)
            };


            v2f vert (appdata i)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(i.posOS);
                o.posWS = mul(unity_ObjectToWorld,i.posOS);
                o.uv = i.uv;
                o.normalOS = i.normalOS;
                o.tangentOS = i.tangentOS;
                TRANSFER_SHADOW(o);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //阴影
                float Shadow = LIGHT_ATTENUATION(i);//声明阴影
                //采样贴图
                float3 var_MainTex = tex2D(_MainTex,i.uv);
                float3 var_NormalTex = UnpackNormal(tex2D(_NormalTex,i.uv));//采样并解包法线贴图
                float3 var_AmbientTex = tex2D(_AmbientTex,i.uv);
                //准备向量
                float3 posWS = i.posWS;//世界空间顶点坐标
                float3 normalWS = normalize(UnityObjectToWorldNormal(i.normalOS));//世界空间法线坐标
                float3 tangentWS = UnityObjectToWorldDir(i.tangentOS);//世界空间切线向量
                float3 btangentWS = normalize(cross(tangentWS,normalWS) );//世界空间副切线向量,DX
                float3x3 TBN = float3x3(tangentWS.xyz,btangentWS.xyz,normalWS.xyz);//BNT矩阵
                normalWS = mul(var_NormalTex,TBN);//将法线贴图通过TBN矩阵转换
                float3 viewDirWS = normalize(_WorldSpaceCameraPos.xyz - posWS);//世界空间视向量
                float3 normalVS = normalize(mul(UNITY_MATRIX_V,normalWS));//视空间法线向量,用于MatCap的UV采样
                float3 lightDir = normalize(_WorldSpaceLightPos0).xyz;//主光源向量
                float3 rlightDir = reflect( -lightDir,normalWS);//主光源的反射向量,用于计算Phong的高光
                float3 halfAngle = normalize(lightDir + viewDirWS);//计算半角向量
                float4 CubeMapUV = float4(reflect(viewDirWS,normalWS),_ReflectionMip);//计算CubeMap的UV (视角的反射方向)并使用了Mipmap
                float4 MatCapUV = float4(normalVS.xy * 0.5 + 0.5,0,_ReflectionMip);//计算MatCap的UV (视空间的法线方向)并使用了Mipmap
                float Fresnel = pow(1 - dot(viewDirWS,normalWS),_FresnelPow);
                
                
                //光照模型
                float Lambert = dot(lightDir,normalWS);//兰伯特光照计算
                float HalfLmabert = Lambert * 0.5 + 0.5;//半兰伯特光照计算
                float Phong = max(0,dot(rlightDir , viewDirWS));//Phong光照计算
                float BlinnPhong = max(0,dot(normalWS,halfAngle));//BlinnPhong光照计算
                //切换高光模式
                float Specular;//声明高光变量
                #if _SPECULARMODE_PHONG //如果PHONG宏生效
                    Specular = Phong;//高光为Phong
                #elif _SPECULARMODE_BLINNPHONG//如果BLINNPHONG宏生效
                    Specular = BlinnPhong;//高光为BlinnPhong
                #endif//if结束
                Specular = pow(Specular,_SpecularPow) * _SpecularStrength;//计算高光POW和强度
                


                //环境光
                float3 SkyColor = unity_AmbientSky.rgb;//获取系统环境光顶部颜色
                float3 EquatorColor = unity_AmbientEquator.rgb;//获取系统环境光中间颜色
                float3 GroundColor = unity_AmbientGround.rgb;//获取系统环境光底部颜色
                SkyColor *= max(0,normalWS.y);//利用法线的Y方向给顶部赋值(因为有负数,所以要提前MAX掉)
                EquatorColor *= 1- (max(0,-normalWS.y) + max(0,normalWS.y));//利用(1-(y+-y))给侧边赋值(因为有负数,所以要提前MAX掉)
                GroundColor *= max(0,-normalWS.y);//利用-Y方向给底部赋值
                float3 AmbinetColor = SkyColor + EquatorColor + GroundColor;//将三个环境光相加得到一个整体的环境光

                
                //环境反射
                //--------------
                //Cube采样
                float3 CubeMap = texCUBElod(_CubeMap,CubeMapUV);//采样CubeMap
                //MatCap采样
                float3 MatCap = tex2Dlod(_MatCap,MatCapUV);//采样MatCap
                //切换Cubemap和MatCap
                float3 Reflection;//声明反射变量
                #if _REFLECTIONMODE_CUBEMAP//如果宏为CUBEMAP
                    Reflection = CubeMap;//反射为CubeMap
                #elif _REFLECTIONMODE_MATCAP//如果宏为MATCAP
                    Reflection = MatCap;//反射为MatCap
                #endif//if结束
                Reflection *= Fresnel * _ReflectionColor;//给反射赋予一个颜色
                
                //Albedo计算
                //Albedo = (颜色贴图+基础颜色+半兰伯特+高光) * 阴影 * 主灯光颜色
                float3 Albedo = (var_MainTex * _BaseColor * HalfLmabert  + Specular) * Shadow * _LightColor0.rgb;
                
              
                //Albedo = lerp(Albedo,Albedo * _LightColor0.rgb,Shadow);
                //环境计算
                //环境光 = (反射+环境光颜色) * AO贴图 * 环境强度
                float3 Environment = (Reflection  + AmbinetColor) * var_AmbientTex * _EnvironmentStrength;


                float3 finalRGB = Albedo + Environment;//最终颜色 = Albedo + 环境
                
                return float4(finalRGB,1);
            }
            ENDCG
        }
    }
    Fallback "Diffuse"
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值