背景
使用 gluTess 从 GDI+ DrawString(..) 路径在 Direct3D9 中构建三角形列表:
然后使用像素着色器 (v3.0) 填充形状。使用不透明值进行绘制时,一切看起来都很好:
问题
在某些字体大小下,如果颜色具有 alpha 分量(即 Argb #55FFFFFF),我们开始看到这些令人讨厌的曲面细分伪影,其中三角形可能会略微重叠:
在较大的字体大小时,有时不存在问题:
使用 Intel 优秀的 GPA Frame Analyzer Pixel History 工具,我们可以看到在出现伪影的区域,像素已经从单个 Erg 中“触摸”了 3 次。
我试图弄清楚如何阻止我的像素着色器多次触摸同一个像素。
其他与防止过度绘制相关的解决方案似乎都是关于 zbuffer 策略的,但是这个问题更多地与在单个像素着色器通道中绘制单个 2D 三角形列表有关。
我在试图想出一个解决方案时有点不知所措。我希望 HLSL 可能有某种“每个像素只触摸一次”标志,但我一直找不到类似的东西。我发现最接近的是将 BLENDOP 设置为 MAX 而不是 ADD。但是当混合场景中的其他颜色时,输出不正确。
我也有 SRCBLEND = ONE,DSTBLEND = INVSRCALPHA。产生正确输出的唯一标志组合(尽管有过度绘制的工件。)
我在 GPA 帧分析器中使用过 SEPARATEALPHABLENDENABLE,这听起来几乎正是我在这里需要的——将混合设置为 MAX,但仅在“alpha”通道上,但据我所知,该设置(和相应的 BLENDOPALPHA)会影响什么都没有。
我想到的最后一件事是将不透明的文本烘焙到纹理上,然后使用适当的 alpha 值将该纹理重新绘制到场景中,但这实际上在这个项目中不起作用,因为我还支持渐变画笔,在哪里停止值可能包含 alpha,这意味着如果我们在烘焙到纹理之前将 alpha 从停止值中剥离出来,则仍然可以看到伪影,或者最终输出完全错误。此外,整个努力将非常昂贵。
任何提示或指针将不胜感激。谢谢阅读。