为什么尽管源代码没有变化,但一个系统与另一个系统的碎片数量却有很大差异?
Why does the number of fragments vary significantly from one system to the other despite no changes in source code?
我已经实现了一个着色器来计算它生成了多少片段。
我注意到,在不更改代码的情况下,计算生成的碎片数在不同的机器上是不同的。
在一台机器上是一致的(总是相同的值),但在不同的计算机上明显不同。
显示器分辨率相同,但显卡不同。我的期望是,如果几何体、着色器、C++ 代码、视口尺寸和监视器相同,片段数也应该相同,但似乎我错了,为什么会这样?
编辑:
要求我添加 MVC 示例。老实说,我认为这实际上与问题无关,因为这不是我的代码特有的行为,而是 属性 的 GPU none the less:
顶点着色器:
#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;
}
OpenGL 不是像素精确的 API。因此,实现可以以稍微不同的方式实现光栅化,或提供不同的数字精度,从而生成不同数量的片段。
此外,如果您渲染的是真实场景而不是全屏四边形,则可能还有其他效果。例如,假设您在渲染命令中有两个三角形,其中一个比另一个更近。在某些硬件上,较近的三角形会在较远的三角形完全光栅化之前完全 read/modify/write 通过深度缓冲区。如果 early depth tests are on,则生成来自更远三角形的片段的 none 个片段着色器。
但是如果同时处理来自两个三角形的片段会怎样?这可能会发生,其原因将取决于硬件(以及渲染命令中三角形之间的距离)。对于某些像素,较远的三角形和较近的三角形将计算其部分片段。
如果您将图像 load/store 操作与深度测试结合使用,这也是 turn on early fragment tests 很重要的原因。
我已经实现了一个着色器来计算它生成了多少片段。
我注意到,在不更改代码的情况下,计算生成的碎片数在不同的机器上是不同的。
在一台机器上是一致的(总是相同的值),但在不同的计算机上明显不同。
显示器分辨率相同,但显卡不同。我的期望是,如果几何体、着色器、C++ 代码、视口尺寸和监视器相同,片段数也应该相同,但似乎我错了,为什么会这样?
编辑: 要求我添加 MVC 示例。老实说,我认为这实际上与问题无关,因为这不是我的代码特有的行为,而是 属性 的 GPU none the less:
顶点着色器:
#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;
}
OpenGL 不是像素精确的 API。因此,实现可以以稍微不同的方式实现光栅化,或提供不同的数字精度,从而生成不同数量的片段。
此外,如果您渲染的是真实场景而不是全屏四边形,则可能还有其他效果。例如,假设您在渲染命令中有两个三角形,其中一个比另一个更近。在某些硬件上,较近的三角形会在较远的三角形完全光栅化之前完全 read/modify/write 通过深度缓冲区。如果 early depth tests are on,则生成来自更远三角形的片段的 none 个片段着色器。
但是如果同时处理来自两个三角形的片段会怎样?这可能会发生,其原因将取决于硬件(以及渲染命令中三角形之间的距离)。对于某些像素,较远的三角形和较近的三角形将计算其部分片段。
如果您将图像 load/store 操作与深度测试结合使用,这也是 turn on early fragment tests 很重要的原因。