在 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的主要内容,如果未能解决你的问题,请参考以下文章

如何在处理P3D模式下绘制2D字体?

如何在处理 P3D 模式下绘制 2D 字体?

如何使用 python 从 2d 坐标中获取 3d 空间坐标?

在 Android(和 iOS)上使用 Qt 使用 openGL 绘制具有 3d 效果的 2d 线

Three.js - 3D 空间中的 2D 对象(通过 Vertices)

如何在 GLSL 中渲染无限的 2D 网格?