Почему количество фрагментов значительно отличается от одной системы к другой, несмотря на отсутствие изменений в исходном коде? - PullRequest
0 голосов
/ 26 мая 2018

Я реализовал шейдер, который подсчитывает, сколько фрагментов он генерирует.

Я заметил, что без изменения кода количество подсчитанных сгенерированных фрагментов различается на разных машинах.

Он одинаков на одном компьютере (всегда одинаковое значение), но на разных компьютерах он явно различается.

Мониторы имеют одинаковое разрешение, но графические карты разные.Я ожидаю, что если геометрия, шейдеры, код 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 голосов
/ 26 мая 2018

OpenGL не является пиксельно-точным API.Таким образом, реализации могут реализовывать растеризацию несколько разными способами или обеспечивать разную числовую точность, которая генерирует разное количество фрагментов.

Кроме того, если вы визуализируете реальную сцену, а не просто полноэкранный квад,Там могут быть другие эффекты.Например, предположим, у вас есть два треугольника в команде рендеринга, и один из них ближе, чем другой.На некотором оборудовании более близкий треугольник выполняет полный проход чтения / изменения / записи в буфере глубины, прежде чем дальнейший треугольник будет растеризован вообще.Если ранние тесты глубины выполняются на , то ни один из фрагментных шейдеров для фрагментов из дальнего треугольника не будет получен.

Но что, если фрагменты из обоих треугольников будут обрабатываться одновременно?Это может произойти, и причины этого будут зависеть от аппаратного обеспечения (и расстояния между треугольниками в команде рендеринга).Для некоторых пикселей в дальний треугольник будут подсчитаны некоторые его фрагменты, а также ближний.

По этой же причине важно повернуть на ранних проверках фрагментов если вы используете операции загрузки / сохранения изображения в тандеме с тестами глубины.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...