使用顶点着色器 GLSL 永久移动顶点

Permanently move vertices using vertex shader GLSL

本文关键字:顶点 GLSL 移动      更新时间:2023-10-16

我倾向于GLSL,一般来说是一些OpenGL,我在顶点移动和管理方面遇到了一些麻烦。 我擅长相机旋转和平移,但现在我需要移动一些顶点并让它们保持在新位置。

我想做的是使用顶点着色器移动它们,但也不跟踪它们在矩阵中的新位置(因为我需要独立移动它们,并且在内存和计算能力方面存储这么多矩阵会非常昂贵)。

如果有一种方法可以直接从顶点着色器更改它们在 VBO 中的位置值,那将是最佳的。

有没有办法做到这一点?您还建议其他哪些方法? 提前谢谢。

PS 我正在使用 GLSL 版本 1.30

虽然可以将着色器中的值写入缓冲区,然后从 CPU 客户端读取它(即通过使用glReadPixels()),但我认为这不是您的情况。

您可以使用单个矩阵移动一组顶点,所有这些顶点都具有相同的移动。为什么不使用 CPU 并存储结果,在需要时更新其 gl-buffer?(如果您只是更新 glBuffer,VAO 保持不变)一旦它们被移动,你就不再需要那个矩阵了,对吧?或者,如果您想撤消运动,那么,是的,您还需要存储矩阵。

似乎转换反馈正是您所需要的。

我想做的是使用顶点着色器移动它们,但也不跟踪它们通过矩阵的新位置

如果我理解正确,那么您想要的是将一些顶点发送到 GPU。然后让顶点着色器移动它们。不能,因为顶点着色器只能从顶点缓冲区读取,而不能写回顶点缓冲区。

在内存和计算能力方面,存储这么多矩阵将非常昂贵。

考虑到:

我擅长相机旋转和平移

那么在里面一点也不贵。考虑到您已经拥有相机和视口的viewprojection矩阵。然后,让一个model矩阵包含每个对象的平移、旋转和缩放并不是瓶颈。

在顶点着色器中,您只需拥有:

uniform mat4 mvp; // model view projection matrix
...
gl_Position = mvp * vec4(position, 1.0);

在 CPU 端,您要做的事情:

mvp = projection * view * model;
GLint mvpLocation​ = glGetUniformLocation(shaderGeometryPass, "mvp")
glUniformMatrix4fv(mvpLocation, 1, GL_FALSE, (const GLfloat*)&mvp);

如果这给您带来了性能问题,那么问题出在其他地方。

如果你真的想"保存"你在GPU方面所做的任何更改,那么你必须研究着色器存储缓冲区对象和/或转换反馈。