2012-02-28 57 views
2

我正在編寫一個引擎,並使用Light 0作爲場景的「太陽」。太陽是定向光。OpenGL定向照明+定位

我設置了場景的正交視點,然後將光線設置在屏幕的「東側」(和字符)(x/y是平面地形的座標,正z朝向相機並在地形上指示「高度」 - 場景也在x軸上的等軸視圖上旋轉)。

光線似乎正在照亮0,0,0的「東」,但隨着角色的移動,它不會移位(CenterCamera對提供的值的負值做一個glTranslate3f,以便它們可以映射指定世界座標)。意思是,我進一步向西移動,它總是黑暗,沒有光。

Graphics.BeginRenderingLayer(); 
    { 
     Video.MapRenderingMode(); 

     Graphics.BeginLightingLayer(Graphics.AmbientR, Graphics.AmbientG, Graphics.AmbientB, Graphics.DiffuseR, Graphics.DiffuseG, Graphics.DiffuseB, pCenter.X, pCenter.Y, pCenter.Z); 
     { 
      Graphics.BeginRenderingLayer(); 
      { 
       Graphics.CenterCamera(pCenter.X, pCenter.Y, pCenter.Z); 
       RenderMap(pWorld, pCenter, pCoordinate); 
      } 
      Graphics.EndRenderingLayer(); 

      Graphics.BeginRenderingLayer(); 
      { 
       Graphics.DrawMan(pCenter); 
      } 
      Graphics.EndRenderingLayer(); 
     } 
     Graphics.EndLightingLayer(); 
    } 
    Graphics.EndRenderingLayer(); 

Graphics.BeginRenderingLayer = PushMatrix,EndRenderingLayer = PopMatrix Video.MapRenderingMode =正交投影與場景旋轉/放大CenterCamera確實一個轉換爲X/Y/Z,使得該字符被現在在中心的相反X/Y/Z在屏幕中間。

有什麼想法?也許我已經在這裏混淆了一些我的代碼?

的照明代碼如下:

public static void BeginLightingLayer(float pAmbientRed, float pAmbientGreen, float pAmbientBlue, float pDiffuseRed, float pDiffuseGreen, float pDiffuseBlue, float pX, float pY, float pZ) 
    { 
     Gl.glEnable(Gl.GL_LIGHTING); 
     Gl.glEnable(Gl.GL_NORMALIZE); 
     Gl.glEnable(Gl.GL_RESCALE_NORMAL); 
     Gl.glEnable(Gl.GL_LIGHT0); 

     Gl.glShadeModel(Gl.GL_SMOOTH); 

     float[] AmbientLight = new float[4] { pAmbientRed, pAmbientGreen, pAmbientBlue, 1.0f }; 
     float[] DiffuseLight = new float[4] { pDiffuseRed, pDiffuseGreen, pDiffuseBlue, 1.0f }; 
     float[] PositionLight = new float[4] { pX + 10.0f, pY, 0, 0.0f }; 
     //Light position of Direction is 5 to the east of the player. 

     Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, AmbientLight); 
     Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, DiffuseLight); 
     Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, PositionLight); 

     Gl.glEnable(Gl.GL_COLOR_MATERIAL); 
     Gl.glColorMaterial(Gl.GL_FRONT_AND_BACK, Gl.GL_AMBIENT_AND_DIFFUSE); 
    } 
+1

它可能有助於發佈您的代碼,顯示您設置燈光的位置。 – kappamaki 2012-02-29 00:17:37

+0

編輯原件以包含照明代碼。 – Locke 2012-03-01 00:21:00

+0

您是否計算併發送每個頂點的法線? – 2012-03-27 20:45:19

回答

3

你將需要爲每個表面提供法線。發生了什麼(沒有法線)是指向的光基本上在零以東的所有東西上都有所發光,而所有東西都有0,0,1的法線(它面向西)。

您不需要發送就我所知,每個頂點都有一個法線,但是因爲GL是一個狀態機,所以每當正常的變化改變它時,你都需要確保每個頂點都有一個法線。所以,如果你在一個立方體渲染一張臉,「西方」的臉應該有一個單一的通話

glNormal3i(0,0,1); 
glTexCoord.. 
glVertex3f... 
glTexCoord.. 
etc. 

在X-Y-Z排列的直角棱鏡的情況下,「」的整數就足夠。對於不面臨六個主要方向之一的面孔,您需要對它們進行歸一化。根據我的經驗,您只需要將前三個點歸一化,除非四邊形不平整。這是通過找到四邊形中前三個邊形成的三角形的法線來完成的。

'計算法線'有一些簡單的內容我覺得很有啓發性。

第二部分是因爲它是一個定向燈,(W = 0)重新定位它與玩家的位置沒有任何意義。除非光本身正在從背後的攝像頭髮射的,你是旋轉在你面前的物體(如模型),你希望永遠是正面照明,它的位置或許應該是這樣的

float[] PositionLight = new float[4] { 0.0f, 0.0f, 1.0f, 0.0f }; 

或者,如果在GLx方向被解釋爲東西方向(即您最初朝北/南)

float[] PositionLight = new float[4] { 1.0f, 0.0f, 0.0f, 0.0f }; 

的概念是,你計算每面的光,如果光沒有按不動並且場景本身不移動(只是相機在場景中移動)方向計算將始終保持正確。如果法線準確,GL可以計算出特定臉部的光線強度。

這裏最後的一點是GL不會自動爲你處理陰影。基本的GL_Light對於一系列凸起形狀的受控照明是足夠的,因此您必須弄清楚是否應該將光(例如太陽)應用於臉部。在某些情況下,這只是將臉部所屬的實體取出來,看看太陽光線的矢量在到達「天空」之前是否與另一個固體相交。

尋找lightmaps上的東西以及shadowmapping。

2

有一件事可以讓很多人發現,發送到glLightFv的位置由當前的矩陣堆棧翻譯。因此,如果要將燈光設置爲世界座標中的特定位置,則必須在調用glLightFv時在矩陣堆疊上設置和激活相機和投影矩陣。