在 3D 空间中使用 GLSL 绘制 2D Mesh Grid
Posted
技术标签:
【中文标题】在 3D 空间中使用 GLSL 绘制 2D Mesh Grid【英文标题】:Draw 2D Mesh Grid using GLSL in 3D space 【发布时间】:2013-11-09 17:47:34 【问题描述】:我希望使用 OpenGL 4.0 在 X 轴上的有限空间内绘制 2D 网格。
我希望使用 GLSL 使用 vert/frag 着色器等来渲染光(使它们出现)。
可以使用较旧的 OpenGL 2.0 方法使用最简单的代码来完成,但当然它不使用照明/着色器来为它们着色:
void Draw_Grid()
for(float i = -500; i <= 500; i += 5)
glBegin(GL_LINES);
glColor3ub(150, 190, 150);
glVertex3f(-500, 0, i);
glVertex3f(500, 0, i);
glVertex3f(i, 0,-500);
glVertex3f(i, 0, 500);
glEnd();
但除了this 之外,我找不到任何教程,我不太了解,无法在 3D 空间中将图形转换为简单的 2D 网格。
【问题讨论】:
如果您已经了解着色器、VBO 等,那么为什么不直接使用它们呢? 我不确定如何实现它,因此试图找到一个教程。我对此的了解非常有限:( 【参考方案1】:是的,您可以只使用着色器来生成几何图形...
-
不要绑定任何 VBO。
致电
glDrawArrays()
在顶点着色器中使用gl_VertexID
或在几何着色器中使用gl_PrimitiveID
以程序方式生成您的东西。
它可以更快,因为没有顶点属性或输入数据。更不用说节省的空间和初始化时间几乎没有。
这是一个使用GL_TRIANGLES
绘制网格的顶点着色器示例:
#version 150
uniform mat4 modelviewMat;
uniform mat3 normalMat;
uniform mat4 projectionMat;
uniform ivec2 dim;
out vec3 esNorm;
const vec2 triOffset[] = vec2[](
vec2(0,0),
vec2(0,1),
vec2(1,1),
vec2(0,0),
vec2(1,1),
vec2(1,0));
void main()
int triVert = gl_VertexID % 6;
int gridIndex = gl_VertexID / 6;
vec2 coord = vec2(gridIndex / dim.x, gridIndex % dim.x);
coord = (coord + triOffset[triVert]) / vec2(dim);
vec4 esVert = modelviewMat * vec4(coord * 2.0 - 1.0, 0.0, 1.0);
gl_Position = projectionMat * esVert;
esNorm = normalMat * vec3(0.0, 0.0, 1.0);
如果没有绑定在我古老的 ATI 卡上的 VBO,我在绘图时确实遇到了一些麻烦。这种方法在我的带有新驱动程序的 Nvidia 卡上运行良好。在此处进一步讨论:Opengl, DrawArrays without binding VBO,其中建议使用glDrawArraysInstanced
/gl_InstanceID
作为替代方案。
进一步说明。我注意到模 %
算术在某些情况下可能有点慢。使用更简单的按位运算或其他技巧可能会加快速度。
【讨论】:
dim+1 是什么意思? @buc030 很好发现。我错误地假设triOffset
会将coord
的范围比dim
增加一。 dim
位于网格单元中,而不是顶点。【参考方案2】:
GLSL 不适合做这样的事情。 GLSL 用于编写以下着色器:
将简单的几何图形细分为稍微复杂的几何图形 将抽象空间中的简单图元转换为剪辑空间 控制片段光栅化过程GLSL 并非用于实际进行绘图调用。是的,您可以使用着色器生成程序几何体,但您总是从在客户端进行几何体和绘制调用开始。
【讨论】:
是的,我希望使用 VBO 在 openGL 4.0+ 中绘制它们,并使用 GLSL 进行照明/着色。这就是为什么我复制到我的问题中的代码不起作用的原因,因为它是 OpenGL 2.0。我不确定如何使用 4.0 中的线条来实现类似对象的网格,也不确定如何使用 .vert 和 .frag 文件来渲染它们。 @Reanimation:那么我建议你阅读 Nicol Bolas 优秀的现代 OpenGL 教程,它解释了 arcsynthesis.org/gltut 的所有内容——在创建网格时,只需将顶点放入一个数组(按顺序)并告诉 OpenGL 从元素 0 开始绘制它…N。以上是关于在 3D 空间中使用 GLSL 绘制 2D Mesh Grid的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 python 从 2d 坐标中获取 3d 空间坐标?
在 Android(和 iOS)上使用 Qt 使用 openGL 绘制具有 3d 效果的 2d 线