gpt4 book ai didi

python - 使用opengl4,可以将`uniform`变量映射到我的用户空间内存吗?

转载 作者:行者123 更新时间:2023-11-30 22:46:44 25 4
gpt4 key购买 nike

(到目前为止,我在https://gamedev.stackexchange.com/questions/133399/can-i-map-uniform-variables中问了同样的问题,但没有答案)。

我实际上只是从GLSL开始,我使用的是python,但实际上我无法运行330(Debian上的Intel hd3000),所以我使用的是130,到目前为止还可以。

我首先开始使用in,但对uniform变量一无所知,我使用了一段代码,该代码允许我将in变量映射到用户空间内存中,然后使用ctypes将其映射到numpy数组。

在我的循环中,我致电:

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glDrawArrays(GL_TRIANGLES, 0, 3)


之后,我将与顶点关联的变量映射回我的用户空间:

def map_buffer(size):
func = ctypes.pythonapi.PyBuffer_FromReadWriteMemory
func.restype = ctypes.py_object
p = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE)
buffer = func(ctypes.c_void_p(p), size)
array = np.frombuffer(buffer, dtype='float32')
return array


这段代码基本上只使用 glMapBuffer返回的指针,并创建一个从该位置开始的缓冲区数组。

我可以使用 numpy毫无问题地操作该数组,然后取消映射,以便下一个循环可以看到更改,到目前为止,只有旋转三角形的顶点。

现在,我的一系列问题很简单:


看来我应该使用 uniform,不是吗?
如果是这样,我看不到如何映射 uniform变量,而我真的很喜欢使用 numpy进行操作,如何将统一内存映射到我的用户空间?
使用 in而不是 uniform是否会有性能损失? (除了在python上进行映射的自然开销外,由于我认为在此过程中未分配内存,因此足够了)。


从着色器的角度来看,据我所知统一是恒定的或不变的,因此只能修改外部着色器。到目前为止,这就是我使用 in变量的方式。因此,与 uniform相比,首选 in似乎很自然,但是与 in相比,我更喜欢 uniform的API,除非存在性能问题,我将继续使用 in

再见

最佳答案

我将分别解决您问题的不同部分。

“映射制服”

您可以将GL缓冲区对象用作统一值的后端存储。这个概念称为Uniform Buffer Object (UBO),自Ope​​nGL 3.1起可用。

关键思想是可以在GLSL着色器代码中的interface blocks中使用统一变量,如下所示

layout(std140) uniform some_block_name {
vec4 foo;
float bar;
mat4 baz;
}


请注意,单个着色器中可以具有不同的统一块,并且每个块都可以从不同的缓冲区对象(您必须在CPU端绑定)中获取数据。

如果您未指定任何 layout,则GL会根据需要将数据布置在缓冲区中,并且您基本上必须查询每个变量的字节偏移量(就像您必须查询普通变量的位置一样)制服)。但是,像我在示例中一样使用 std(140)布局将使用一些标准化的对齐规则,因此您可以直接计算每个成员的偏移量,而不必查询它,并且它的优点是不会依赖于GL实施。确切的对齐规则可以在OpenGL规范中找到,我也确实复制了它们 in this answer here on SO

统一与顶点属性


  从着色器的角度来看,据我所知统一是恒定的或不变的,因此只能修改外部着色器。到目前为止,这就是我使用 in变量的方式。因此,与 uniform相比,更倾向于使用 in


您应该不以某种抽象的流水线阶段来考虑这一点,而应以单个着色器调用为中心。
顶点着色器的 in put是所谓的顶点属性。这些是每个顶点确实(或至少可能)变化的值。另一方面,制服在整个绘制调用过程中保持不变-这意味着顶点属性是每次调用都不同的数据,而制服在它们之间共享。

因此,这意味着要使用所有的顶点数据到顶点属性中。然后,您将计算所需的一些额外参数(但不依赖于确切的顶点)放入统一中。


  我可以使用numpy毫无问题地操作该数组,然后取消映射它,以便下一个循环可以看到更改,到目前为止,只有旋转三角形的顶点。


目前尚不清楚您最终想要实现什么,但是您在这里所做的并不是应该如何使用渲染管道。

这个想法是您的模型是恒定的,只有变换会改变。因此,您只需将其上载到缓冲区中,然后在每次绘制时让GPU重新转换。通常,我们为此使用4x4矩阵和线性代数,因此我们只需为绘图调用更新一些统一的矩阵,而无需重新指定几何形状(除非我们实际上要对其进行变形-在CPU上,我们通常不这样做)不想)。

但是,随着可编程GPU灵活性的提高,制服和顶点属性之间的界限开始变得模糊。从概念上讲,您现在可以执行类似

uniform vec3 vertexPosition[someBigNumber];
// ...
vec3 pos = vertexPosition[gl_VertexID]
gl_Position = some_matrix * vec4(pos, 1.0);


这样,您可以解决一些顶点属性的限制(即,有16个属性插槽,每个插槽最多一个vec4),但是取决于GPU,您可能会或可能不会以性能损失的形式付出一些代价,这是由于间接的另一层。某些GPU确实具有特殊的硬件单元,这些硬件单元优化了顶点属性的提取(允许它更好地计划顶点着色器调用)。还应注意,统一存储器本身通常仅限于2kB,UBO限于64k。但是,您可以将其他缓冲区对象类型用于此类用法(例如 texture buffer objectsshader storage buffer objects)。

您的实际问题


  
  看来我应该使用制服,不是吗?
  


好吧,目前尚不清楚您到底要实现什么目标,因此我无法给出明确的答案。在正常情况下,顶点的位置被视为顶点属性,因此您不应为此使用制服。


  
  如果是这样,我看不到如何映射统一变量,并且我真的很喜欢使用numpy进行操作,如何将统一内存映射到我的用户空间?
  


您可以使用UBO。


  
  使用in而不是统一是否会有性能损失? (除了在python上进行映射的自然开销外,由于我认为在此过程中未分配内存,因此足够了)。
  


这在很大程度上取决于。关于您的实际用例和数据访问模式。在GPU上。在您的实际工作量上-即顶点着色器可能不是瓶颈(在每个draw调用仅绘制一个三角形的情况下当然不是这样),因此即使VS在概念上存在一些性能差异,也可能对实际渲染性能的影响为零。

我仍然要说,至少在正常使用情况下,对每个顶点数据使用顶点属性至少应与使用制服一样快或更快。

关于python - 使用opengl4,可以将`uniform`变量映射到我的用户空间内存吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40792839/

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