I программирование с C++ + SDL2 + GLEW + Opengl 4.1 небольшая игра воксела, немного напоминающая Minecraft.Оптимизация рендеринга Voxel с геометрическим шейдером
Я пытаюсь оптимизировать рендеринг вокселей, где могу.
Я помещаю мир в куски, и это куски в блоки.
Каждый блок содержит блоки 16x16x16.
Теперь, если отредактируйте фрагмент (удалите/поместите блок) Я перестрою полный кусок и соседний кусок и загружаю его с помощью vao и vbo на графическую карту.
Теперь, чтобы свести к минимуму данные вершин, я должен перейти от процессора к gpu. Я использую геометрические шейдеры.
Прежде всего, это хорошая идея?
Я имею в виду, что каждый кадр геометрического шейдера должен вычислять примитив для каждой поверхности вокселя.
Однако я запрограммировал вершинный шейдер так, что мне нужно передать только одну вершину для каждой грани блока.
Чтобы сделать это, я использовал vec4.
Первые 3 элемента (x, y, z), которые я использовал для положения блока, и 4. Элемент (w) Я использовал для указания, в каком направлении отображается лицо.
0 означает назад, 1 означает фронт, 2 означает левый, 3 означает право, 4 означает дно, 5 означает верх.
Просьба игнорировать УФ и нормальные на данный момент.
Далее я загружаю GLbyte вместо GLfloat.
Это хорошая идея?
Что было бы лучше/быстрее?
#version 410
uniform mat4 un_Combined;
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
in vec2 ge_UV[];
out vec2 fr_UV;
out vec3 fr_Normal;
void main()
{
vec4 o = gl_in[0].gl_Position.xyzw;
if(o.w == 0)
{
gl_Position = un_Combined * vec4(o.x, o.y, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, -1);
EmitVertex();
}
else
if(o.w == 1)
{
gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
}
else
if(o.w == 2)
{
gl_Position = un_Combined * vec4(o.x, o.y, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(-1, 0, 0);
EmitVertex();
}
else
if(o.w == 3)
{
gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(1, 0, 0);
EmitVertex();
}
else
if(o.w == 4)
{
gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, -1, 0);
EmitVertex();
}
else
{
gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z + 1, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x, o.y + 1, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 0, 1);
EmitVertex();
gl_Position = un_Combined * vec4(o.x + 1, o.y + 1, o.z, 1);
fr_UV = vec2(0, 0);
fr_Normal = vec3(0, 1, 0);
EmitVertex();
}
EndPrimitive();
}
Слишком плохо, что вы не используете 4.3, тогда вы можете запускать вычислительные шейдеры для генерации кусков. –
Спасибо, я не знал, что «вычислительный шейдер», похоже, является еще одним хорошим подходом. –