基本剪切

在本示例中,我们将学习如何使用 WebGL 剪切操作绘制矩形和正方形。剪切会建立一个裁剪区域,在此区域之外的绘制将不会发生。

应用剪切时清除绘图缓冲区

这是使用 scissor() 进行渲染的演示。

尽管 clear() 绘图命令会将清除颜色(由 clearColor() 设置)写入绘图缓冲区的所有像素,但 scissor() 定义了一个掩码,只允许指定矩形区域内的像素被更新。

这是一个讨论像素和片段之间区别的好机会。像素是屏幕上的一个图像元素(实际上是一个点),或者绘图缓冲区中的单个元素,即存储您的像素数据(如 RGB 颜色分量)的内存区域。片段是指在 WebGL 管道处理像素时所使用的状态。

之所以要进行这种区分,是因为片段颜色(以及其他片段值,如深度)在最终写入屏幕之前,可能会在图形操作中被多次修改。我们已经通过应用 颜色掩码 了解到片段颜色是如何在图形操作中发生变化的。在其他情况下,片段可能会被完全丢弃(因此像素值不会被更新),或者它可能会与已存在的像素值进行交互(例如,在为场景中非不透明元素进行颜色混合时)。

这里我们看到了片段和像素之间区别的另一个例子。剪切是 WebGL/OpenGL 图形管道中的一个独立阶段(它发生在颜色清除之后,颜色掩码之前)。在实际像素被更新之前,片段必须通过剪切测试。如果片段通过了剪切测试,它们将继续沿着图形管道向下传递,并且屏幕上的相应像素将被更新。如果它们未能通过测试,它们将被立即丢弃,不再进行任何进一步的处理,像素也不会被更新。由于只有指定矩形区域内的片段成功通过了剪切测试,因此只有该区域内的像素会被更新,我们在屏幕上得到一个矩形。

管道的剪切阶段默认是禁用的。我们在这里使用 enable() 方法启用它(您也将使用 enable() 来激活 WebGL 的许多其他功能;因此,在这种情况下,将 SCISSOR_TEST 常量作为参数)。这再次展示了 WebGL 中命令的典型顺序。我们首先调整 WebGL 状态。在这种情况下,启用剪切测试并建立一个矩形掩码。只有在 WebGL 状态得到令人满意的调整后,我们才执行绘图命令(在本例中是 clear()),该命令启动片段沿着图形管道的处理。

html
<p>Result of scissoring.</p>
<canvas>Your browser does not seem to support HTML canvas.</canvas>
css
body {
  text-align: center;
}
canvas {
  display: block;
  width: 280px;
  height: 210px;
  margin: auto;
  padding: 0;
  border: none;
  background-color: black;
}
js
const paragraph = document.querySelector("p");
const canvas = document.querySelector("canvas");

// The following two lines set the size (in CSS pixels) of
// the drawing buffer to be identical to the size of the
// canvas HTML element, as determined by CSS.
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;

const gl = canvas.getContext("webgl");
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);

// Enable scissoring operation and define the position and
// size of the scissoring area.
gl.enable(gl.SCISSOR_TEST);
gl.scissor(40, 20, 60, 130);

// Clear the drawing buffer solid yellow.
gl.clearColor(1.0, 1.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

此示例的源代码也可在 GitHub 上找到。