本教程基於教程4-法線對映。在實現乙個點光源前你無需知道法線對映,所以如果你只想知道如何實現乙個點光源,可以暫時無需理解教程4的知識。
這個教程只解釋什麼是點光源以及如何實現它,你可以在本教程使用的演算法之後新增法線對映或其他你需要的shader。
只要你理解了教程1,2,3,這個教程不是很難。
點光源(point lights,在某些渲染工具中也叫做omni light)的光線是從3d空間中的乙個點向四周發出的。
不像前面教程中的單向光,點光源有乙個作用範圍,光線傳播一段距離後會衰減為零,這叫做衰減因子(attenuation factor):
attenuation=1-((x/r )2+(y/r )2+(z/r )2)
公式中的r為衰減距離,公式也可表達為:
attenuation=1-(l/r )•(l/r )
如果用1減去v1=l/r和v2=l/r的點乘,就能獲得衰減因子。
在點光源光照範圍之外的物體只有環境光顏色,所以最後的光照方程如下:
i = a + diffuse*specular*attenuation
自陰影使用上述光照方程會遇到的乙個問題是:在漫反射和鏡面高光計算時會有一些顯示錯誤,當光線向量和視線向量方向相反時畫素也會被照亮,而且,如果光源距物體表面過近,也會有顯示錯誤。
解決上述問題的乙個方法是使用自陰影(self-shadowing),它可以避免不應該被照亮的畫素獲得光照。
當物體被遮擋或不應該獲得光照時,自陰影因子為零或接近於零,如果畫素被照亮,則這個因子大於零。
那麼如何實現呢?只需計算表面法線和光照方向的點乘即可:
s = saturate( n.l );
但是這裡的臨界值過低,所以將它乘以4才可以獲得正確的臨界值。
現在我們可以用s乘以漫反射和鏡面高光反射的顏色,這樣當s為零時顏色也為零!我們的新光照方程如下:
i = a + s*(diffuse*specular*attenuation)
這個方程可以進行優化,方法是只有當s大於零時才計算漫反射和鏡面高光反射,否則顏色就為零:if( s > 0) .
當使用法線對映時,我們是在切線空間中進行計算的。這個演算法讓我們可以使用光線向量的z分量,因為切線空間中的這個z分量就等於n•l. 所以有以下方程:
s = 4 * lightdirection.z;
首先我們需要宣告光照範圍:
view source
print?
1
float
lightrange;
然後在頂點著色器中計算光照,將衰減值放在光源w分量,光線方向放在l向量中:
view source
print?
1
// calculate distance to light in world space
2
float3 l = veclightpos - posworld;
3
4
// transform light to tangent space
5
out.light.xyz = normalize(mul(worldtotangentspace, l));
// l, light
6
7
// add range to the light, attenuation
8
out.light.w = saturate( 1 - dot(l / lightrange, l / lightrange));
剩下的事情就是在光照方程中使用衰減值和施加自陰影,這是在畫素著色器中進行處理的:
view source
print?
1
float
shadow = saturate(4.0 * lightdir.z);
2
....
3
....
4
return
0.2 * color + shadow*((color * d * lightcolor + s*lightcolor) * (l.w));
如你所見,點光源與前面我們使用的單向光源區別不大,當使用光照時,自陰影值也可以用於前面的示例。
除了需要設定光照範圍和光源位置代替前面教程中的光線方向,xna**沒有其他變化:
view source
print?
1
effect.parameters[
"veclightpos"
].setvalue(vlightposition);
2
effect.parameters[
"lightrange"
].setvalue(100.0f);
3
effect.parameters[
"lightcolor"
].setvalue(vlightcolor);
shader之 多光源漫反射以及陰影
shader unlit mullight subshader cgprogram pragma vertex vert pragma fragment frag include unitycg.cginc pragma target 3.0 衰減與陰影的實現 include autolight.c...
點光源小孔成像matlab
模擬的r射線,不用考慮散 function spheresource h input source to collimator h input source to detector r input hole diameter d1 input pinhole1 parameter x y axis ...
opengl 教程 20 點光源
前面的教程中,我們在方向光的前提下,研究了基本的光照模型 環境光,漫反射光,高光 方向光沒有起點,所有光線都是沿著乙個方向,它的強度不會隨著距離的增加有任何變化。本篇教程中,我們開始研究點光源,點光源是起始於乙個點,向四面照射,會隨著傳輸距離增加而衰減,所以在點光源屬性中,我們會增加乙個光源位置。通...