如何使用着色器制作混合边

时间:2013-10-02 15:02:01

标签: webgl shader

让我来介绍一下我的答案。

这是用 webgl 呈现的三角形。嗯,它有点放大...... enter image description here

这是我要拥有的三角形:enter image description here

所以我正在寻找一些着色器,它将能够混合原始三角形的边缘。我知道如何实现一个,但我可能还不够好写它。

我的想法是这样的: 基于3个顶点的位置计算每个片段,原始覆盖像素多少,然后根据计算的信息设置该像素的透明度...

我可以从顶点着色器获取2D坐标并在片段着色器中使用它们。现在我可能想要使用gl_FragCoord.xygl_PointCoord.xy并计算%像素覆盖率,但我无法比较这些值(似乎单位不同,我用毫米计算里程并且'点零'在这些向量的其他地方),所以我无法计算最终的透明度值。

有人能帮帮我吗?请转向我正确的方式。

2 个答案:

答案 0 :(得分:1)

有很多方法可以实现这个目标

您可以以更高的分辨率渲染。使您的画布大于其显示的大小,浏览器几乎肯定会双线性插值结果。例如:

<canvas width="400" height="400" style="width: 200px; height 200px" />

声明一个400x400 backstore的画布,显示时缩放到200x200。

Here's a fiddle

另一种技术是在着色器中计算alpha值,以便沿多边形边缘获得所需的混合。

我确定还有其他人。大多数Canvas2D实现都是gpu加速和消除锯齿,即使GPU不支持抗锯齿,所以you could try digging through one of those

答案 1 :(得分:0)

你的计划的问题是OpenGL应用它自己的测试来决定首先绘制哪些像素 - 如果片段的中心位于几何边界内,那么它是光栅化的,如果它位于外面那么它不是,如果它恰好位于边界上,然后光栅化取决于它是在水平或垂直运行的开始还是结束。边界条件确保两个三角形完全相交的地方,它们都不会包含相同的碎片。

因此,如果你计算每个片段的覆盖率,你几乎不会得到一个小于50%的数字(角落和其他非常薄的几何体是例外)。你不会得到你想要的完全抗锯齿。您将获得由别名版本修剪的抗锯齿版本。

硬件通过对每个输出像素采样多个片段来实现此目的。您可以通过以输出大小的倍数渲染纹理来模拟,然后缩小。 mip贴图生成将过滤输入图像。

总而言之,您是否曾尝试在调用antialias时将true作为canvas.GetContext传递?这将使用硬件功能,具体取决于硬件和浏览器支持。