【问题标题】:GLSL rendering in 2DGLSL 2D 渲染
【发布时间】:2011-07-20 14:45:40
【问题描述】:

(OpenGL 2.0)

我设法在 opengl 中进行了一些不错的文本渲染,并决定让它由着色器设计。 然而,在固定管道模式下看起来不错的渲染字体纹理在 GLSL 模式下看起来很不愉快。

在固定管线模式下,我看不出 GL_LINEAR 和 GL_NEAREST 过滤有什么区别,这是因为纹理实际上不需要过滤,因为我设置了正交投影并将四边形的宽度和高度与纹理坐标对齐。

现在,当我尝试使用着色器对其进行渲染时,我可以看到一些非常糟糕的 GL_NEAREST 过滤伪影,并且对于 GL_LINEAR,纹理显得过于模糊。

固定管道,令人满意,质量最好(线性/最近没有区别):

GLSL,最近(可见伪影,例如,查看分数字形):

GLSL,线性(太模糊):

着色器程序:

Vertex shader was successfully compiled to run on hardware.
Fragment shader was successfully compiled to run on hardware.
Fragment shader(s) linked, vertex shader(s) linked. 

------------------------------------------------------------------------------------------
 attribute vec2 at_Vertex;
 attribute vec2 at_Texcoord;
 varying vec2 texCoord;


 void main(void) {
     texCoord = at_Texcoord;
    gl_Position = mat4(0.00119617, 0, 0, 0, 0, 0.00195503, 0, 0, 0, 0, -1, 0, -1, -1, -0, 1)* vec4(at_Vertex.x, at_Vertex.y, 0, 1);
}

-----------------------------------------------------------------------------------------
 varying vec2 texCoord;
 uniform sampler2D diffuseMap;
 void main(void) {
     gl_FragColor = texture2D(diffuseMap, texCoord); 
 }

四重渲染,已修复:

    glTexCoord2f (0.0f, 0.0f);
            glVertex2f (40.0f, 40.0f);
            glTexCoord2f (0.0f, 1.0f);
            glVertex2f ((font.tex_r.w+40.0f), 40.0f);
            glTexCoord2f (1.0f, 1.0f);
            glVertex2f ((font.tex_r.w+40.0f), (font.tex_r.h+40.0f));
            glTexCoord2f (1.0f, 0.0f);
            glVertex2f (40.0f,              (font.tex_r.h+40.0f));

四重渲染,着色器模式:

            glVertexAttrib2f(__MeshShader::ATTRIB_TEXCOORD, 0.0f, 0.0f);
            glVertexAttrib2f(__MeshShader::ATTRIB_VERTEX, 40.0f, 40.0f);
            glVertexAttrib2f(__MeshShader::ATTRIB_TEXCOORD, 0.0f, 1.0f);
            glVertexAttrib2f(__MeshShader::ATTRIB_VERTEX, (font.tex_r.w+40.0f), 40.0f);
            glVertexAttrib2f(__MeshShader::ATTRIB_TEXCOORD, 1.0f, 1.0f);
            glVertexAttrib2f(__MeshShader::ATTRIB_VERTEX, (font.tex_r.w+40.0f), (font.tex_r.h+40.0f));
            glVertexAttrib2f(__MeshShader::ATTRIB_TEXCOORD, 1.0f, 0.0f);
            glVertexAttrib2f(__MeshShader::ATTRIB_VERTEX, 40.0f,                (font.tex_r.h+40.0f));

在这两种情况下,矩阵都是从同一个源计算的,尽管出于性能原因,如您所见,我在这样一个函数的帮助下将常量值写入着色器代码(如果这是原因,如何我写得对吗?):

std::ostringstream buffer;
    buffer << f;
    return buffer.str().c_str();

其中“f”是一些双精度值。

编辑: 我进一步研究的结果有点令人惊讶。

现在我将顶点坐标乘以 CPU 上的相同正交矩阵(而不是像以前那样在顶点着色器中),并且我在顶点着色器中保持顶点不变,只是将它传递给 gl_Position。我简直不敢相信,但这确实有效并且实际上解决了我的问题。每个操作都是在浮点数上进行的,就像在 GPU 中一样。

似乎矩阵/顶点乘法在 CPU 上更准确。 问题是:为什么?

编辑:实际上,整个原因是不同的矩阵来源..!真的,非常小的错误!
Nicol 最接近解决方案。

【问题讨论】:

  • 另外,现在我用 uniform 切换了常量矩阵值,并将计算出的矩阵直接传递到着色器中。尽管如此,质量还是很糟糕。
  • 没有贡献任何东西:我认为第三个看起来比第一个好得多。
  • 但是对于较小的文本大小,它变得不可读。

标签: c++ opengl glsl shader


【解决方案1】:

尽管出于性能原因,如您所见,我将常量值写入着色器代码

这对你的表现没有帮助。上传单个矩阵统一对于大多数 OpenGL 着色器来说是相当标准的,并且在性能方面不会花费任何重要的成本。

似乎矩阵/顶点乘法在 CPU 上更准确。问题是:为什么?

这不是更准确;它只是使用不同的矩阵。如果您通过着色器制服将该矩阵传递给 GLSL,您可能会得到相同的结果。您在着色器中使用的矩阵与您在 CPU 上使用的矩阵不同。

【讨论】:

  • 感谢您为我指明了正确的方向。确实,问题出在不同的矩阵源上,我只是第一次没有看到。接受适合你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 2013-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
相关资源
最近更新 更多