首页 文章

2D中的GLSL渲染

提问于
浏览
4

(OpenGL 2.0)

我设法在opengl中做了一些不错的文本渲染,并决定将其设计为着色器 . 但是,在固定管道模式下看起来不错的渲染字体纹理在GLSL模式下看起来很不愉快 .

在固定管道模式下,我没有看到GL_LINEAR和GL_NEAREST过滤之间有任何区别,这是因为纹理不需要真正过滤,因为我设置了正交投影并将四边形的宽度和高度与纹理坐标对齐 .

现在,当我尝试使用着色器渲染它时,我可以看到一些非常糟糕的GL_NEAREST过滤瑕疵,而对于GL_LINEAR,纹理看起来太模糊了 .

固定管道,satysfying,最佳质量(线性/最近之间无差异):

GLSL,最近(可见的工件,例如,查看分数字形):

enter image description here

GLSL,线性(太模糊):

enter image description here

着色器程序:

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”是一些双重值 .

EDIT: 我进一步研究的结果有点令人惊讶 .

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

看起来像矩阵/顶点乘法在CPU上更准确 . 问题是:为什么?

EDIT: 实际上,整个原因是不同的矩阵源..!真的,真的很小的虫子!
尼科尔离解决方案最近 .

2 回答

  • 6

    虽然出于性能原因,正如您所看到的,我正在将着色值写入着色器代码中

    这不会对你的表现有所帮助 . 对于大多数OpenGL着色器来说,上传单个矩阵均匀是非常标准的,并且在性能方面不会花费任何重要性 .

    看起来像矩阵/顶点乘法在CPU上更准确 . 问题是:为什么?

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

  • 3

    我认为问题是半像素偏移 .

    看看:http://drilian.com/2008/11/25/understanding-half-pixel-and-half-texel-offsets/

    你可以试试:

    texCoord = at_Texcoord + vec2(0.5,0.5) / textureSize(diffuseMap,0);
    

    再见 .

相关问题