透视投影中的像素完美文本渲染

时间:2017-08-15 19:01:17

标签: opengl glsl text-rendering

我正在尝试在透视投影中渲染文本作为纹理四边形(不想使用正投影),我正在努力处理像素对齐。

设置很简单,我在3D中使用对齐锚点的文本,我将其模型转换更改为广告牌转换,并计算比例(三角形相似度)以使文本始终具有相同的大小。由于文本四边形的几何体是使用与像素相对应的世界单位构造的,因此无论相机方向或锚点偏移,结果文本确实看起来都是相同的大小。

Vector3d dist = camera.getPosition();
dist.sub(translation);

double pxFov = camera.getFOV() / camera.getScreenWidth();
double scale = Math.sin(pxFov) / Math.sin((Math.PI / 2) - pxFov) 
            * dist.length() * camera.getAspectRatio();

V.getRotationScale(R);
R.transpose();

M.setIdentity();
M.setRotation(R);
M.setScale(scale);
M.setTranslation(translation);

其中 V 是4x4摄像机视图矩阵, R 临时3x3矩阵, M 是用于 MVP的4x4模型转换矩阵计算。

我找到supposed solution,但它只是略微改变了渲染文字的行为,而不是修复问题。

使用顶点着色器时

void main () {
    vec2 view = vec2(1280, 720);

    vec4 cpos = MVP * vec4 (position, 1.0f);
    vec2 p = floor(cpos.xy * view*0.5/cpos.w);
    p += 0.5; // does not influence result
    cpos.xy = p * (2.0/view*cpos.w);

    gl_Position = cpos;
}

文本确实在某些地方呈现清晰,在某些地方模糊

text blurred in waves

如果是简单的顶点着色器

void main () {
    gl_Position = MVP * vec4 (position, 1.0f);
}

是完全模糊或完全清晰的文字

sort of completely sharp

completely blurred

将顶点位置设置为视口空间,将其四舍五入并将其向后移动似乎是逻辑上的,但似乎缺少某些东西。

编辑:说明我如何计算比例因子。

Scale factor explanation

在这里你可以看到我的直角三角形为红色,绿色和蓝色线条。知道红色长度(相机文本锚距离),红色和蓝色之间的角度((fov / 2)/(屏幕宽度/ 2)),红色和绿色之间的角度是直角,我可以使用正弦法来计算绿线的长度,也是当前投影中具有相同尺寸的一个纹素的比例。

无论相机/文字方向/位置(所需的8个像素),文本的比例似乎都是正确的。缩放可能只是轻微错误并导致模糊效果,但我看不出如何。

1 个答案:

答案 0 :(得分:0)

在我看来,由于数字问题,你正在遭受z-buffer战斗。

也许你可以在文本z坐标上添加一点值,将它与背景分开一点。

另一种解决方案是避免文本比例 - 非量表计算。
您可以通过在CPU端对每个文本进行透视数学来计算像素锚定。然后用正投影显示它。