在GLSL着色器中创建视图矩阵

时间:2011-10-18 09:13:31

标签: opengl glsl glm-math

我在GPU上的1D纹理中存储了许多位置和方向。我想在GLSL几何着色器中将它们用作渲染源。为此,我需要从这些纹理创建相应的视图矩阵。

我的第一个想法是绕道CPU,将纹理读取到内存并从那里创建一堆视图矩阵,类似glm::lookat()。然后将矩阵作为统一变量发送到着色器。

我的问题是,是否可以跳过此绕行而是直接在GLSL几何着色器中创建视图矩阵?此外,这是否可行?

3 个答案:

答案 0 :(得分:1)

没有人说(或者没有人应该说)你的视图矩阵必须通过制服来自CPU。您可以直接从着色器内的纹理中的矢量生成视图矩阵。也许好的旧gluLookAt的实施对你有帮助。

如果这种方法在性能方面是一个好主意,那么另一个问题是,但如果这种纹理非常大或经常变化,那么这种方法可能比将其读回CPU更好。

但是也许您可以使用简单的类似GPGPU的着色器将矩阵预生成到另一个纹理/缓冲区中,除了为纹理中的每个位置/向量生成矩阵并将其存储在另一个纹理中(使用FBO)或缓冲区(使用变换反馈)。这样您就不需要对CPU进行往返,也不需要为每个顶点/基元/任何内容重新生成矩阵。另一方面,这将增加所需的内存,因为4x4矩阵比位置和方向更重。

答案 1 :(得分:1)

不确定。读取纹理,并从值...

构建矩阵
vec4 x = texture(YourSampler, WhateverCoords1);
vec4 y = texture(YourSampler, WhateverCoords2);
vec4 z = texture(YourSampler, WhateverCoords3);
vec4 w = texture(YourSampler, WhateverCoords4);
mat4 matrix = mat4(x,y,z,w);

这有什么问题吗?还是我错过了什么?

答案 2 :(得分:-1)

视图矩阵是统一的,制服在渲染批处理中间不会改变,也不能从着色器(直接)写入。在我看来,如何生成它是不可能的,至少不是直接的。

另请注意,几何着色器在使用模型视图矩阵转换顶点之后运行,因此它不会太多意义(至少在同一遍期间)重新生成该矩阵或其中的一部分。

你当然可能仍然会对变换反馈进行一些破解,将一些值写入缓冲区,然后将其作为统一缓冲区复制/绑定,或者只是从着色器中读取值并乘以矩阵。这至少可以避免到CPU的往返 - 问题是这种方法是否有意义,以及你是否真的想做这样一个不起眼的事情。如果不确切地知道你想要实现什么,很难说出什么是最好的,但很可能只是在顶点着色器中转换(读取那些纹理,构建矩阵,相乘)将更好更容易地工作。