[英]GLSL rendering in 2D
(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));
在这两种情况下,矩阵都是从同一个源计算的,尽管出于性能原因,如您所见,我在 function 的帮助下将常量值写入着色器代码(如果这是原因,我该怎么写他们正确吗?):
std::ostringstream buffer;
buffer << f;
return buffer.str().c_str();
其中“f”是一些双值。
编辑:我进一步研究的结果有点令人惊讶。
现在我将顶点坐标乘以 CPU 上的相同正交矩阵(而不是像以前那样在顶点着色器中),并且我在顶点着色器中保持顶点不变,只是将它传递给 gl_Position。 我简直不敢相信,但这确实有效并且实际上解决了我的问题。 每个操作都是在浮点数上进行的,如 GPU。
似乎矩阵/顶点乘法在 CPU 上更准确。 问题是:为什么?
编辑:实际上,整个原因是不同的矩阵来源..,真的,真的很小的错误!
Nicol 最接近解决方案。
尽管出于性能原因,如您所见,我将常量值写入着色器代码
这不会帮助你的表现。 对于大多数 OpenGL 着色器来说,上传单个矩阵制服是相当标准的,并且在性能方面不会花费你任何重要的成本。
似乎矩阵/顶点乘法在 CPU 上更准确。 问题是:为什么?
这不是更准确; 它只是使用不同的矩阵。 如果您通过着色器制服将该矩阵传递给 GLSL,您可能会得到相同的结果。 您在着色器中使用的矩阵与您在 CPU 上使用的矩阵不同。
我认为问题在于半像素偏移。
看: http://drilian.com/2008/11/25/understanding-half-pixel-and-half-texel-offsets/
你可以试试:
texCoord = at_Texcoord + vec2(0.5,0.5) / textureSize(diffuseMap,0);
再见。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.