Skip to content

Commit f7fd6c5

Browse files
colin3dmaxgreggman
authored andcommitted
Translate webgl-picking.md to Chinese
1 parent ca36b15 commit f7fd6c5

File tree

2 files changed

+220
-165
lines changed

2 files changed

+220
-165
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
Title: WebGL2 and Alpha
2+
Description: How alpha in WebGL is different than alpha in OpenGL
3+
TOC: WebGL2 and Alpha
4+
5+
6+
I've noticed some OpenGL developers having issues with how WebGL
7+
treats alpha in the backbuffer (ie, the canvas), so I thought it
8+
might be good to go over some of the differences between WebGL
9+
and OpenGL related to alpha.
10+
11+
The biggest difference between OpenGL and WebGL is that OpenGL
12+
renders to a backbuffer that is not composited with anything,
13+
or effectively not composited with anything by the OS's window
14+
manager, so it doesn't matter what your alpha is.
15+
16+
WebGL is composited by the browser with the web page and the
17+
default is to use pre-multiplied alpha the same as .png `<img>`
18+
tags with transparency and 2D canvas tags.
19+
20+
WebGL has several ways to make this more like OpenGL.
21+
22+
### #1) Tell WebGL you want it composited with non-premultiplied alpha
23+
24+
gl = canvas.getContext("webgl2", {
25+
premultipliedAlpha: false // Ask for non-premultiplied alpha
26+
});
27+
28+
The default is true.
29+
30+
Of course the result will still be composited over the page with whatever
31+
background color ends up being under the canvas (the canvas's background
32+
color, the canvas's container background color, the page's background
33+
color, the stuff behind the canvas if the canvas has a z-index > 0, etc....)
34+
in other words, the color CSS defines for that area of the webpage.
35+
36+
A really good way to find if you have any alpha problems is to set the
37+
canvas's background to a bright color like red. You'll immediately see
38+
what is happening.
39+
40+
<canvas style="background: red;"><canvas>
41+
42+
You could also set it to black which will hide any alpha issues you have.
43+
44+
### #2) Tell WebGL you don't want alpha in the backbuffer
45+
46+
gl = canvas.getContext("webgl", { alpha: false }};
47+
48+
This will make it act more like OpenGL since the backbuffer will only have
49+
RGB. This is probably the best option because a good browser could see that
50+
you have no alpha and actually optimize the way WebGL is composited. Of course
51+
that also means it actually won't have alpha in the backbuffer so if you are
52+
using alpha in the backbuffer for some purpose that might not work for you.
53+
Few apps that I know of use alpha in the backbuffer. I think arguably this
54+
should have been the default.
55+
56+
### #3) Clear alpha at the end of your rendering
57+
58+
..
59+
renderScene();
60+
..
61+
// Set the backbuffer's alpha to 1.0 by
62+
// Setting the clear color to 1
63+
gl.clearColor(1, 1, 1, 1);
64+
65+
// Telling WebGL to only affect the alpha channel
66+
gl.colorMask(false, false, false, true);
67+
68+
// clear
69+
gl.clear(gl.COLOR_BUFFER_BIT);
70+
71+
Clearing is generally very fast as there is a special case for it in most
72+
hardware. I did this in many of my first WebGL demos. If I was smart I'd switch to
73+
method #2 above. Maybe I'll do that right after I post this. It seems like
74+
most WebGL libraries should default to this method. Those few developers
75+
that are actually using alpha for compositing effects can ask for it. The
76+
rest will just get the best perf and the least surprises.
77+
78+
### #4) Clear the alpha once then don't render to it anymore
79+
80+
// At init time. Clear the back buffer.
81+
gl.clearColor(1,1,1,1);
82+
gl.clear(gl.COLOR_BUFFER_BIT);
83+
84+
// Turn off rendering to alpha
85+
gl.colorMask(true, true, true, false);
86+
87+
Of course if you are rendering to your own framebuffers you may need to turn
88+
rendering to alpha back on and then turn it off again when you switch to
89+
rendering to the canvas.
90+
91+
### #5) Handling Images
92+
93+
By default if you are loading images with alpha into WebGL, WebGL will
94+
provide the values as they are in the file with color values not
95+
premultiplied. This is generally what I'm used to for OpenGL programs
96+
because it's lossless whereas pre-multiplied is lossy.
97+
98+
1, 0.5, 0.5, 0 // RGBA
99+
100+
Is a possible un-premultiplied value whereas pre-multiplied it's an
101+
impossible value because `a = 0` which means `r`, `g`, and `b` have
102+
to be zero.
103+
104+
When loading an image you can have WebGL pre-multiply the alpha if you want.
105+
You do this by setting `UNPACK_PREMULTIPLY_ALPHA_WEBGL` to true like this
106+
107+
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
108+
109+
The default is un-premultiplied.
110+
111+
Be aware that most if not all Canvas 2D implementations work with
112+
pre-multiplied alpha. That means when you transfer them to WebGL and
113+
`UNPACK_PREMULTIPLY_ALPHA_WEBGL` is false WebGL will convert them
114+
back to un-premultipiled.
115+
116+
### #6) Using a blending equation that works with pre-multiplied alpha.
117+
118+
Almost all OpenGL apps I've writing or worked on use
119+
120+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
121+
122+
That works for non pre-multiplied alpha textures.
123+
124+
If you actually want to work with pre-multiplied alpha textures then you
125+
probably want
126+
127+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
128+
129+
Those are the methods I'm aware of. If you know of more please post them below.
130+
131+
132+

0 commit comments

Comments
 (0)