Unity Shader着色器学习(二)

半兰伯特光照模型

半兰伯特光照模型

为什么需要半兰伯特光照模型
在这里插入图片描述
在前面我们使用的是兰伯特光照模型,它有一个问题,在光照无法到达的区域,模型的外观通常是全黑的,没有任何明暗变化,这会使模型的背光区域看起来就像一个平面一样,失去了模型细节表现。实际上我们可以通过添加环境光来得到非全黑的效果,但即便这样仍然无法解决背光面明暗一样的缺点。为此,有一种改善技术被提出来,这就是半兰伯特(Half Lambert)光照模型。

半兰伯特光照模型公式

广义的半兰伯特光照模型的公式如下:
在这里插入图片描述

c_diffuse=(c_light∙m_diffuse)(α(n ̂⋅l ̂ )+β)
可以看出,与原兰伯特模型相比,半兰伯特光照模型没有使用max操作来防止n ̂和l ̂的点积为负值,而是对其结果进行了一个α倍的缩放再加上一个β大小的偏移。绝大多数情况下,α和β的值均为0.5,即公式为:
c_diffuse=(c_light∙m_diffuse )(“0.5” (n ̂⋅l ̂ )+“0.5” )
在这里插入图片描述

通过这样的方式,我们可以把n ̂⋅l ̂的结果范围从[-1, 1]映射到[0, 1]范围内。也就是说,对于模型的背光面,在原兰伯特光照模型中点积结果将映射到同一个值,即0值处;而在半兰伯特模型中,背光面也可以有明暗变化,不同的点积结果会映射到不同的值上。
需要注意的是,半兰伯特是没有任何物理依据的,它仅仅是一个视觉加强效果。

由于n ̂⋅l ̂的值等于cos⁡θ,因此我们可以查看(“0.5” (n ̂⋅l ̂ )+“0.5” )的函数图像,这样比较清晰明了。
在这里插入图片描述

Shader编写

DiffuseFragment_HalfLambert.shader

Shader "Shader Learning Siki/Lighting/Diffuse PerFragment Half Lambert"
{
   
	Properties
	{
   
		_Diffuse("Diffuse Color", Color) =(1.0, 1.0, 1.0, 1.0)
	}

	SubShader
	{
   
		Pass
		{
   
			Tags{
    "LightMode" = "ForwardBase" }  //这里一定不要忘记定义了,要定义合适的LightMode

	CGPROGRAM

	#include "Lighting.cginc"
	#include "UnityCG.cginc"

	#pragma vertex vert
	#pragma fragment frag

	fixed4 _Diffuse;

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

	struct v2f
	{
   
		float4 pos : SV_POSITION;
		fixed3 worldNormal : COLOR;
	};

	v2f vert(a2v v)
	{
   
		v2f o;
		o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
		o.worldNormal = mul(v.normal, (float3x3)_World2Object);

	return o;
	}

	fixed4 frag(v2f i) : SV_Target
	{
   
		fixed3 worldNormalize = normalize(i.worldNormal);
		//fixed3 worldNormal = normalize(mul((float3x3)_Object2World, v.normal));
		fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);   //对于每个顶点来说 光源的位置就是光源的方向,因为光是平行光

	fixed halfLambert = dot(worldNormalize, worldLight) * 0.5 + 0.5;
	fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;

	fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
	fixed3 color = diffuse + ambient;

	return fixed4(color
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值