我在 GPU 上的一维纹理中存储了许多位置和方向。我想将它们用作 GLSL 几何着色器中的渲染源。为此,我需要从这些纹理创建相应的视图矩阵。
我的第一个想法是绕道 CPU,将纹理读取到内存并从那里创建一堆视图矩阵,例如glm::lookat()
. 然后将矩阵作为统一变量发送到着色器。
我的问题是,是否可以跳过这个弯路,而是直接在 GLSL 几何着色器中创建视图矩阵?另外,这种可行的性能是否明智?
没有人说(或不应该说)您的视图矩阵必须通过制服来自 CPU。您可以直接在着色器内从纹理中的向量生成视图矩阵。也许旧的gluLookAt的实现对你有帮助。
如果这种方法在性能方面是一个好主意,那是另一个问题,但如果这个纹理非常大或经常变化,这种方法可能比将它读回 CPU 更好。
但是也许您可以使用简单的类似 GPGPU 的着色器将矩阵预生成到另一个纹理/缓冲区中,该着色器无非为纹理中的每个位置/向量生成一个矩阵并将其存储在另一个纹理中(使用 FBO)或缓冲区(使用变换反馈)。这样您就不需要往返 CPU,也不需要为每个顶点/基元/任何东西重新生成矩阵。另一方面,这将增加所需的内存,因为 4x4 矩阵比位置和方向要重一些。
当然。读取纹理,并根据值构建矩阵......
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);
这有什么问题吗?还是我错过了什么?
视图矩阵是统一的,统一在渲染批次的中间不会改变,也不能从着色器(直接)写入。就目前而言,我看不出它是如何产生的,至少不是直接的。
另请注意,几何着色器在顶点已使用模型视图矩阵转换后运行,因此重新生成该矩阵或其一部分并没有太大意义(至少在同一通道期间)。
当然,您可能仍然可以对变换反馈进行一些修改,将一些值写入缓冲区,然后将其复制/绑定为统一缓冲区,或者只是从着色器中读取值并作为矩阵相乘。这至少可以避免到 CPU 的往返——问题是这种方法是否有意义,以及你是否真的想做这样一件晦涩难懂的事情。如果不确切知道您想要实现什么,很难说出什么是最好的,但很可能只是在顶点着色器中转换事物(读取这些纹理,构建矩阵,相乘)会更好,更容易。