【发布时间】: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