尽管源代码没有变化,为什么从一个系统到另一个系统的片段数量变化很大?

时间:2018-05-26 03:38:14

标签: c++ opengl graphics gpu fragment-shader

我已经实现了一个着色器,它会计算它生成的碎片数量。

我注意到,在不更改代码的情况下,不同机器中计算的生成片段数量不同。

它在一台机器上是一致的(总是相同的值),但在不同的计算机上却截然不同。

显示器具有相同的分辨率,但显卡不同。我的期望是,如果几何,着色器,C ++代码,视口尺寸和监视器是相同的,片段的数量也应该相同,但似乎我错了,为什么会这样?

编辑: 请求我添加MVC示例。老实说,我认为它与问题实际上并不相关,因为这不是我的代码特有的行为,而是GPU的特性:

顶点着色器:

#version 430

layout(location = 0) in vec3 position;  // (x,y,z) coordinates of a vertex
layout(location = 1) in vec3 normal;      // normal to the vertex
layout(location = 2) in vec2 uv;        // texture coordinates

out vec3 v_pos;
out vec3 v_norm;
out vec2 v_uv;

uniform mat4 model_m = mat4(1); // model matrix
uniform mat4 view_m = mat4(1);  // view matrix
uniform mat4 proj_m = mat4(1);  // perspective projection matrix

void main()
{
    v_pos = vec3(model_m*vec4(position,1));
    v_norm = vec3(model_m*vec4(normal,1.0));
    v_uv = uv;

    gl_Position = proj_m*view_m*vec4(v_pos, 1.0);
}

片段着色器:

#version 430

layout(location = 0) in vec3 position; // (x,y,z) coordinates of a vertex

out vec3 v_pos;

uniform mat4 model_m = mat4(1); // model matrix

void main()
{
    v_pos = vec3(model_m*vec4(position,1));
}

C ++:

    //Binding the buffer
    glGenBuffers(1, &ssbo);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
    glObjectLabel(GL_BUFFER, ssbo, -1, "\"SSBO\"");
    GLint zero = 0;
    glBufferStorage(GL_SHADER_STORAGE_BUFFER, sizeof(GLint), &zero,
        GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
GLuint *counter;
void render()
{
    glClearColor(0,0.5,0.5,0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(counter);
    mesh->draw();
    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
    GLint z2;
    glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLint), &z2);
    cout << "Fragments: " << z2 << endl;
    GLint zero=0;
    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLint), &zero);endl;

}

1 个答案:

答案 0 :(得分:2)

OpenGL不是像素精确的API。因此,实现可以以稍微不同的方式实现光栅化,或者提供不同的数字精度,从而生成不同数量的片段。

此外,如果您要渲染实际场景而不仅仅是全屏四边形,则可能会有其他效果。例如,假设您在渲染命令中有两个三角形,其中一个比另一个更近。在某些硬件上,较近的三角形在深度缓冲区上进行完全读取/修改/写入传递,然后根本不再进行光栅化。如果early depth tests are on,则不会产生来自更远三角形的片段的片段着色器。

但是如果来自两个三角形的片段同时被处理呢?这可能发生,导致这种情况的原因将取决于硬件(以及渲染命令中三角形之间的距离)。对于某些像素,更远的三角形将获得一些碎片以及更接近的碎片。

如果你在深度测试中使用图像加载/存储操作,这也是turn on early fragment tests的重要原因。