Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make WebGL canvas transparent

Is it possible to have WebGL canvas with transparent background? I want to have contents of web page visible through the canvas.

This is what I have now: http://i50.tinypic.com/2vvq7h2.png

As you can see, the text behind the WebGL canvas is not visible. When I change style of Canvas element in CSS and add

opacity: 0.5;

The page will look like this: http://i47.tinypic.com/302ys9c.png

Which is almost what I want, but not entirely - the color of text due to the CSS alpha setting is of course not the same black and color of blue shape is not the same blue as in the first picture.

Thanks for any help!

like image 919
Jack Sean Avatar asked Sep 05 '12 02:09

Jack Sean


People also ask

How do I make a transparent canvas?

The globalAlpha property returns the transparency value of drawing. The value 1.0 of this property specifies no transparency and the value 0.0 of this property specifies full transparency. Hence, by setting the globalAlpha property to 0.0, we can get a transparent canvas.

Can a canvas element be transparent?

Canvases are transparent by default. Try setting a page background image, and then put a canvas over it. If nothing is drawn on the canvas, you can fully see the page background.

How do I make a HTML page transparent?

You can easily make a transparent web page using the opacity property in HTML. You simply need to adjust the opacity value between 0.0 to 1.0 where a low value represents high transparency and a high value represents low transparency.

How do I use WebGL in canvas?

WebGL Context HTML5 Canvas is also used to write WebGL applications. To create a WebGL rendering context on the canvas element, you should pass the string experimental-webgl, instead of 2d to the canvas. getContext() method. Some browsers support only 'webgl'.


2 Answers

WebGL defaults to being transparent. Here's a sample

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>

Note that the browser assumes the pixels in the canvas represent PRE-MULTIPLIED-ALPHA values. That means for example if you changed the clear color to (1, 0, 0, 0.5) you'd get something you don't see anywhere else in HTML.

What I mean by that is Pre-multiplied alpha means the RGB parts are such that they've already been multiplied by the alpha value. So if you started 1,0,0 for RGB and your alpha is 0.5. Then if you multiply the RGB by alpha you'd get 0.5, 0, 0 for the RGB. That's what the browser expects by default.

If the pixels in WebGL are 1,0,0,0.5 that makes no sense to the browser and you'll get strange effects.

See for example

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>

Notice the black text has become red even though you'd think an alpha of 0.5 = 50% of the black text and 50% of the red WebGL canvas. That's because the red has not been pre-multiplied.

You can solve this by making sure the values you create in WebGL represent pre-multiplied values., or you can tell the browser that your WebGL pixels are not pre-multiplied when you create the webgl context with

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

Now the 1,0,0,0.5 pixels work again. Example:

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>

Which way you do this is up to your application. Many GL programs expect non-premultiplied alpha where as all other parts of HTML5 expect premultlipled alpha so WebGL gives you both options.

like image 133
gman Avatar answered Sep 24 '22 02:09

gman


WebGL supports alpha transparency by default, but you have to use it. Most basically, make sure you have set the clear color to transparent, gl.clearColor(0, 0, 0, 0), before your gl.clear operation.

If you want to have semi-transparent objects drawn, that gets into blending operations and sorted drawing, but it looks like you just want the un-drawn area to be transparent, which the above is sufficient for.

like image 36
Kevin Reid Avatar answered Sep 24 '22 02:09

Kevin Reid