高光反射模型

高光反射部分计算公式为。

             Cspecular=(Clight*Mspecular)*pow(max(0,dot(V,R)),Mgloss)

Clight是入射光的颜色和强度,材质的高光反射系数Mspecular视角方向V和反射方向R点乘的结果再与高光系数pow。

R=2(dot(N,-L))N+L,幸运的是CG提供了计算发射方向的函数reflect。

下面是Shader代码

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

Shader "Custom1/Specular" {
	Properties{
		_Diffuse("Diffuse",Color) = (1,1,1,1)
		_Specular("Specular",Color) = (1,1,1,1)
		_Gloss("Gloss",Range(8.0,256)) = 20
	}
		SubShader{
			Tags { "LightMode" = "ForwardBase" }
			LOD 200
		Pass{
			CGPROGRAM
	#pragma vertex vert
	#pragma fragment frag
	#include "Lighting.cginc"
			fixed4 _Diffuse;
			fixed4 _Specular;
			float _Gloss;
			struct a2v {
				float4 vertex :POSITION;
				float3 normal:NORMAL;
			};
			struct v2f {
				float4 pos:SV_POSITION;
				fixed3 color : COLOR0;
			};
			v2f vert(a2v v) {
				v2f o;
				o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
				fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
				//计算漫反射
				fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*max(0, dot(worldNormal, worldLightDir));
				//计算反射方向
				fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
				//计算视角方向
				fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
				//高光反射计算公式
				fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(dot(reflectDir, viewDir), _Gloss);
				o.color = diffuse + ambient + specular;
				return o;

			}
			fixed4 frag(v2f i) :SV_Target{
				return fixed4(i.color,1.0);
			}
		ENDCG
	 }
	}
	 FallBack "Specular"
	
}

Blinn-Phong光照模型

图形学界大牛Jim Blinn对Phong模型进行了改进,提出了Blinn-Phong模型。Blinn-Phong模型与Phong模型的区别是,把dot(V,R)换成了dot(N,H),其中H为半角向量,位于法线N和光线L的角平分线方向。Blinn-Phong模型可表示为:

          Ispecular = Ks*Is* pow(( dot(N,H), n )

其中H = (L + V) / | L+V |,计算H比计算反射向量R更快速。

代码如下:

Shader "Custom1/Blinn-Phong"
{
	Properties{
		_Diffuse("Diffuse",Color) = (1,1,1,1)
		_Specular("Specular",Color) = (1,1,1,1)
		_Gloss("Gloss",Range(8.0,256)) = 20
	}
		SubShader{
		Tags{ "LightMode" = "ForwardBase" }
		LOD 200
		Pass{
		CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc"
		fixed4 _Diffuse;
	fixed4 _Specular;
	float _Gloss;
	struct a2v {
		float4 vertex :POSITION;
		float3 normal:NORMAL;
	};
	struct v2f {
		float4 pos:SV_POSITION;
		fixed3 color : COLOR0;
	};
	v2f vert(a2v v) {
		v2f o;
		o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
		fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
		fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
		fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
		//计算漫反射
		fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*max(0, dot(worldNormal, worldLightDir));
		//计算反射方向
		//fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
		//计算视角方向
		fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
		//计算半角
		fixed3 halfDir = normalize(worldLightDir + viewDir);
		//高光反射计算公式
		fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(dot(worldNormal,halfDir), _Gloss);
		o.color = diffuse + ambient + specular;
		return o;

	}
	fixed4 frag(v2f i) :SV_Target{
		return fixed4(i.color,1.0);
	}
		ENDCG
	}
	}
		FallBack "Specular"

}



版权声明:本文为qq_34552886原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。