19

是否可以使用具有透明背景的WebGL 画布?我想通过画布看到网页的内容。

这就是我现在所拥有的:http: //i50.tinypic.com/2vvq7h2.png

如您所见,WebGL 画布后面的文本是不可见的。当我在 CSS 中更改 Canvas 元素的样式并添加

opacity: 0.5;

该页面将如下所示:http: //i47.tinypic.com/302ys9c.png

这几乎是我想要的,但不完全是 - 由于 CSS alpha 设置导致的文本颜色当然不是黑色,蓝色形状的颜色与第一张图片中的蓝色不同。

谢谢你的帮助!

4

2 回答 2

22

WebGL 默认是透明的。这是一个示例

const gl = document.getElementById("c").getContext("webgl");
gl.clearColor(0.5, 0, 0, 0.5);
gl.clear(gl.COLOR_BUFFER_BIT);
pre {
    padding-left: 50px;
    font-family: sans-serif;
    font-size: 20px;
    font-weight: bold;
}

canvas {
    z-index: 2;
    position: absolute;
    top: 0px;
    border: 1px solid black;
}
<pre>
Some 
text
under
the
canvas
</pre>
<canvas id="c"></canvas>

请注意,浏览器假定画布中的像素代表 PRE-MULTIPLIED-ALPHA 值。这意味着例如,如果您将清除颜色更改为 (1, 0, 0, 0.5),您将获得在 HTML 中其他任何地方都看不到的东西。

我的意思是预乘 alpha 意味着 RGB 部分已经乘以 alpha 值。因此,如果您为 RGB 开始 1,0,0 并且您的 alpha 为 0.5。然后,如果将 RGB 乘以 alpha,RGB 将得到 0.5、0、0。这就是浏览器默认的期望。

如果 WebGL 中的像素是 1,0,0,0.5,这对浏览器来说毫无意义,你会得到奇怪的效果。

参见例如

const gl = document.getElementById("c").getContext("webgl");
gl.clearColor(1, 0, 0, 0.5);
gl.clear(gl.COLOR_BUFFER_BIT);
pre {
    padding-left: 50px;
    font-family: sans-serif;
    font-size: 20px;
    font-weight: bold;
}

canvas {
    z-index: 2;
    position: absolute;
    top: 0px;
    border: 1px solid black;
}
<pre>
Some 
text
under
the
canvas
</pre>
<canvas id="c"></canvas>

请注意黑色文本已变为红色,即使您认为 0.5 的 alpha = 黑色文本的 50% 和红色 WebGL 画布的 50%。那是因为红色没有被预乘。

您可以通过确保在 WebGL 中创建的值表示预乘值来解决此问题。或者您可以告诉浏览器您的 WebGL 像素在创建 webgl 上下文时未预乘

const gl = canvas.getContext("webgl", { premultipliedAlpha: false });

现在 1,0,0,0.5 像素再次起作用。例子:

const gl = document.getElementById("c").getContext("webgl", {
  premultipliedAlpha: false,
});
gl.clearColor(1, 0, 0, 0.5);
gl.clear(gl.COLOR_BUFFER_BIT);
pre {
    padding-left: 50px;
    font-family: sans-serif;
    font-size: 20px;
    font-weight: bold;
}

canvas {
    z-index: 2;
    position: absolute;
    top: 0px;
    border: 1px solid black;
}
<pre>
Some 
text
under
the
canvas
</pre>
<canvas id="c"></canvas>

采用哪种方式取决于您的应用程序。许多 GL 程序需要非预乘 alpha,而 HTML5 的所有其他部分都需要预乘 alpha,因此 WebGL 为您提供了两种选择。

于 2012-09-05T22:14:43.080 回答
16

WebGL 默认支持 alpha 透明度,但您必须使用它。gl.clearColor(0, 0, 0, 0)最重要的是,在您gl.clear操作之前,请确保您已将透明颜色设置为透明。

如果要绘制半透明对象,则需要进行混合操作和排序绘制,但看起来您只希望未绘制区域是透明的,以上就足够了。

于 2012-09-05T16:56:51.180 回答