Unity 光照着色器

 

光照着色器需要考虑光照的分类,一般分为漫反射和镜面反射。

 

漫反射计算基本光照:

float brightness=dot(normal,lightDir)    将法线和光的入射方向进行点积运算,求出光的亮度。

float3 pixelColor=brightness*lightColor*surfaceColor  将光的亮度*光的颜色*物体表面颜色得到我们最终看到的颜色。

 

Shader "Unlit/DiffuseShader"
{
    Properties
    {
       _Color("Color",Color)=(1,0,0,1)
    }
    SubShader
    {
        #新加了光照模式标签
        Tags { "RenderType"="Opaque"  "LightMode"="ForwardBase"}
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

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

            fixed4 _Color;

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal:NORMAL;                        #法线方向
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal:TXCOORD0;                #

            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                float3 worldNormal=UnityObjectToWorldNormal(v.normal);
                o.worldNormal=worldNormal;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float3 normalDirection=normalize(i.worldNormal);
                float nl=max(0.0,dot(normalDirection,_WorldSpaceLightPos0.xyz));
                float4 diffusTerm=nl*_Color*_LightColor0;
                return diffusTerm;
            }
            ENDCG
        }
    }
}

 

镜面反射具体实现:

R=2*(N*L)*N-L;

float3 reflectionVector=reflect(-lightDir,normal);                 //用入射光线方向和法线求出反射光线方向

float specDot=max(dot(reflectionVector,eyeDir),0.0);        //反射光线和眼睛入射方法求点积

float spec=pow(specDot,spectExponent);

            fixed4 frag (v2f i) : SV_Target
            {
                //标准化法向量
                float3 normalDirection=normalize(i.worldNormal);
                float3 viewDirection=normalize(UnityWorldSpaceViewDir(i.vertexWorld));
                float3 lightDirection=normalize(UnityWorldSpaceViewDir(i.vertexWorld));
                
                //采样纹理
                float4 tex=tex2D(_DiffuseTex,i.uv);

                //漫反射计算,使用兰帕特近似方法lambert
                float nl=max(0.0,dot(normalDirection,_WorldSpaceLightPos0.xyz));
                float4 diffusTerm=nl*_Color*_LightColor0;

                //镜面反射计算,使用芳式近似方法Phong
                float3 reflectionDirection=reflect(-lightDirection,normalDirection);
                float3 specularDot=max(0.0,dat(viewDirection,reflectionDirection));
                float3 specular=pow(specularDot,_shininess);

                //计算最终的颜色
                float4 specularTerm=float4(specular,1)*_SpacColor*_LightColor;
                float4 finalColor=diffusTerm*specularTerm;

                return finalColor;

 

posted @ 2019-03-21 08:31  彩色的梦  阅读(477)  评论(0编辑  收藏  举报