OpenGL光照陰影演算法的實現

2021-07-05 22:21:04 字數 1930 閱讀 9085

陰影

(又稱影子背影),光線被不透明物體阻檔而產生的黑暗範圍,與光源的方向相反。影的橫切面是二維

輪廓、阻檔光線物體的倒轉投影。影的大小、形狀隨光線的入射角而改變。(維基百科)在場景中新增陰影可以使得場景更加逼真。下面兩幅圖是有無陰影效果的對比:

如何製造陰影?

簡單地做法,我們可以通過把源物體壓平在物體表面所處的平面上,來製造陰影效果。然後被壓平的物體用黑色或深色進行繪製。通過操作高階矩陣的方式,來把物體壓平到其他表面上。

被壓平的效果

我們需要壓平的模型檢視投影矩陣,以使得所有被繪製的物體都會被壓平到陰影所處的二維平面上。無論物體朝哪個方向,都會被投影到陰影所在的平面上。在此需要考慮兩種情況,光源離物體的距離以及光源的照射方向。光源的方向決定了陰影的形狀和大小。就像在一天中的不同時段,人站在太陽底下,影子會隨著太陽的位置而變化。

在math3d庫中,有乙個函式m3dmakeplanarshadowmatrix,它接受的引數包括乙個陰影所處平面的平面方程(3個點不能位於一條直線上),光源的位置,返回的是乙個變換矩陣。用當前的模型檢視矩陣乘以這個矩陣,隨後的所有被繪製的物體都會被壓平到這個投影平面上。

void m3dmakeplanarshadowmatrix(m3dmatrix44f proj, const m3dvector4f planeeq, const m3dvector3f vlightpos)

陰影例子

為了演示陰影的效果,我們把噴氣式飛機懸空,然後在其上面放置乙個光源,製造乙個飛機投影到地面的陰影效果。

下面的例子,我們在setuprc中建立乙個陰影矩陣,並用全域性變數儲存它。在renderscene中使用。

glfloat lightpos = ;

...

//陰影矩陣

m3dmatrix44f shadowmat;

...

void setuprc()

,

,

};

glenable(gl_depth_test);

glfrontface(gl_ccw);

glenable(gl_cull_face);

//enable lighting

glenable(gl_lighting);

....

//構造投影平面

m3dvector4f vplaneequation;

m3dgetplaneequation(vplaneequation, points[0], points[1], points[2]);

//計算投影矩陣

m3dmakeplanarshadowmatrix(shadowmat, vplaneequation, lightpos);

...

}

在renderscene中,我們先繪製地面,然後畫噴氣式飛機。然後恢復模型檢視矩陣乘以陰影矩陣,然後我們再次繪製噴氣式飛機(此過程要關掉深度測試)。飛機的投影和地面處於同乙個位置,在一般情況下後面畫的那個物體會疊在之前的物體上面被顯示。但有的時候,會導致z-figinting,從而產生混亂。

**如下:

void renderscene(void)

執行的效果

OpenGL光照設定,實現渲染效果

opengl實現具有凹凸感的渲染效果圖 一 設定光照 1 設定光照成分 環境光 環境光來自於四面八方。所有場景中的物件都處於環境光的照射中。漫射光 由特定的光源產生,並在您的場景中的物件表面上產生反射。處於漫射光直接照射下的任何物件表面都變得很亮,而幾乎未被照射到的區域就顯得要暗一些。這樣在我們所建...

OpenGL 光照方程的計算

分析程式並計算,請看下面的一段程式,並計算三個頂點1 2和3處的光照的顏色值。必須寫出過程,只有結果不得分。include void init void glfloat mat diffuse glfloat mat emission glfloat mat specular glfloat mat...

opengl光照方程的計算驗證

include stdafx.h include include using namespace std void init void 光源環境光 glfloat mat diffuse 散射光glfloat mat emission 鏡面光glfloat mat specular 物體自發光 gl...