Color masking - Web APIs 编辑
Masking random colors
{{IncludeSubnav("/en-US/Learn")}}This WebGL example modifies random colors by applying color masking to limit the range of displayed colors to specific shades.
This example modifies the random color animation by applying color masking with colorMask()
. You can think of the color masking operation as if looking at the colored canvas through some tinted glass or color filter. So, by masking off the blue and green channels, you are only allowing the red component of pixels to be updated, and therefore it is as if you were looking through a red tinted glass.
Color masking allows us to demonstrate some basics of color theory. By masking off some channel(s), we are in fact biasing the displayed colors towards the complementary color. So, clearly masking both blue and red, would give us shades of green. Masking only the blue channel would give us shades of yellow (including shades of orange, brown, olive and yellow-green), the complementary of blue. Similarly, masking only green would give us shades of magenta (also purples, crimsons, and so on), and masking only red would give shades of cyan (also sea greens, blues, and so on).
Note that the calls to colorMask()
only occur when the user clicks on one of the toggle buttons. But rendering is done every second, using the timer. The color mask state of WebGL is preserved, so we do not need to call colorMask()
every frame to set up the color mask. This is an important aspect of the WebGL state machine. It allows us to setup WebGL in a single initialization phase, and then just execute drawing commands for each frame.
Color masking gives you fine control of updating pixel values on the screen. By limiting the color channels that are written by each drawing command, you can use each channel, for example, to store a different grayscale image. Alternatively, you may use the RGB components for color, but the alpha component for some custom pixel data of your invention.
Finally, color masking teaches us that WebGL is not only a state machine, it is also a graphics pipeline. This means that graphics operations in WebGL are done in a certain order, where the output of each operation serves as the input of the next. So, for example, clearing operation sets the value of each pixel to the chosen clear color. Masking occurs later in the pipeline, and modifies the pixel color value, so the final result on the screen is that of the clear color, tinted by the color mask.
<p>Tinting the displayed colors with color masking.</p>
<canvas>Your browser does not seem to support
HTML5 canvas.</canvas>
<button id="red-toggle">On</button>
<button id="green-toggle">On</button>
<button id="blue-toggle">On</button>
body {
text-align : center;
}
canvas {
display : block;
width : 280px;
height : 210px;
margin : auto;
padding : 0;
border : none;
background-color : black;
}
button {
display : inline-block;
font-family : serif;
font-size : inherit;
font-weight : 900;
color : white;
margin : auto;
padding : 0.6em 1.2em;
}
#red-toggle {
background-color : red;
}
#green-toggle {
background-color : green;
}
#blue-toggle {
background-color : blue;
}
window.addEventListener("load", function setupAnimation (evt) {
"use strict"
window.removeEventListener(evt.type, setupAnimation, false);
var canvas = document.querySelector("canvas");
var gl = canvas.getContext("webgl")
|| canvas.getContext("experimental-webgl");
if (!gl) {
document.querySelector("p").textContent =
"Failed to get WebGL context. Your browser or device may not support WebGL.";
return;
}
gl.viewport(0, 0,
gl.drawingBufferWidth, gl.drawingBufferHeight);
var timer = setInterval(drawAnimation, 1000);
var mask = [true, true, true];
var redtoggle = document.querySelector("#red-toggle"),
greentoggle = document.querySelector("#green-toggle"),
bluetoggle = document.querySelector("#blue-toggle");
redtoggle.addEventListener("click", setColorMask, false);
greentoggle.addEventListener("click", setColorMask, false);
bluetoggle.addEventListener("click", setColorMask, false);
function setColorMask(evt) {
var index =
evt.target === greentoggle && 1
|| evt.target === bluetoggle && 2
|| 0;
mask[index] = !mask[index];
if (mask[index] === true)
evt.target.textContent ="On";
else
evt.target.textContent ="Off";
gl.colorMask(mask[0], mask[1], mask[2], true);
drawAnimation();
};
function drawAnimation () {
var color = getRandomColor();
gl.clearColor(color[0], color[1], color[2], 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
function getRandomColor() {
return [Math.random(), Math.random(), Math.random()];
}
}, false);
The source code of this example is also available on GitHub.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论