unity的光源类型和光照衰减

一、Unity的光源类型

Unity一共支持4种光源类型:平行光、点光源、聚光灯和面光源(area Light)。面光源仅在烘焙时才可发挥作用。

Shader中最常使用的光源属性有光源的位置、方向(准确的说是到达某点的方向)、颜色、强度以及衰减(具体的说就是,到某点的衰减与该点到光源的距离有关)这5个属性。这些属性和它们的几何定义息息相关。

1. 平行光

照亮范围没有限制的,通常作为太阳这样的角色在场景中出现的。
没有唯一的位置。
它的几何属性只有方向,并且到所有点的方向都是一样的。
没有衰减,光到任何一点的强度都是一样的。

2. 点光源

点光源的照亮空间有限,它是由空间中的一个球体定义的。
可以表示从一个点发出的、向所有方向延伸的光。

注意:需要在Scene视图中(有个光照按钮)开启光照才能看到预览光源是如何影响场景中的物体的。
球体半径可以修改Range属性来调整。
点光源有位置属性
方向属性需要用光源位置减去某点的位置来得到它到该点的方向
点光源的颜色和强度可以再Light组件面板中调整。
点光源是会衰减的。

3. 聚光灯

照亮空间由一块锥形区域定义。
锥形区域的半径由面板中的Range属性决定,锥形的张开角度由Spot Angle属性决定
有位置属性
方向属性需要用光源位置减去某点的位置来得到它到该点的方向
聚光灯也会衰减
 
二、unity的光照衰减

前面提过unity使用一张纹理作为查找表来在片元着色器中计算逐像素光照的衰减,这样的好处在于,计算衰减不依赖于数学公式的复杂性,我们只需要使用一个参数值去纹理中采样即可。

但使用纹理查找来计算衰减也有一些弊端:

需要预处理得到采样纹理,而且纹理的大小也会影响衰减的精度。

不直观,同时也不方便,因此一旦把数据存储到查找表中,我们就无法使用其他数学公式来计算衰减。

但由于这种方法在一定程度上提升性能,而且得到的效果在大部分情况下都是良好的,因此unity默认就是使用这种纹理查找的方式来计算逐像素的点光源和聚光灯的衰减的。

1. 用于光照衰减的纹理

unity在内部使用一张名为_LightTexture0的纹理来计算光照衰减。如果我们对该光源使用了cookie,那么衰减查找纹理是_LightTexureB0。我们通常关系_LightTexture0对角线上的纹理颜色值,这些值表明了在光源空间中不同位置的点的衰减值,例如(0,0)点表明了与光源位置重合的点的衰减值,而(1,1)点表明了在光源空间中所关心的距离最远的点的衰减。

为了对_LightTexture0纹理采样得到给定点到该光源的衰减值,我们首先需要得到该点在光源空间中的位置,通过_LightMatrix0变换矩阵得到的(把顶点从世界空间变换到光源空间),因此我们只需要把_LightMatrix0和世界空间中的顶点坐标相乘即可得到光源空间中的相应位置:

float3 lightCoord=mul(_LightMatrix0,float4(i.worldPosition,1)).xyz;

然后我们可以使用这个坐标的模的平方对衰减纹理进行采样,得到衰减值:

fixed atten=tex2D(_LightTexture0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;

在上面代码中,我们使用了光源空间中顶点距离的平方,来对纹理进行采样,之所以没有使用距离值采样是因为这种方法避免了开方操作,然后我们使用宏UNITY_ATTEN_CHANNEL来得到衰减纹理中衰减值所在的分量,以得到最终的衰减值。

2. 使用数学公式计算衰减

尽管纹理采样的方法介意减少计算衰减时的复杂度,但有时我们希望可以在代码中利用公式来计算光源的衰减,下面的代码可以计算光源的线性衰减:

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

atten=1.0/distance;

unity并没有在文档中给出内置衰减计算的相关说明,尽管我们仍然可以在片元着色器中利用一些数学公式来计算衰减。

版权声明:本文为CSDN博主「小橙子0」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cgy56191948/article/details/100174022

最新文章