为啥 DirectX/DirectWrite/Direct2D 文本渲染不能像 GDI 一样清晰?

Posted

技术标签:

【中文标题】为啥 DirectX/DirectWrite/Direct2D 文本渲染不能像 GDI 一样清晰?【英文标题】:Why can't DirectX/DirectWrite/Direct2D text rendering be as sharp as GDI?为什么 DirectX/DirectWrite/Direct2D 文本渲染不能像 GDI 一样清晰? 【发布时间】:2012-01-26 14:09:24 【问题描述】:

我已经知道亚像素定位会导致DirectWrite text rendering to be blurry compared to GDI。

但是,我的问题更基础:为什么 DirectWrite(和相关方法)不能像 GDI 一样清晰地呈现文本?

换句话说:是什么阻止了 DirectWrite 能够像 GDI 那样将文本捕捉到最近的像素?

例如,是硬件问题吗?驱动架构问题?它根本没有实施吗?还是别的什么?


小样本:

更大的样本:

Direct2D,别名:

Direct2D,默认:

Direct2D(“经典 GDI”):

Direct2D(“自然 GDI”):

实际经典 GDI:

实际 ClearType GDI:


注意:如果所有在您看来都模糊不清,请运行

document.body.style.zoom = 1 / window.devicePixelRatio

在 Chrome 的控制台中,然后查看。

【问题讨论】:

嗯,是的,我想看看这个问题的答案。这些技术产生的文本过于模糊,不值得使用;我什至不能使用通过 DirectWrite 呈现文本的产品(咳嗽,Firefox)。不幸的是,我有一个偷偷摸摸的怀疑,答案是从事该项目的人都认为这很重要。 因为像素对齐使得渲染文本的宽度无法预测。分辨率无关的文本渲染是圣杯。被 GDI+、WPF 的硬性要求和显示技术的可持续改进所困扰。 DWrite 可以做到,你只需要问。创建 custom render parameters 并将 clearTypeLevel 设置为零。请注意,清晰度是以牺牲准确性为代价的。例如,请参阅 the rotated text 以及它在 GDI 中看起来有多厚实,以及与子像素相比,GDI 中的间距有多不均匀。 @RaymondChen:我之前实际上已经尝试过(在尝试查看 SciTE 的加速文本渲染是否可以变得更清晰时),但它不起作用。也许我做错了——你有一段演示代码可以显示它的渲染很清晰吗? @Mehrdad 我自己从未尝试过,但从阅读文档看来它应该可以工作。也许它只是切换到灰度抗锯齿?无论如何,如果您不喜欢 DirectWrite,请不要使用它。 (与其说宽度是不可预测的,不如说它是不均匀的。在低分辨率下,整个像素都很大。) 【参考方案1】:

你不是在比较喜欢和喜欢。您的 Direct2D 示例都以灰度呈现,而 GDI 和 Linux 示例使用亚像素抗锯齿(在 Windows 上也称为 ClearType)。

此页面描述了启用 cleartype 需要执行的操作:http://msdn.microsoft.com/en-us/library/windows/desktop/dd368170%28v=vs.85%29.aspx

注意在像这样测试渲染时,总是值得使用 Windows 放大镜或类似工具来检查您是否真的得到了您认为得到的结果。

【讨论】:

认为关于 Linux 的部分是不正确的(因为“Cleartype”是 Microsoft 的东西,而且由于 Linux 实际上不是 完全像 GDI 之一)但是,是的,其余的都是正确的。当我使用pRenderTarget->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE) 时,Direct2D 结果几乎与 GDI 完全一样。 会给你一个赏金,实际上——我认为这是非常值得的。 :) 是的,ClearType 是微软实现的亚像素抗锯齿,所以它不是 Linux 使用的。我已经稍微澄清了文字。并感谢您的赏金! 当然!我现在不能给它,因为它需要一天左右,但我会尽快奖励它!顺便说一句,here are the results 用于将 Direct2D 与 ClearType 结合使用——就清晰度而言,它就像 GDI。 :) @Mehrdad 不完全是。它仍然缺乏一致性 vanilla true,软件呈现 Cleartype。您发布的是硬件渲染,旨在尽可能接近软件 Cleartype。我锐利的眼睛仍然模糊不清。

以上是关于为啥 DirectX/DirectWrite/Direct2D 文本渲染不能像 GDI 一样清晰?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?