WebGL基础入门
案例教程[https://threelab.cn/openthree/#/codeMirror?navigation=WebGL&classify=base&id=Triangle]
一、WebGL的工作原理
(一)渲染管线概述
WebGL的渲染管线是将3D模型转换为2D图像的过程,这个过程可以分为几个主要阶段:
顶点处理:
- 顶点数据输入:顶点数据(如位置、颜色、纹理坐标等)被输入到顶点着色器。
- 顶点着色器(Vertex Shader):顶点着色器对每个顶点进行处理,可以进行变换(如平移、旋转、缩放)、光照计算等操作。顶点着色器的输出是变换后的顶点位置和一些附加数据(如颜色、纹理坐标等)。
- 图元装配(Primitive Assembly):将顶点组装成图元(如点、线、三角形)。
- 裁剪(Clipping):将超出视口范围的图元裁剪掉。
- 屏幕映射(Screen Mapping):将裁剪后的图元映射到屏幕坐标系中。
光栅化(Rasterization):
- 片元生成:将图元分解为片元(Fragment),每个片元对应屏幕上的一个像素。
- 片元着色器(Fragment Shader):片元着色器对每个片元进行处理,计算最终的像素颜色。可以进行纹理映射、光照计算等操作。
- 深度测试(Depth Testing):确定片元是否被前面的物体遮挡,只有通过深度测试的片元才会被渲染到屏幕上。
- 混合(Blending):将片元的颜色与帧缓冲区(Frame Buffer)中对应像素的颜色进行混合,最终生成屏幕上的像素颜色。
(二)顶点着色器和片元着色器的作用
顶点着色器(Vertex Shader):
- 输入:顶点数据(如位置、颜色、纹理坐标等)。
- 处理:对每个顶点进行变换(如平移、旋转、缩放)、光照计算等操作。
- 输出:变换后的顶点位置和一些附加数据(如颜色、纹理坐标等)。
- 示例代码:glsl
attribute vec4 a_position; // 顶点位置 attribute vec4 a_color; // 顶点颜色 varying vec4 v_color; // 传递给片元着色器的颜色 void main() { gl_Position = a_position; // 设置顶点位置 v_color = a_color; // 传递颜色到片元着色器 }
片元着色器(Fragment Shader):
- 输入:顶点着色器传递过来的数据(如颜色、纹理坐标等)。
- 处理:对每个片元进行处理,计算最终的像素颜色。可以进行纹理映射、光照计算等操作。
- 输出:最终的像素颜色。
- 示例代码:glsl
precision mediump float; // 精度声明 varying vec4 v_color; // 从顶点着色器接收的颜色 void main() { gl_FragColor = v_color; // 设置片元颜色 }
二、WebGL上下文
(一)获取WebGL上下文
要使用WebGL,首先需要获取WebGL上下文。这可以通过HTML中的<canvas>
元素来实现。以下是一个简单的示例代码:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGL Example</title>
</head>
<body>
<canvas id="webglCanvas" width="800" height="600"></canvas>
<script>
// 获取canvas元素
const canvas = document.getElementById('webglCanvas');
// 获取WebGL上下文
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
alert('Your browser does not support WebGL');
} else {
console.log('WebGL context obtained');
}
</script>
</body>
</html>
(二)创建一个简单的WebGL程序
以下是一个完整的示例,展示如何创建一个简单的WebGL程序,绘制一个三角形:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGL Triangle Example</title>
</head>
<body>
<canvas id="webglCanvas" width="800" height="600"></canvas>
<script>
// 获取canvas元素
const canvas = document.getElementById('webglCanvas');
// 获取WebGL上下文
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
alert('Your browser does not support WebGL');
}
// 顶点着色器代码
const vertexShaderSource = `
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
`;
// 片元着色器代码
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 红色
}
`;
// 创建顶点着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
// 创建片元着色器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
// 创建程序
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program));
}
// 使用程序
gl.useProgram(program);
// 定义顶点数据
const positions = [
0.0, 0.5, 0.0, // 顶点1
-0.5, -0.5, 0.0, // 顶点2
0.5, -0.5, 0.0 // 顶点3
];
// 创建缓冲区
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// 绑定顶点属性
const positionLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 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>
三、Canvas元素
(一)在HTML中使用<canvas>
元素
<canvas>
元素是HTML5引入的一个用于绘图的元素,它提供了一个矩形区域,可以在其上进行图形绘制。<canvas>
元素本身并不提供绘图功能,而是通过JavaScript来操作。
html
<canvas id="webglCanvas" width="800" height="600"></canvas>
id
属性:用于通过JavaScript获取该元素。width
和height
属性:定义了<canvas>
的大小。
(二)设置WebGL上下文
通过getContext
方法获取WebGL上下文。getContext
方法的参数可以是'webgl'
或'experimental-webgl'
,后者用于兼容较旧的浏览器。
javascript
const canvas = document.getElementById('webglCanvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
alert('Your browser does not support WebGL');
}
通过这种方式,你可以在<canvas>
元素上创建一个WebGL上下文,然后使用WebGL的API进行3D图形的绘制。
总结
WebGL是一种强大的3D图形技术,通过HTML的<canvas>
元素和JavaScript的API,可以在网页中实现复杂的3D图形渲染。了解WebGL的渲染管线、顶点着色器和片元着色器的作用,以及如何获取WebGL上下文和创建简单的WebGL程序,是学习WebGL的基础。通过这些知识,你可以开始探索更复杂的3D图形应用。