Unity shader学习之逐顶点漫反射光照模型
公式如下:
Cdiffuse = Clight * mdiffuse * max(0, dot(n,l));
其中,n 为表面法线,l 为指向光源的单位向量,mdiffuse 为材质温反射颜色,Cdiffuse 为光源颜色。
需要注意的是,需要防止法线与光源方向点积为负,因些使用max函数。
转载请注明出处:http://www.cnblogs.com/jietian331/p/7068273.html
shader如下:
Shader "Custom/Diffuse Vertex-Level" { Properties { _Diffuse ("Diffuse", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Tags { "LightMode"="ForwardBase" } // 只有设置了正确的LightMode,才能访问一些Unity提供的内置变量,如:_LightColor0 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct appdata { float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; }; float4 _Diffuse; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); // 在模型空间中计算 float3 lightDir = ObjSpaceLightDir(v.vertex); lightDir = normalize(lightDir); float4 diffuseColor = _Diffuse * _LightColor0 * max(0, dot(lightDir, v.normal)); // 也可以世界坐标中计算 //float3 worldNormal = normalize(mul(v.normal, (float3x3)_World2Object)); // 使用顶点变换矩阵的逆转置矩阵来变换法线,参考前面的章节“法线变换” //float3 worldLight = normalize(_WorldSpaceLightPos0.xyz); //float4 diffuseColor = _Diffuse * _LightColor0 * saturate(dot(worldNormal, worldLight)); o.color = UNITY_LIGHTMODEL_AMBIENT + diffuseColor; return o; } fixed4 frag (v2f i) : SV_Target { return i.color; } ENDCG } } Fallback "Diffuse" }
效果如下: