如何在C中最好地编写体素引擎并考虑到性能

如何在C中最好地编写体素引擎并考虑到性能

我是OpenGl中的一个电枢,因此我只想学习现代OpenGl 4.x的东西。一旦我完成了基本教程(例如旋转立方体),我决定尝试创建一个基于体素的程序,仅处理立方体。这个程序的目标是快速,使用有限的CPU功率和内存,并且是动态的,因此地图大小可以改变,只有在数组中它表示块被填充时才会绘制块。

我有一个VBO,其中包含由三角形构成的立方体的顶点和索引。在开始时,如果渲染函数我告诉OpenGl要使用的着色器,然后在完成后绑定VBO我执行此循环

绘制立方体循环:

//The letter_max are the dimensions of the matrix created to store the voxel status in// The method I use for getting and setting entries in the map are very efficient so I have not included it in this examplefor(int z = -(z_max / 2); z < z_max - (z_max / 2); z++){
    for(int y = -(y_max / 2); y < y_max - (y_max / 2); y++)
    {
        for(int x = -(x_max / 2); x < x_max - (x_max / 2); x++)
        {
            DrawCube(x, y, z);
        }
    }}

Cube.c

#include "include/Project.h"void CreateCube(){
    const Vertex VERTICES[8] =
    {
    { { -.5f, -.5f,  .5f, 1 }, { 0, 0, 1, 1 } },
    { { -.5f,  .5f,  .5f, 1 }, { 1, 0, 0, 1 } },
    { {  .5f,  .5f,  .5f, 1 }, { 0, 1, 0, 1 } },
    { {  .5f, -.5f,  .5f, 1 }, { 1, 1, 0, 1 } },
    { { -.5f, -.5f, -.5f, 1 }, { 1, 1, 1, 1 } },
    { { -.5f,  .5f, -.5f, 1 }, { 1, 0, 0, 1 } },
    { {  .5f,  .5f, -.5f, 1 }, { 1, 0, 1, 1 } },
    { {  .5f, -.5f, -.5f, 1 }, { 0, 0, 1, 1 } }
    };

    const GLuint INDICES[36] =
    {
    0,2,1,  0,3,2,
    4,3,0,  4,7,3,
    4,1,5,  4,0,1,
    3,6,2,  3,7,6,
    1,6,5,  1,2,6,
    7,5,6,  7,4,5
    };

    ShaderIds[0] = glCreateProgram();
    ExitOnGLError("ERROR: Could not create the shader program");
    {
    ShaderIds[1] = LoadShader("FragmentShader.glsl", GL_FRAGMENT_SHADER);
    ShaderIds[2] = LoadShader("VertexShader.glsl", GL_VERTEX_SHADER);
    glAttachShader(ShaderIds[0], ShaderIds[1]);
    glAttachShader(ShaderIds[0], ShaderIds[2]);
    }
    glLinkProgram(ShaderIds[0]);
    ExitOnGLError("ERROR: Could not link the shader program");

顶点着色器仅处理顶点的旋转和变换,片段着色器仅处理颜色,它们运行起来并不昂贵,因此它们不是瓶颈。

如何改进此代码以提高效率并充分利用现代OpenGL功能来降低开销?

PS我不是在寻找一本书或一个工具或一个非现场资源作为答案我使用背面剔除和OpenGL深度测试试图提高速度但是它们没有产生显着的差异它仍然需要~50ms渲染帧,这对于32 * 32 * 32的体素网格来说太多了。

这是我正在做的截图:

https://img2.mukewang.com/5d53bbc8000173ea08040665.jpg

这里链接到完整代码:


倚天杖
浏览 727回答 2
2回答

开满天机

如果您正在进行单独的绘制调用并为每个特定的多维数据集调用着色器执行,这将是一个巨大的性能损失。我肯定会推荐实例化 - 这样你的代码就可以进行一次绘制调用,并且所有的多维数据集都将被渲染。查找glDrawElementsInstanced的文档,但是这种方法也意味着你必须有一个矩阵的“缓冲区”,每个体素立方体一个,并且必须使用gl_InstanceID访问着色器中的每一个以索引到正确的矩阵。关于深度缓冲区,如果立方体矩阵以某种方式从摄像机前后排序,那么渲染将会节省,因此早期z深度测试的性能优势对于已经存在的任何可能的片段都会失败 - 渲染的体素立方体。
打开App,查看更多内容
随时随地看视频慕课网APP