gpt4 book ai didi

math - 为什么我的 GLSL 着色器灯光会随着它所照射的对象在场景中移动?

转载 作者:行者123 更新时间:2023-11-30 23:45:32 26 4
gpt4 key购买 nike

我正在关注 a tutorial on OpenGL ES 2.0并将其与 GLSL lighting 上的教程相结合我发现,使用 a handy Utah teapot来自 developer.apple.com。

经过大量的摆弄和实验后,我在屏幕上适度正确地绘制了茶壶,使用照明教程中的“卡通阴影”围绕所有三个轴旋转。由于我只是将整个顶点列表绘制为三角形 strip (如果您查看 teapot.h 文件,在我应该开始新的三角形 strip 的位置嵌入了“-1”,但这是仅测试数据,与我的问题无关)。

我真正感到困惑的是如何在场景中定位灯光。在我的 Objective-C 代码中,我有一个浮点数 3包含 {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;
}

'Position' 由 Obj-C 代码设置,是对象的顶点,'Normal' 是来自顶点数组 (VBO) 的法线列表,'Projection' 和 'Modelview' 计算如下:

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

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

最佳答案

首先是一些定义:

  • 世界空间:定义你的整个世界的空间。按照惯例,它是一个永远不会移动的静态空间。
  • View 空间/相机空间/眼睛空间:定义相机的空间。它通常是相对于世界空间的位置和旋转
  • 模型空间:定义模型的空间。与相机空间一样,它通常是相对于世界空间的位置和旋转
  • 光空间:同模型空间

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

    现在,您在渲染之前对您的对象所做的是创建一个矩阵,将模型的顶点转换为 View 空间,因此是“modelViewMatrix”。

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

    这是通过计算以下内容来完成的:
    _lightDirUniform = inverseMatrix(model) * inverseMatrix(light) * lightPosition;

    光照位置从光照到世界,再到模型空间。如果您没有世界空间,只需省略模型空间转换,您应该没问题。

    关于math - 为什么我的 GLSL 着色器灯光会随着它所照射的对象在场景中移动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7193139/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com