2011-08-25 33 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转换从光到世界,然后到模型空间:

这是通过计算像做。如果你没有世界空间,那么就省去模型空间转换,你应该没问题。