2011-08-25 31 views
4

我正在關注a tutorial on OpenGL ES 2.0,並將它與我在GLSL lighting上找到的教程相結合,使用developer.apple.com的a handy Utah teapot爲什麼我的GLSL着色器照明在它照射的對象周圍移動?

經過大量的小提琴和實驗後,我在屏幕上適度地繪製了茶壺,並在燈光教程中使用了「香椿底紋」旋轉了所有三個軸。由於我簡單地將整個頂點列表繪製爲三角形條帶,因此在幾何體中會出現一些故障(如果您在teapot.h文件中查看嵌入了'-1'的位置,我應該開始新的三角形條帶,但這是隻測試數據並與我的問題無關)。

我真的很困惑的一點是如何在場景中定位燈光。在我的Objective-C代碼中,我有一個包含{0,1,0}的float 3向量,並將其傳遞給着色器,然後計算出光的強度。

爲什麼光線也出現在場景中?我的意思是,光看起來好像是用一根看不見的棒子粘在茶壺上,無論茶壺面朝什麼方向,都指向它的同一側。

這是頂點着色器

attribute vec4 Position; 
attribute vec4 SourceColor; 
attribute vec3 Normal; 

uniform mat4 Projection; 
uniform mat4 Modelview; 

varying vec3 normal; 

void main(void) { 
    normal = Normal; 
    gl_Position = Projection * Modelview * Position; 
} 

「位置」由對象 - C代碼設置的,用於該對象的頂點,「正常」是既從頂點數組法線的列表(VBO ),「投影」和「模型變換」被計算如下:

(A CC3GLMatrix距離Cocos3D庫,在上述鏈接的GLES教程)

CC3GLMatrix *projection = [CC3GLMatrix matrix]; 
float h = 4.0f * self.frame.size.height/self.frame.size.width; 
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:1 andFar:100]; 
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix); 

CC3GLMatrix *modelView = [CC3GLMatrix matrix]; 
[modelView populateFromTranslation:CC3VectorMake(0, 0, -7)]; 
[modelView scaleBy:CC3VectorMake(30, 30, 30)]; 

_currentRotation += displayLink.duration * 90; 
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, _currentRotation)]; 

glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix); 

提到我設置的光在做現場

float lightDir[] = {1,0,1}; 
glUniform3fv(_lightDirUniform, 1, lightDir); 

片段着色器看起來是這樣的

varying lowp vec4 DestinationColor; // 1 
varying highp vec3 normal; 
uniform highp vec3 LightDir; 


void main(void) { 
    highp float intensity; 
    highp vec4 color; 
    intensity = dot(LightDir,normal); 
    if (intensity > 0.95) 
     color = vec4(1.0,0.5,0.5,1.0); 
    else if (intensity > 0.5) 
     color = vec4(0.6,0.3,0.3,1.0); 
    else if (intensity > 0.25) 
     color = vec4(0.4,0.2,0.2,1.0); 
    else 
     color = vec4(0.2,0.1,0.1,1.0); 

    gl_FragColor = color; 
} 

而努力工作,這一點我遇到一個引用(不存在的在GLES)代碼「gl_LightSource」和' gl_NormalMatrix',但不知道要把什麼放入等價物,我必須從我的代碼傳入着色器。對「眼睛空間」,「相機空間」,「世界空間」等的引用是令人困惑的,我知道我應該轉換它們之間的東西,但不明白爲什麼或如何(以及在​​何處 - 在代碼中,或在着色器?)

每幀需要修改光源嗎?我設置它的代碼看起來過於簡單。我並不是真的在移動茶壺,而是我正在移動整個場景 - 光線和周圍?

回答

5

首先一些定義的:

  • 世界空間:你的整個世界在限定的空間內按照慣例是,從來沒有移動的靜態空間。

  • 視圖空間/相機空間/眼空間:相機在限定的空間中,通常是相對於世界空間中的位置和旋轉

  • 模型空間:您的模型中所限定的空間中。像相機的空間,它通常是相對於世界空間的位置和旋轉

  • 光空間:同型號的空間

在簡單的例子(我猜你的)模型空間和世界空間是一樣。另外OpenGL本身並沒有世界空間的概念,這並不意味着你不能使用它。當你想在場景中獨立移動多個物體時,它非常方便。

現在,您在渲染之前正在處理的對象正在創建一個矩陣,該矩陣將模型的頂點轉換爲視圖空間,因此爲'modelViewMatrix'。

在這種情況下,光有點不同。着色器中的光照計算是在模型空間中完成的,因此您必須將每個幀的亮點轉換爲模型空間。

_lightDirUniform = inverseMatrix(model) * inverseMatrix(light) * lightPosition; 

的lightposition轉換從光到世界,然後到模型空間:

這是通過計算像做。如果你沒有世界空間,那麼就省去模型空間轉換,你應該沒問題。