1
- Title: WebGL2 and Alpha
2
- Description: How alpha in WebGL is different than alpha in OpenGL
3
- TOC: WebGL2 and Alpha
1
+ Title: WebGL2 和 Alpha
2
+ Description: WebGL 中的 Alpha 与 OpenGL 中的 Alpha 有何不同
3
+ TOC: WebGL2 和 Alpha
4
4
5
+ 我注意到一些 OpenGL 开发者在使用 WebGL 时遇到了关于后缓冲区(即画布)中 alpha 的问题,所以我觉得有必要讲一下 WebGL 和 OpenGL 在 alpha 处理上的一些差异。
5
6
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.
7
+ OpenGL 和 WebGL 最大的区别是,OpenGL 渲染到一个不会被任何东西合成的后缓冲区,或者说操作系统的窗口管理器实际上不会对它进行合成,所以无论 alpha 怎么设置都无所谓。
10
8
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.
9
+ 而 WebGL 是由浏览器与网页内容合成的,默认使用预乘 alpha(premultiplied alpha),这和带透明通道的 PNG ` <img> ` 标签以及 2D canvas 标签的行为相同。
15
10
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.
11
+ WebGL 有几种方式可以使其行为更像 OpenGL。
19
12
20
- WebGL has several ways to make this more like OpenGL.
21
-
22
- ### #1 ) Tell WebGL you want it composited with non-premultiplied alpha
13
+ ### #1 ) 告诉 WebGL 你希望使用非预乘 alpha 合成
23
14
24
15
gl = canvas.getContext("webgl2", {
25
16
premultipliedAlpha: false // Ask for non-premultiplied alpha
26
17
});
27
18
28
- The default is true.
19
+ 默认值是 true。
29
20
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.
21
+ 当然,结果仍会与画布下方的背景颜色合成(画布背景色、画布容器背景色、页面背景色,或者当画布 z-index 大于 0 时背后的内容),
22
+ 换句话说,是网页该区域 CSS 定义的颜色。
35
23
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.
24
+ 判断是否存在 alpha 问题的一个好方法是将画布背景设置为鲜艳颜色,例如红色。你能立刻看到效果:
39
25
40
26
<canvas style="background: red;"><canvas>
41
27
42
- You could also set it to black which will hide any alpha issues you have.
28
+ 你也可以设置成黑色,黑色会掩盖任何 alpha 问题。
43
29
44
- ### #2 ) Tell WebGL you don't want alpha in the backbuffer
30
+ ### #2 ) 告诉 WebGL 你不需要后缓冲区的 alpha
45
31
46
32
gl = canvas.getContext("webgl", { alpha: false }};
47
33
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.
34
+ 这样它的行为更像 OpenGL,因为后缓冲区只会有 RGB。 这可能是最好的选择,因为优秀的浏览器能检测到你不需要 alpha, 从而优化 WebGL 的合成方式。 但这也意味着后缓冲区实际上没有 alpha,如果你确实依赖它可能会不适用。 我所知道的应用中很少使用后缓冲区 alpha。 从某种角度看,我认为这应该是默认行为。
55
35
56
- ### #3 ) Clear alpha at the end of your rendering
36
+ ### #3 ) 在渲染结束时清除 alpha 通道
57
37
58
38
..
59
39
renderScene();
@@ -68,14 +48,10 @@ should have been the default.
68
48
// clear
69
49
gl.clear(gl.COLOR_BUFFER_BIT);
70
50
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.
51
+ 清除操作通常非常快,因为大多数硬件对此有特殊优化。 我在许多早期 WebGL 示例中都这么做过。 如果聪明的话,应该用上面方法 #2 。 也许我发完这条就去改。 大多数 WebGL 库也应该默认采用这种方法。 真正使用 alpha 进行合成效果的开发者可以主动开启。 其余人则能获得最佳性能和最少意外。
52
+
77
53
78
- ### #4 ) Clear the alpha once then don't render to it anymore
54
+ ### #4 ) 清除 Alpha 通道一次,之后不再渲染到该通道
79
55
80
56
// At init time. Clear the back buffer.
81
57
gl.clearColor(1,1,1,1);
@@ -84,49 +60,38 @@ rest will just get the best perf and the least surprises.
84
60
// Turn off rendering to alpha
85
61
gl.colorMask(true, true, true, false);
86
62
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.
63
+ 当然如果你在渲染自定义的帧缓冲区时, 可能需要重新开启 alpha 渲染, 然后切回渲染画布时再关闭。
90
64
91
- ### #5 ) Handling Images
65
+ ### #5 ) 处理带 alpha 的图片
92
66
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.
67
+ 默认情况下,加载带 alpha 的图片到 WebGL,WebGL 会提供文件中的原始颜色值, 且颜色值未做预乘。 这一般符合我对 OpenGL 程序的使用习惯, 因为未预乘是无损的,而预乘会有损失。
97
68
98
69
1, 0.5, 0.5, 0 // RGBA
99
70
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.
71
+ 这是一个可能的未预乘值, 但预乘情况下不可能出现这种值, 因为 alpha = 0,r、g、b 必须都是 0。
103
72
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
73
+ 加载图像时,如果需要,可以让 WebGL 对 Alpha 进行预乘。
74
+ 你可以通过如下方式将 UNPACK_PREMULTIPLY_ALPHA_WEBGL 设置为 true 来实现。
106
75
107
76
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
108
77
109
- The default is un-premultiplied.
78
+ 默认情况下是不进行预乘的。
110
79
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.
80
+ 请注意,大多数(如果不是全部的话)Canvas 2D 实现都使用预乘 alpha。 这意味着当你将它们传输到 WebGL 并且 UNPACK_PREMULTIPLY_ALPHA_WEBGL 设置为 false 时,WebGL 会将它们转换回非预乘状态。
115
81
116
- ### #6 ) Using a blending equation that works with pre-multiplied alpha.
82
+ ### #6 ) 使用与预乘 alpha 兼容的混合方程
117
83
118
- Almost all OpenGL apps I've writing or worked on use
84
+ 我写过或参与过的几乎所有 OpenGL 应用, 默认都是这样设置混合函数。
119
85
120
86
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
121
87
122
- That works for non pre-multiplied alpha textures.
88
+ 这适用于非预乘 alpha 的纹理。
123
89
124
- If you actually want to work with pre-multiplied alpha textures then you
125
- probably want
90
+ 如果你确实想使用预乘 alpha 纹理,那么你可能需要使用以下设置
126
91
127
92
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
128
93
129
- Those are the methods I'm aware of. If you know of more please post them below.
94
+ 这些是我所知道的方法。如果你了解更多,请在下方分享。
130
95
131
96
132
97
0 commit comments