【问题标题】:Bug Fixing. OpenGL, GLSL sprite grid rendering Issue错误修复。 OpenGL、GLSL sprite 网格渲染问题
【发布时间】:2018-09-02 15:37:41
【问题描述】:

这是一个非常具体的案例,我的想法已经不多了。

我试图在不使用位置作为每个精灵的实例数据的情况下渲染精灵网格。这可以使用 gl_InstanceID 变量来完成。

世界由块组成(16 * 16 * 2(2,因为每个位置有两个精灵/实例))。所有块本身都被正确绘制,但并非所有块都位于相对于另一个块的正确位置。

看起来是这样的:

我使用宽度和高度来指定新行的开始时间。将相机放置在正确的位置时,您可以看到左下角(没问题)

当相机稍微偏离一点时,就会画出来:

现在是右下角。

注意 width = 3(由 printf 语句返回),它清楚地表明不应该有 4 列(但有)。

简而言之,这就是问题所在。

我几乎可以肯定问题出在 GLSL 代码(着色器)上,因为我检查了发送到显卡的所有值及其偏移量。我觉得问题出在 glsl 计算块位置的方式上。

#version 330 core
layout (location = 0) in vec2 v_pos;
layout (location = 1) in vec2 v_uv;
layout (location = 2) in float uv_index;

layout (std140) uniform Matrices
{
    mat4 view;
    mat4 projection;
};
uniform uint diagonalSpriteCount; //used for the uv indexing (of no interest here)
uniform uint chunksOnScreenRow; //what you saw as width on the pictures
uniform vec2 camOffsetToFirst; //this specifies the position to the first instance to be rendered

out vec2 uvCoordinates;

void main()
{
//////////////////////////////////////////
//THIS IS PROBABLY THE ONLY RELEVANT PART FOR YOU
    //i devide the index by two, as only every second instance the position changes
    int posIndex = gl_InstanceID / 2; 
    //every 256 Positions (16 * 16) a chunk is complete, thus the next chunk begins
    int chunkIndex = posIndex / 256;
    //the position of the vertex, first basic quad information and an offset
    gl_Position = projection * view * 
    vec4(v_pos.xy + camOffsetToFirst + 
        vec2(
            //this specifies the x within the chunk
            mod(posIndex, 16)    
                //this is the offset on the x axis, 
                //which depends on which chunk (the chunk the instance belongs to) is currently being rendered 
                //chunksOnScreenRow = width that you saw on the pictures
                + 16 * mod(chunkIndex, chunksOnScreenRow), 
            //this is the position on the y axis, relative to the first element of the current chunk
            floor(mod(posIndex, 256) / 16)   
                //same like with the x axis, offset on y depending on current chunk
                + 16 * floor(float(chunkIndex) / chunksOnScreenRow)
        ), 
    0.0, 1.0); //this is just the rest of the vec 4
//////////////////////////////////////////
    //irrelevant for you
    uvCoordinates = v_uv / diagonalSpriteCount + vec2(
        uv_index / diagonalSpriteCount - floor(uv_index / diagonalSpriteCount),
        floor(uv_index / diagonalSpriteCount) / diagonalSpriteCount
    );
}

这里是数据的结构方式,以备不时之需。


现在我请求你的帮助,如果你碰巧知道什么可能导致这种奇怪的行为。如果您能帮助我找到这种行为的原因,我将永远感激不尽。

编辑:您在图片中看到的每个块都是一个块。您将无法看到单个实例

编辑:显然,如果我在第二个 vec2() 参数中删除 chunkIndex 周围的 float(),偏移量仍然会发生,但会增加一个

【问题讨论】:

  • 乍一看,这似乎是一个错误,可能是在取模方法中引入的。
  • 你的区块只有 6x6 有什么特别的原因吗?还是我错过了什么?
  • 不抱歉,我想我应该更好地指定。我用相同的纹理为每个块着色,因此块中的每个实例共享相同的纹理。我这样做了,所以你可以更容易地看到块边界。所以你看到的是 6*6 的块。但是感谢您指出这一点
  • 你能告诉我camOffsetToFirst每3张图片的值,如果可以的话,还有chunkIndex的输出。假设 projection view 在您的测试中是静态的,那么这里只有两个变量可能出错。
  • @Enfyve chunkIndex 在 GPU 上。不幸的是我无法阅读它。我只能在 CPU 上猜测或计算。投影有点静态(取决于缩放),它确实会改变最大宽度,但不会直接影响绘制哪个块。视图矩阵也改变了截锥体,从而增加了宽度。最后,它与屏幕当前显示的宽度有关。我发现问题的宽度为 3,或者如果我将块的总数更改为 20 x 20,那么甚至 6、7、9、12、13、14、15 ......但是从那里到 20它工作正常

标签: c++ c opengl graphics glsl


【解决方案1】:

好的,我想通了。如果出现 Off by One 错误(就像 Enfyve 所说的那样),不要相信内置的 glsl mod() 函数,因为它会在途中将变量转换为单位并在途中搞砸。

【讨论】:

    猜你喜欢
    • 2016-02-27
    • 2021-10-30
    • 2016-04-30
    • 1970-01-01
    • 2013-10-05
    • 1970-01-01
    • 1970-01-01
    • 2019-08-28
    • 1970-01-01
    相关资源
    最近更新 更多