shader入门精要读书笔记20 Unity中的光源类型与衰减计算

一、光源类型

Unity中4中光源:平行光、点光源、聚光灯、面光源(只在烘焙时发生作用)。

光源位置、方向、颜色、强度、衰减等等都与他们的属性息息相关,会影响到Shader。

1.平行光
他没有唯一的位置,它的几何属性只有方向。

2.点光源
表示由一个点发出的向所有方向延伸的光。
照亮空间有限,存在位置等属性,存在衰减等等。

3.聚光灯
是由一块锥形区域定义的,从一个特定位置出发,向特定方向延伸的光。
最复杂的一种光源,照亮空间有限,存在位置、方向、衰减等等。

二、在前向渲染中处理不同的光源类型

前向渲染路径时,Unity Shader会访问5个光源属性:
位置、方向、颜色、强度、衰减,

实践:默认平行光和绿色点光源


Pass 
{
	Tags{"LightMode"="ForwardBase"}//设置Base Pass
	CGPROGRAM
	#pragma multi_compile_fwdbase  //编译指令确保Shader中光照衰减等光照变量被正确赋值。
	...
	...//片元着色器中
	fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //在片元着色器中计算环境光
	fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*max(0,dot(worldNormal,worldLightDir));
	fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0,dot(worldNormal,halfDir)),_Gloss);
	fixed atten = 1.0;
	return fixed4(ambient+(diffuse+specular)*atten,1.0);
}
------------------------------------------------------
//此时Unity中只有一个平行光,就在Base Pass处理。Base Pass处理的一定是平行光。
//如果没有平行光时,Base Pass会当作全黑的光源处理。
//但当着色器中有多个平行光时,Base Pass会处理最亮的平行光,其他平行光会传递给Addition Pass中处理。
------------------------------------------------------
Pass
{
	Tags{"LightMode"="ForwardAdd"} //设置Addition Pass
	Blend One One   //开启混合模式将此光照结果和之前帧缓存中的光照进行叠加
	CGPROGRAM
	#pragma multu_compile_fwdadd //保证我们在Pass中得到正确的光照变量
	...
	...//片元着色器中首先需要判断光源类型,计算不同光源的方向
	#ifdef USING_DIRECTIONAL_LIGHT
		fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
	#else
		fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz-i.worldPosition.xyz);
	#endif	
	//以上为了计算不同光源类型时,光源方向
	
	fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*max(0,dot(worldNormal,worldLightDir));
	fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(0,dot(worldNormal,halfDir)),_Gloss);
	
	#ifdef USING_DIRECTIONAL_lIGHT
		fixed atten = 1.0;
	#else
		float lightCoord = mul(_LightMatrix0,float4(i.worldPosition,1)).xyz;
		fixed atten = tex2D(_LightTexture0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;
		//宏UNITY_ATTEN_CHANNEL是为了得到衰减纹理中衰减值所在的分量。
	#endlf
	//计算不同光源类型的衰减效果,lightCoord是将顶点位置转换到光源空间
	//衰减效果使用一张纹理作为查找表,计算衰减。
	//我们通常关心的是纹理对角线上的纹理颜色值,其表示了光源空间中不同距离的衰减值。
	
	return fixed4(ambient+(diffuse+specular)*atten,1.0);
}

也可以使用线性数学方法计算衰减:

float distance = length(_WorldSpaceLightPos0.xyz-i.worldPosition.xyz);
atten = 1.0/distance;

一些补充:

Unity绘制光源的顺序是按照重要程度排序的,与颜色、强度、距离有关。
Untiy不会渲染不在聚光灯内的光源。
在前向渲染路径中,可以使用前向渲染路径中的内置函数和内置变量计算逐顶点与SH光源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值