试图让问题和答案更简单,我会将问题从3d减少到2d。
我在2d空间中有一个带有X * Y单元的2d网格。它仅由X,Y,bBoxMin2d和bBoxMax2d定义。
在GPU上(当前在VBO中),我有X * Y(无符号8位)整数,它们定义了单元格的亮度。因此,对于X = Y = 3,如果VBO包含{4,7,3,2,9,4,7,2,1},则应使用以下亮度的补丁渲染网格:
4 7 3
2 9 4
7 2 1
我知道我可以创建另一个VBO,其中包含每个单元格中心的世界位置,并使用几何着色器创建要传递给片段着色器的补丁。
但是,我想要更高效,没有第二个VBO。我的想法是,如果几何着色器的每个实例都有自己的线程索引(类似于CUDA),它可以仅使用该索引创建单元格的补丁,并且例如使用bBoxMin2d和bBoxMax2d。一个UBO。片段着色器然后将从VBO读取颜色,我很高兴。
但似乎没有几何着色器线程索引。那么,我该如何解决我的问题?
请不要告诉我使用其他位置的VBO - 这将增加sizeof(uint8_t)=每个单元1个字节到至少sizeof(float3)+ sizeof(uint8_t)= 13个字节的内存要求。我有很多细胞:|
答案 0 :(得分:2)
好的,让我们来处理房间里的大象。您有一个正在渲染的大型3D单元网格。你正在制作一个Minecraft克隆;最好是对此事先做好准备。
您尝试做的事情绝不会高效。使用几何着色器从单个数字和gl_PrimitiveIDIn
生成正方形/立方体不是渲染一堆立方体的有效方法。有效的方法是执行Minecraft的工作:创建包含可见地形的缓冲区对象并渲染 。这将占用更多的内存,但是你将更有可能在渲染“大量单元格”时获得合理的性能。
如果你想知道如何使你当前的方法工作,大概(我必须推测,因为你没有说),你的GS作为其input points
and converts this into several triangle_strip
outputs。因此每个顶点输入变为输出四边形/立方体。
这很容易处理:use gl_PrimitiveIDIn
。因为您将点作为输入,所以原始计数与顶点计数相同。因此,如果你有3x3的空间,并且gl_PrimitiveIDIn
是4,你知道你在那个空间的(1,1)部分:
vec2 spacePos.xy = vec2(mod(gl_PrimitiveIDIn, space.x), (gl_PrimitiveIDIn / space.y));
这是您在抽象空间中的XY索引。请注意,space
应该是某个ivec2
统一变量,它定义了您拥有的X和Y中的索引数。 3D版本稍微复杂一些,但也可行。
获得抽象空间索引后,可以根据该位置计算顶点位置。我假设你知道怎么做。