在简单的体素渲染器中实现环境光遮挡

Implementing Ambient Occlusion in simple Voxel Renderer

我目前正在尝试在一个简单的体素渲染器中实现环境光遮蔽,每个块都使用 24 个顶点和 12 个三角形渲染(除非不可见),因此没有任何类型的网格划分。

我遵循了 this 教程,了解类似 minecraft 世界的环境遮挡如何工作,但它没有解释如何在着色器/图形编程中实际实现它,所以我到目前为止所做的只是我没有受过教育的最佳猜测。

基本思想是,对于每个顶点,从周围的块中生成一个关于环境光遮挡应该如何的值。 (没关系我的价值观目前是完全错误的)。这些是从 0(没有周围环境)到 3(顶点完全包围)我链接的教程中的图片有助于解释这一点。

所以我试过了,但它似乎并没有使顶点周围的区域变暗,而是使整个三角形变暗,顶点位于...如何让它不那样做?我是着色器和图形编程方面的初学者,所以非常感谢您的帮助:D

这是我的顶点着色器,输入是

#version 450

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 tex_coord;
layout(location = 3) in vec2 tile_uv;
layout(location = 4) in uint ambient_occlusion;

layout(location = 0) out vec3 v_position;
layout(location = 1) out vec3 v_normal;
layout(location = 2) out vec2 v_tex_coord;
layout(location = 3) out vec2 v_tile_uv;
layout(location = 4) out uint v_ambient_occlusion;

layout(set = 0, binding = 0) uniform Data {
    mat4 world;
    mat4 view;
    mat4 proj;
    vec2 tile_size;
} uniforms;

void main() {
    mat4 worldview = uniforms.view * uniforms.world;
    v_normal = mat3(transpose(inverse(uniforms.world))) * normal;
    v_tex_coord = tex_coord;
    v_tile_uv = tile_uv;
    v_position = vec3(uniforms.world * vec4(position, 1.0));
    v_ambient_occlusion = ambient_occlusion;
    gl_Position = uniforms.proj * worldview * vec4(position.x, position.y, position.z, 1.0);
}

这是我的片段着色器:

#version 450

layout(location = 0) in vec3 v_position;
layout(location = 1) in vec3 v_normal;
layout(location = 2) in vec2 v_tex_coord;
layout(location = 3) in vec2 v_tile_uv;
layout(location = 4) in flat uint v_ambient_occlusion;

layout(location = 0) out vec4 f_color;

layout(set = 0, binding = 1) uniform sampler2D block_texture;

void main() {
    vec3 ao_color;
    switch (v_ambient_occlusion) {
        case 0: ao_color = vec3(1.0, 0.0, 0.0); break;
        case 1: ao_color = vec3(0.0, 1.0, 0.0); break;
        case 2: ao_color = vec3(0.0, 0.0, 1.0); break;
        case 3: ao_color = vec3(1.0, 1.0, 1.0); break;
    }

    f_color = texture(block_texture, v_tex_coord);
    f_color.rgb = mix(f_color.rgb, vec3(0.05, 0.05, 0.05), 0.3 * v_ambient_occlusion * distance(v_tile_uv, vec2(0.5)));
}

这"flat"部分...

layout(location = 4) in flat uint v_ambient_occlusion;

... 表示对整个三角形使用相同的值(取自激发顶点)。如果你想在 3 个每个顶点值之间进行插值,那么只需删除 flat 限定符。

请注意,目前这是一个整数属性值,必须是平面阴影,因此您也需要将输入转换为浮点数。