【Unityshader】漫反射光照学模型

基本光照漫反射计算公式:

C[diffuse] = (C[light]*m[diffuse]max(0,n·l) )

C[light]为光源颜色和强度,可以由lighting.cginc中的_LightColor0提供

m[diffuse]为材质反射系数,一般自己定义在properties中

n为表面法线,l为光源方向。 其中n由NORMAL提供,l由_WorldSpaceLightPos0提供。

逐像素光照:

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/Chapter-DiffuseVertexLevel"
{
    Properties{
        _Diffuse ("Diffuse",Color) = (1,1,1,1)
    }
    SubShader{
        Pass{
            Tags{"LightMode" = "ForwardBase"
            }
             CGPROGRAM  //定义顶点着色器和片元着色器函数名称
            #pragma vertex vert
            #pragma fragment frag
            #include "Lighting.cginc"

            fixed4 _Diffuse;   //Cg代码中必须有一个和属性中名称类型相匹配的变量

            struct a2v{
                float4 vertex:POSITION;  //模型空间顶点坐标填充vertex
                float3 normal:NORMAL;     //模型空间法线方向填充normal
            };
            struct v2f{
                float4 pos:SV_POSITION;   //告诉unity pos中有顶点在裁剪空间中的位置信息  需要计算
                float3 worldNormal:TEXCOORD0; //世界坐标中的法线方向
            };

            v2f vert(a2v v){
                v2f o;
                
                o.pos = UnityObjectToClipPos(v.vertex);//将模型空间中的坐标转化为裁剪空间
                o.worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject));  //将模型空间中的法线乘以逆矩阵并调换变量位置,即可得到乘以转置逆矩阵的效果->求出世界空间下的坐标

                return o;
            }
            fixed4 frag(v2f i):SV_Target{
                fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //环境光
                
                 fixed3 worldNormal = normalize(i.worldNormal);

                 fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); 

                 fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal,worldLightDir));//saturate函数来控制参数在[0,1]的范围内,防止物体被后面来的光照亮
                 
                 fixed3 color = ambient+diffuse;  //叠加环境光与漫反射光
                 return fixed4(color,1.0);

            }
        ENDCG
        }
    }
    FallBack "Diffuse"
}

其中逐顶点计算即是在顶点着色器中计算漫反射需要的变量,片元着色器只负责输出颜色即可。

上一篇:Unity #pragma multi_compile说明


下一篇:Unity Shader入门总结(一)