返回

用WebGL给物体上色

前端

概述

在上一篇教程中,我们通过使用缓冲区对象来向顶点着色器传送数据,从而绘制了一个三角形。然而,如果我们想给这个三角形上色,我们需要使用着色器。

着色器是可以在GPU上运行的小程序,它们可以用来处理顶点数据,也可以用来处理片段数据(像素数据)。顶点着色器用于处理顶点数据,而片段着色器用于处理片段数据。

顶点着色器

顶点着色器是用来处理顶点数据的着色器,它是第一个被执行的着色器。顶点着色器可以用来执行各种操作,例如:

  • 转换顶点位置
  • 计算顶点的颜色
  • 计算顶点的法线

片段着色器

片段着色器是用来处理片段数据的着色器,它是最后一个被执行的着色器。片段着色器可以用来执行各种操作,例如:

  • 计算片段的颜色
  • 计算片段的透明度
  • 计算片段的纹理坐标

使用着色器给物体上色

为了给物体上色,我们需要使用片段着色器。片段着色器可以用来计算片段的颜色,并将其存储在颜色缓冲区中。颜色缓冲区是一个内存区域,它存储了每个片段的颜色。

当我们调用gl.draw()函数时,GPU就会执行顶点着色器和片段着色器。顶点着色器将顶点数据转换为屏幕坐标,并将其存储在顶点缓冲区中。然后,片段着色器将顶点缓冲区中的顶点数据转换为片段数据,并将其存储在颜色缓冲区中。最后,颜色缓冲区中的数据被显示在屏幕上。

示例

以下是一个使用WebGL给物体上色的示例代码:

<!DOCTYPE html>
<html>
<head>

<script src="webgl.js"></script>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>

<script>
// 获取canvas元素
var canvas = document.getElementById("canvas");

// 创建WebGL上下文
var gl = canvas.getContext("webgl");

// 定义顶点着色器的源代码
var vertexShaderSource = `
attribute vec3 position;
void main() {
  gl_Position = vec4(position, 1.0);
}
`;

// 定义片段着色器的源代码
var fragmentShaderSource = `
void main() {
  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

// 编译顶点着色器
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);

// 编译片段着色器
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);

// 创建着色器程序
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);

// 定义顶点数据
var vertices = [
  -0.5, -0.5, 0.0,
  0.5, -0.5, 0.0,
  0.0, 0.5, 0.0
];

// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();

// 绑定缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

// 缓冲区对象的数据
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

// 获取顶点着色器中的position变量的地址
var positionAttributeLocation = gl.getAttribLocation(program, "position");

// 启用position变量
gl.enableVertexAttribArray(positionAttributeLocation);

// 绑定position变量的地址与缓冲区对象
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);

// 清除颜色缓冲区
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
</body>
</html>

在这个示例中,我们首先定义了顶点着色器的源代码和片段着色器的源代码。然后,我们编译顶点着色器和片段着色器,并将其附加到着色器程序中。接下来,我们定义顶点数据,并将其存储在缓冲区对象中。最后,我们启用position变量,并将其绑定到缓冲区对象。最后,我们清除颜色缓冲区,并绘制三角形。

当我们运行这个示例代码时,我们会看到一个红色的三角形。这个三角形是通过使用片段着色器来给它上色的。