光照衰减-Lights

Shader "QStudyShader/Lights"
{
    Properties
    {
        _MainTex("Main Texture", 2D) = "white" {}
        _BaseColor("Base Color", Color) = (1.0,1.0,1.0,1.0)
        _Gloss("Gloss", Range(8.0,200.0)) = 20.0
        _Scale("Scale",Range(0,1)) = 1.0
    }
        SubShader
        {
            Tags{"Queue" = "Geometry"}
            Pass{
                Tags{ "LightMode" = "ForwardBase" }
                CGPROGRAM
                    #include "Lighting.cginc"
                    #include "UnityCG.cginc"
                    #pragma vertex Vertex
                    #pragma fragment Fragment
            //只有分别为BasePass和AddPase 设置 #progma multi_compile_fwdbase 和 #pragma multi_compile_fwdadd 
            //然后才可以在Pass语句块中得到正确的光照变量(后续需要研究)
            #pragma multi_compile_fwdbase
            struct a2v {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float4 texcoord : TEXCOORD0;
            };
            struct v2f {
                float4 pos : SV_POSITION;
                float3 worldNormal : TEXCOORD0;
                float3 worldPos : TEXCOORD1;
                float2 uv : TEXCOORD2;
            };
            sampler2D _MainTex;
            float4 _BaseColor;
            float _Gloss;
            float _Scale;
            v2f Vertex(a2v v) {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldPos = mul(unity_ObjectToWorld,v.vertex);
                o.uv = v.texcoord;
                return o;
            }
            fixed4 Fragment(v2f i) : SV_TARGET{
                float3 worldNormal = normalize(i.worldNormal);
                float3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
                float3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
                //混合
                fixed3 albedo = tex2D(_MainTex,i.uv).xyz * _BaseColor.xyz;
                //环境光
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
                //漫反射
                fixed3 diffuse = _LightColor0.xyz * albedo * saturate(dot(lightDir,worldNormal));
                //半角向量
                fixed3 halfDir = normalize(viewDir + lightDir);
                //高光
                fixed3 specular = _LightColor0.xyz * pow(saturate(dot(halfDir,worldNormal)),_Gloss);
                //光照衰减
                fixed atten = 1.0;
                //计算光照衰减 = 环境光 + (高光+漫反射) * 光照衰减系数
                return fixed4(ambient + (specular + diffuse) * atten,1.0);
            }
        ENDCG
    }
    Pass{
        Tags{"LightMode" = "ForwardAdd"}
        // 开启混合 设置线性混合 叠加
        Blend One One
    CGPROGRAM
        #include "Lighting.cginc"
        #include "UnityCG.cginc"
        #include "AutoLight.cginc"
        #pragma vertex Vertex1
        #pragma fragment Fragment1
        #pragma multi_compile_fwdadd

        struct a2v {
            float4 vertex : POSITION;
            float3 normal : NORMAL;
            float4 texcoord : TEXCOORD0;
        };

        struct v2f {
            float4 pos : SV_POSITION;
            float3 worldNormal : TEXCOORD0;
            float3 worldPos : TEXCOORD1;
            float2 uv : TEXCOORD2;
        };
        sampler2D _MainTex;
        fixed4 _BaseColor;
        float _Gloss;
        v2f Vertex1(a2v v) {
            v2f o;
            o.pos = UnityObjectToClipPos(v.vertex);
            o.worldNormal = UnityObjectToWorldNormal(v.normal);
            o.worldPos = mul(unity_ObjectToWorld,v.vertex);
            o.uv = v.texcoord;
            return o;
        }
        fixed4 Fragment1(v2f i) : SV_TARGET{
            fixed3 worldNormal = normalize(i.worldNormal);
        //如果是平行光 
        #ifdef USING_DIRECTIONAL_LIGHT
            fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
            //如果不是平行光则 关照方向就为光源方向向量 - 模型位置向量
            #else
                fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos);
            #endif

            fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));

            fixed3 albedo = tex2D(_MainTex,i.uv).xyz * _BaseColor.xyz;
            //漫反射 光源强度 * cos0 cos0 = 光源方向向量 dot 模型法线向量
            fixed3 diffuse = _LightColor0.xyz * albedo * saturate(dot(lightDir,worldNormal));
            //半程向量 = 光源方向向量 + 视角向量 由于半程向量内部实现需要光源方向的反向量 而光源方向向量应该 = 光源方向向量 - 模型位置向量 

            fixed3 halfDir = normalize(viewDir + lightDir);
            //高光 BelinnPhone模型                    
            fixed3 specular = _LightColor0.xyz * pow(saturate(dot(halfDir,worldNormal)),_Gloss);

            #ifdef USING_DIRECTIONAL_LIGHT
            //无光照衰减
            fixed atten = 1.0;
        #else
            //如果是点光源
            #if defined(POINT)
            //unity_WorldToLight矩阵 = 模型空间变换到光源空间矩阵
            float3 lightCoord = mul(unity_WorldToLight,float4(i.worldPos,1)).xyz;
            //光照衰减 对点光源采样_LightTexture0 Dot(光源,光源)计算在光源空间下到原点的距离 .rr 构建一个二维采样坐标 
            //如果是点光源 _LightTexture0 = 基于距离的采样纹理
            //UNITY_ATTEN_CHANNEL = 基于平台选择 一般是r通道
            fixed atten = tex2D(_LightTexture0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;

            #elif defined(SPOT)
            //如果是聚光灯 _LightTexture0 = 基于张角范围的采样纹理
            float4 lightCoord = mul(unity_WorldToLight,float4(i.worldPos,1));
            //聚光灯 光源衰减
            fixed atten = (lightCoord.z > 0) * tex2D(_LightTexture0,lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;

            #endif
        #endif

        return fixed4((specular + diffuse) * atten,1.0);
    }

ENDCG
}
        }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值