Math 为什么我的GLSL明暗器照明会在场景中移动,其中的对象是它';什么在发光?

Math 为什么我的GLSL明暗器照明会在场景中移动,其中的对象是它';什么在发光?,math,ios4,glsl,opengl-es-2.0,opengl-es-lighting,Math,Ios4,Glsl,Opengl Es 2.0,Opengl Es Lighting,我正在使用developer.apple.com上的一个教程,将它与我找到的教程结合起来 经过大量的摆弄和实验后,我在屏幕上正确地画出了茶壶,用灯光教程中的“卡通阴影”围绕所有三个轴旋转。由于我只是简单地将整个顶点列表绘制为三角形条带,几何图形中出现了一些小问题(如果您查看teapot.h文件,我应该在其中嵌入“-1”以开始新的三角形条带,但这只是测试数据,与我的问题无关) 我真正困惑的是如何在场景中定位灯光。在我的Objective-C代码中,我有一个包含{0,1,0}的浮点向量,并将其传递到

我正在使用developer.apple.com上的一个教程,将它与我找到的教程结合起来

经过大量的摆弄和实验后,我在屏幕上正确地画出了茶壶,用灯光教程中的“卡通阴影”围绕所有三个轴旋转。由于我只是简单地将整个顶点列表绘制为三角形条带,几何图形中出现了一些小问题(如果您查看teapot.h文件,我应该在其中嵌入“-1”以开始新的三角形条带,但这只是测试数据,与我的问题无关)

我真正困惑的是如何在场景中定位灯光。在我的Objective-C代码中,我有一个包含{0,1,0}的浮点向量,并将其传递到着色器中,然后计算光的强度

为什么灯光在场景中也会移动?我的意思是,光线的作用就像它被一根看不见的棍子固定在茶壶上,无论茶壶朝哪个方向,光线总是指向它的同一侧

这是顶点着色器

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;
}
“位置”由Obj-C代码设置,是对象的顶点,“法线”是顶点数组(VBO)中的法线列表,“投影”和“模型视图”的计算如下:

(CC3GLMatrix来自Cocos3D库,如上面链接的GLES教程所述)

然后我在场景中设置灯光

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”的代码,但不知道要将什么放入等效项中,我必须从代码传递到着色器中。对“眼睛空间”、“相机空间”、“世界空间”等的引用令人困惑,我知道我可能应该在它们之间转换东西,但不理解为什么或如何转换(以及在代码中或着色器中的位置?)


我需要修改光源的每一帧吗?我设置它的代码看起来太简单了。我不是真的移动茶壶,是吗,而是移动整个场景-灯光和周围?

首先是一些定义:

  • 世界空间:定义整个世界的空间。按照惯例,这是一个永远不会移动的静态空间

  • 视图空间/摄影机空间/眼睛空间:在其中定义摄影机的空间。它通常是相对于世界空间的位置和旋转

  • 模型空间:在其中定义模型的空间。与摄影机空间一样,它通常是相对于世界空间的位置和旋转

  • 灯光空间:与模型空间相同

在简单的例子中(我猜在你的例子中),模型空间和世界空间是相同的。此外,OpenGL本身没有世界空间的概念,这并不意味着你不能使用世界空间。当您想让多个对象在场景中独立移动时,它非常方便

现在,在渲染之前对对象执行的操作是创建一个矩阵,该矩阵将模型的顶点转换为视图空间,因此称为“modelViewMatrix”

在这种情况下,光线有点不同。着色器中的灯光计算是在模型空间中完成的,因此必须将每个帧的灯光位置转换为模型空间

这是通过计算以下内容来实现的:

_lightDirUniform = inverseMatrix(model) * inverseMatrix(light) * lightPosition;
光照位置从灯光转换到世界,然后转换到模型空间。如果没有世界空间,只需忽略模型空间变换,就可以了

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