【问题标题】:Pixel perfect text rendering in perspective projection透视投影中的像素完美文本渲染
【发布时间】:2018-01-23 18:42:29
【问题描述】:

我正在尝试在透视投影中将文本渲染为带纹理的四边形(不想使用正射投影),但我正在努力解决像素对齐问题。

设置很简单,我有 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;
}

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

如果是简单的顶点着色器

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

文字是完全模糊还是完全清晰

将顶点位置移至视口空间似乎是合乎逻辑的,将其四舍五入并将其移回,但似乎缺少某些东西。

编辑:解释我如何计算比例因子。

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

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

【问题讨论】:

  • 我看不出scale 计算应该如何工作。透视划分不取决于点到相机的距离,而是点到包含相机的平面之间的距离,并且平行于图像平面(或者换句话说,距离的正交投影)投影的主轴)。对于不在该主轴上的任何点,您的比例因子都应该是错误的。
  • @derhass 为比例计算添加了更多细节
  • 你的解释没有解决我的顾虑。在图像中,你的文字可以在任意高度,你计算length(pos - camPos),所以你使用的“相机-文字距离”并不是你在图中绘制的水平距离。此外,现在您引入了pxFOV,将角度与屏幕尺寸相关联,这根本没有任何意义。
  • 很可能它是零意义的,事实是只有亚像素错误是纯粹的机会。什么是正确的解决方案?

标签: opengl glsl text-rendering


【解决方案1】:

在我看来,由于数字问题,您正在遭受 z 缓冲区的冲突。

也许您可以为文本 z 坐标添加一点值,将其与背景稍微分开。

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

【讨论】:

  • z 值/深度测试与问题中描述的问题有什么关系?
  • 我刚刚看了图片并描述了我所看到的。
  • 没有Z战。字体的轮廓和面在同一个纹理中,纹理过滤在最近邻上,所有透明片段都被丢弃。由于字母之间没有重叠,因此最终绘制的两个片段不会具有相同的坐标。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多