光照着色器---镜面反射

镜面反射计算公式

float3 reflectVector=reflect(-lightDir,normal)---光线方向和法线方向求出反射方向

float specDot=max(dot(reflectionVector,eyeDir),0.0)---反射方向和眼睛方向求点积

float spec=pow(specDot,specExponent)---最后一个参数是镜面反射强度

1、设置反射颜色和反射强度的属性

        _SpecColor("Specular Matirals Color",Color)=(1,1,1,1)
        _Shiness("Shiness",float)=10

2、矩阵乘法转化为世界坐标系

            float _Shiness;            
v2f vert (appdata v) { v2f o; o.vertex
= UnityObjectToClipPos(v.vertex); o.vetexWorld = mul(unity_ObjectToWorld, v.vertex); }

3、正则化表示和计算

              fixed4 frag (v2f i) : SV_Target
                {
                float3 normalDirection = normalize(i.worldNormal);
                float3 viewDirection = normalize(UnityWorldSpaceViewDir(i.vetexWorld));
                float3 LightDirection = normalize(UnityWorldSpaceLightDir(i.vetexWorld));
                //漫反射
                float4 tex = tex2D(_DiffuseTex, i.UV);
                float nl = max(_Ambient, dot(normalDirection, _WorldSpaceLightPos0.xyz));
                //镜面反射
                float3 ReflectDirection = reflect(-LightDirection, normalDirection);
                float3 SpecularDot = max(0.0, dot(ReflectDirection, viewDirection));
                float3 Specular = pow(SpecularDot, _Shiness);
                float4 SpecularTerm = float4(Specular, 1)*_SpecColor*_LightColor0;

                float4 diffuseTerm = nl * tex*_Color*_LightColor0;
                float4 finalyColor = diffuseTerm + SpecularTerm;

                return finalyColor;
                }

完整代码:

Shader "Custom/SpecularShader"
{
    Properties
    {
        _Color("Color",Color) = (1,0,0,1)
        _DiffuseTex("Texture",2D) = "white"{}
        _Ambient("Ambient",Range(0,1))=0.25
        _SpecColor("Specular Matirals Color",Color)=(1,1,1,1)
        _Shiness("Shiness",float)=10

    }

        SubShader
    {
        Tags { "RenderType" = "Opaque" "LightMode" = "ForwardBase"}
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include"UnityLightingCommon.cginc"


            fixed4 _Color;
            sampler2D _DiffuseTex;
            float4 _DiffuseTex_ST;
            float _Ambient;
            float _Shiness;


            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal:Normal;
                float2 UV:TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal : TEXCOORD1;
                float2 UV:TEXCOORD0;
                float4 vetexWorld:TEXCOORD2;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.vetexWorld = mul(unity_ObjectToWorld, v.vertex);
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldNormal = worldNormal;
                o.UV = TRANSFORM_TEX(v.UV, _DiffuseTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float3 normalDirection = normalize(i.worldNormal);
                float3 viewDirection = normalize(UnityWorldSpaceViewDir(i.vetexWorld));
                float3 LightDirection = normalize(UnityWorldSpaceLightDir(i.vetexWorld));
                //漫反射
                float4 tex = tex2D(_DiffuseTex, i.UV);
                float nl = max(_Ambient, dot(normalDirection, _WorldSpaceLightPos0.xyz));
                //镜面反射
                float3 ReflectDirection = reflect(-LightDirection, normalDirection);
                float3 SpecularDot = max(0.0, dot(ReflectDirection, viewDirection));
                float3 Specular = pow(SpecularDot, _Shiness);
                float4 SpecularTerm = float4(Specular, 1)*_SpecColor*_LightColor0;

                float4 diffuseTerm = nl * tex*_Color*_LightColor0;
                float4 finalyColor = diffuseTerm + SpecularTerm;

                return finalyColor;
            }
            ENDCG
        }
    }
}

多光源完整代码:

Shader "Custom/SpecularShaderForwardAdd"
{
    Properties
    {
        _Color("Color",Color) = (1,0,0,1)
        _DiffuseTex("Texture",2D) = "white"{}
        _Ambient("Ambient",Range(0,1))=0.25
        _SpecColor("Specular Matirals Color",Color)=(1,1,1,1)
        _Shiness("Shiness",float)=10

    }

        SubShader
    {
        Pass
        {
            Tags { "RenderType" = "Opaque" "LightMode" = "ForwardBase"}
            LOD 100
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase

            #include "UnityCG.cginc"
            #include"UnityLightingCommon.cginc"


            fixed4 _Color;
            sampler2D _DiffuseTex;
            float4 _DiffuseTex_ST;
            float _Ambient;
            float _Shiness;


            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal:Normal;
                float2 UV:TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal : TEXCOORD1;
                float2 UV:TEXCOORD0;
                float4 vetexWorld:TEXCOORD2;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.vetexWorld = mul(unity_ObjectToWorld, v.vertex);
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldNormal = worldNormal;
                o.UV = TRANSFORM_TEX(v.UV, _DiffuseTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float3 normalDirection = normalize(i.worldNormal);
                float3 viewDirection = normalize(UnityWorldSpaceViewDir(i.vetexWorld));
                float3 LightDirection = normalize(UnityWorldSpaceLightDir(i.vetexWorld));
                //漫反射
                float4 tex = tex2D(_DiffuseTex, i.UV);
                float nl = max(_Ambient, dot(normalDirection, _WorldSpaceLightPos0.xyz));
                //镜面反射
                float3 ReflectDirection = reflect(-LightDirection, normalDirection);
                float3 SpecularDot = max(0.0, dot(ReflectDirection, viewDirection));
                float3 Specular = pow(SpecularDot, _Shiness);
                float4 SpecularTerm = float4(Specular, 1)*_SpecColor*_LightColor0;

                float4 diffuseTerm = nl * tex*_Color*_LightColor0;
                float4 finalyColor = diffuseTerm + SpecularTerm;

                return finalyColor;
            }
            ENDCG
        }

        Pass
        {
            Tags { "RenderType" = "Opaque" "LightMode" = "Forwardadd"}
            Blend one one
            LOD 100
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdadd

            #include "UnityCG.cginc"
            #include"UnityLightingCommon.cginc"


            fixed4 _Color;
            sampler2D _DiffuseTex;
            float4 _DiffuseTex_ST;
            float _Ambient;
            float _Shiness;


            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal:Normal;
                float2 UV:TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal : TEXCOORD1;
                float2 UV:TEXCOORD0;
                float4 vetexWorld:TEXCOORD2;
            };

            v2f vert(appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.vetexWorld = mul(unity_ObjectToWorld, v.vertex);
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                o.worldNormal = worldNormal;
                o.UV = TRANSFORM_TEX(v.UV, _DiffuseTex);
                return o;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                float3 normalDirection = normalize(i.worldNormal);
                float3 viewDirection = normalize(UnityWorldSpaceViewDir(i.vetexWorld));
                float3 LightDirection = normalize(UnityWorldSpaceLightDir(i.vetexWorld));
                //漫反射
                float4 tex = tex2D(_DiffuseTex, i.UV);
                float nl = max(0.0, dot(normalDirection, _WorldSpaceLightPos0.xyz));
                //镜面反射
                float3 ReflectDirection = reflect(-LightDirection, normalDirection);
                float3 SpecularDot = max(0.0, dot(ReflectDirection, viewDirection));
                float3 Specular = pow(SpecularDot, _Shiness);
                float4 SpecularTerm = float4(Specular, 1)*_SpecColor*_LightColor0;

                float4 diffuseTerm = nl * tex*_Color*_LightColor0;
                float4 finalyColor = diffuseTerm + SpecularTerm;

                return finalyColor;
            }
            ENDCG
        }
    }
}
原文地址:https://www.cnblogs.com/Optimism/p/11342398.html