(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"является некоторым двойным значением.
РЕДАКТИРОВАТЬ: Результат моих дальнейших исследований несколько удивителен.
Теперь я умножаю координаты вершины на ту же ортогональную матрицу наПроцессор (не в вершинном шейдере, как раньше), и я оставляю вершину нетронутой в вершинном шейдере, просто передавая ееgl_Position.Я не мог поверить, но это действительно работает и фактически решает мою проблему.Каждая операция выполняется с плавающей запятой, как в графическом процессоре.
Похоже, что умножение матрицы / вершины намного более точно на процессоре.вопрос: почему?
РЕДАКТИРОВАТЬ: На самом деле, вся причина была в разных матричных источниках ..!Действительно, очень маленькая ошибка!
Николь был ближайшим решением.