在简单的体素渲染器中实现环境光遮挡
Implementing Ambient Occlusion in simple Voxel Renderer
我目前正在尝试在一个简单的体素渲染器中实现环境光遮蔽,每个块都使用 24 个顶点和 12 个三角形渲染(除非不可见),因此没有任何类型的网格划分。
我遵循了 this 教程,了解类似 minecraft 世界的环境遮挡如何工作,但它没有解释如何在着色器/图形编程中实际实现它,所以我到目前为止所做的只是我没有受过教育的最佳猜测。
基本思想是,对于每个顶点,从周围的块中生成一个关于环境光遮挡应该如何的值。 (没关系我的价值观目前是完全错误的)。这些是从 0(没有周围环境)到 3(顶点完全包围)我链接的教程中的图片有助于解释这一点。
所以我试过了,但它似乎并没有使顶点周围的区域变暗,而是使整个三角形变暗,顶点位于...如何让它不那样做?我是着色器和图形编程方面的初学者,所以非常感谢您的帮助:D
这是我的顶点着色器,输入是
- 顶点位置
- 顶点法线
- tex_coord 在纹理图集中
- tile_uv:块上的位置(left/right bottom/top 为 0 或 1)
- ambient_occlusion 值
#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
限定符。
请注意,目前这是一个整数属性值,必须是平面阴影,因此您也需要将输入转换为浮点数。
我目前正在尝试在一个简单的体素渲染器中实现环境光遮蔽,每个块都使用 24 个顶点和 12 个三角形渲染(除非不可见),因此没有任何类型的网格划分。
我遵循了 this 教程,了解类似 minecraft 世界的环境遮挡如何工作,但它没有解释如何在着色器/图形编程中实际实现它,所以我到目前为止所做的只是我没有受过教育的最佳猜测。
基本思想是,对于每个顶点,从周围的块中生成一个关于环境光遮挡应该如何的值。 (没关系我的价值观目前是完全错误的)。这些是从 0(没有周围环境)到 3(顶点完全包围)我链接的教程中的图片有助于解释这一点。
所以我试过了,但它似乎并没有使顶点周围的区域变暗,而是使整个三角形变暗,顶点位于...如何让它不那样做?我是着色器和图形编程方面的初学者,所以非常感谢您的帮助:D
这是我的顶点着色器,输入是
- 顶点位置
- 顶点法线
- tex_coord 在纹理图集中
- tile_uv:块上的位置(left/right bottom/top 为 0 或 1)
- ambient_occlusion 值
#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
限定符。
请注意,目前这是一个整数属性值,必须是平面阴影,因此您也需要将输入转换为浮点数。