标准光照模型-半兰伯特模型

        Valve公司在《半条命》中提出了一种技术,叫做半兰伯特光照模型

        c_{diffuse}=(c_{light}\cdot m_{diffuse})(0.5(\dot{n}\cdot \dot{l})+0.5)

        通过这个方式,可以把点积的结果从[-1,1]到[0,1]范围内,也就是说,对于模型的背光面,从原模型中点积结果会映射到同一个值,即0处;而在半兰伯特模型中,背光面也可以有明暗变化,不同的点积结果会映射到不同的值上。

        标准光照模型-半兰伯特模型_第1张图片

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'

//半兰伯特
Shader "HalfLambert"
{
	Properties
	{
		_Diffuse("Diffuse", Color) = (1,1,1,1)
	}

	SubShader
	{
		Pass
		{
			Tags{"LightModel" = "ForwardBase"}

			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			#include "Lighting.cginc"

			float4 _Diffuse;

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

			struct v2f
			{
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
			};

			v2f vert(a2v v)
			{
				v2f o;

				//转换顶点从模型空间到裁剪空间
				o.pos = UnityObjectToClipPos(v.vertex);
				//转换法线从模型空间到世界空间
				o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);

				return o;
			}

			fixed4 frag(v2f o) : SV_TARGET
			{
				//获取环境光
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				//获取法线
				float3 normal = normalize(o.worldNormal);
				//获取世界空间的直射光
				float3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
				//计算半兰伯特
				fixed halfLambert = dot(normal, worldLight) * 0.5 + 0.5;
				//计算漫反射光
				fixed3 diffuse = _Diffuse.rgb * _LightColor0.rgb * halfLambert;

				return fixed4(diffuse + ambient, 1);
			}

		ENDCG
		}

	}
	Fallback "Diffuse"
}

 

 

 

 

你可能感兴趣的:(Unity,Shader)