OpenGL纹理伪影



我已经为2D实现了一个简单的批处理渲染设置。它似乎在起作用,除了一些看起来像在单个表面上Z战斗的工件。

TL;博士?我录制了一段视频,展示了我所看到的;修复";

有三种纹理绑定:

  • 尺寸为1x1的纯白色纹理
  • 长满青草的瓷砖;背景";纹理
  • 一个简单的木箱

有些四边形仅带有纹理,有些仅使用平面颜色着色,有些带有纹理并着色。

这是顶点着色器:

#version 460 core
layout(location = 0) in vec3  _position;
layout(location = 1) in vec4  _color;
layout(location = 2) in vec2  _texture_coords;
layout(location = 3) in int   _texture_index;
layout(location = 4) in float _tiling_factor;
uniform mat4 viewproj_matrix;
out vec4     color;
out vec2     texture_coords;
out flat int texture_index;
out float    tiling_factor;
void main()
{
color          = _color;
texture_coords = _texture_coords;
texture_index  = _texture_index;
tiling_factor  = _tiling_factor;

gl_Position = viewproj_matrix * vec4(_position, 1.0);
}

碎片着色器:

#version 460 core
layout(location = 0) out vec4 final_color;
in vec4     color;
in vec2     texture_coords;
in flat int texture_index;
in float    tiling_factor;
uniform sampler2D textures[32];
void main()
{
final_color = (
texture(textures[texture_index], texture_coords * tiling_factor) * color
);
}

当然,这很简单。但我也是一个新手,所以简单就是好。此行为似乎与采样多个纹理有关。我这么说是因为,正如我在视频中演示的那样,如果我只采样三个绑定纹理中的一个,伪影就会消失。当我强制批次大小为单个四边形时,这种情况也会自行解决。

以下是绘制平面阴影四边形的代码:

void Renderer2D::draw_quad(const RenderAPI &api, const glm::vec3 &position,
const glm::vec4 &color,
const float rotation, const glm::vec3 &scale) {
if(_batch.quad_count >= _batch.max_quads) {
_flush_and_reset();
}
_batch.api = &api;
glm::mat4 transform = glm::translate(_ident, position) *
glm::rotate(_ident, glm::radians(rotation), _z_axis) *
glm::scale(_ident, scale);
for(uint32_t corner = 0; corner < _corners_per_quad; corner++) {
_batch.vertex_buffer_ptr->position = transform * _vertex_coords[corner];
_batch.vertex_buffer_ptr->color         = color;
_batch.vertex_buffer_ptr->texture_coord = _texture_coords[corner];
_batch.vertex_buffer_ptr->texture_index = _white_texture_index;
_batch.vertex_buffer_ptr->tiling_factor = _default_tiling;
_batch.vertex_buffer_ptr++;
}
_batch.quad_count++;
_stats.quad_count++;
}

如果您对更多内容感兴趣,下面是整个Renderer2D类。希望这是足够的信息,但在整个shebang中也没有那么多代码。

我正在努力寻找解决问题的角度。欢迎任何指导、理论、指针或猜测。我期待着加强我的GPU/3D数学等调试技能

看起来您正试图在单个调用组中渲染多个纹理。这意味着您正在使用不动态统一的变量对纹理进行采样。这会导致采样丢失隐式导数,实际上它们是未定义的。

有很多方法可以分割调用组,以便以动态统一的方式对纹理进行采样。您可以使用3D纹理来保存所有不同的纹理,尽管这需要所有纹理的大小相同,或者使用纹理图集。另一种方法是对每个唯一的纹理使用单独的绘制调用,或者更好地使用MultiDraw命令,这是相同的,但可以将多个绘制调用分组为一个,同时保持调用组的独立性。

最新更新