【问题标题】:How to make WebGL canvas transparent如何使 WebGL 画布透明
【发布时间】:2012-09-05 02:47:04
【问题描述】:

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

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

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

opacity: 0.5;

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

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

感谢您的帮助!

【问题讨论】:

    标签: css canvas transparency webgl alpha


    【解决方案1】:

    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 为您提供了两种选择。

    【讨论】:

    • 感谢您的解释,它帮助我更加了解了 WebGL 的基础知识。
    • 您所说的“HTML5 的所有其他部分都期望预多重化 alpha 以使 WebGL 为您提供两种选择”是什么意思?在我看来,当我们将 premultipliedAlpha 设置为 false 时,我们会得到与 CSS 不透明度相同的不透明度,这似乎与您在那里所说的相反。我在想“HTML5 的所有其他部分”是指使用 CSS 不透明度的所有内容,在这种情况下,我记得我们以非预乘格式使用 rgba()。例如,在 CSS 中,rgba(1,1,1,0) 无论 RGB 值如何(非预乘)都是 100% 透明的。
    • HTML 的所有其他部分是指普通图像、2d 画布、视频。 CSS 不是 HTML :)
    【解决方案2】:

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

    如果你想绘制半透明的对象,那就是混合操作和排序绘制,但看起来你只是想让未绘制的区域透明,上面的就足够了。

    【讨论】:

      猜你喜欢
      • 2014-10-06
      • 1970-01-01
      • 2017-04-12
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 2019-03-31
      • 2019-07-05
      相关资源
      最近更新 更多