3

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

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

我的问题是,是否可以跳过这个弯路,而是直接在 GLSL 几何着色器中创建视图矩阵?另外,这种可行的性能是否明智?

4

3 回答 3

2

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

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

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

于 2011-10-18T15:59:28.283 回答
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);

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

于 2011-10-18T17:48:59.757 回答
-2

视图矩阵是统一的,统一在渲染批次的中间不会改变,也不能从着色器(直接)写入。就目前而言,我看不出它是如何产生的,至少不是直接的。

另请注意,几何着色器在顶点已使用模型视图矩阵转换后运行,因此重新生成该矩阵或其一部分并没有太大意义(至少在同一通道期间)。

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

于 2011-10-18T11:08:14.637 回答