我正在尝试在透视投影中渲染文本作为纹理四边形(不想使用正投影),我正在努力处理像素对齐。
设置很简单,我在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个像素),文本的比例似乎都是正确的。缩放可能只是轻微错误并导致模糊效果,但我看不出如何。
答案 0 :(得分:0)
在我看来,由于数字问题,你正在遭受z-buffer战斗。
也许你可以在文本z坐标上添加一点值,将它与背景分开一点。
另一种解决方案是避免文本比例 - 非量表计算。
您可以通过在CPU端对每个文本进行透视数学来计算像素锚定。然后用正投影显示它。