📅  最后修改于: 2023-12-03 14:48:25.831000             🧑  作者: Mango
WebGL是一项用于在Web浏览器中呈现3D图形的技术。 通过利用GPU的强大计算能力和硬件加速功能,WebGL可提供更流畅的3D图形显示。WebGL-旋转是WebGL编程中的一种基本技术,它允许开发者以一定的角度旋转3D场景。
在使用WebGL之前,需要先从canvas元素中获取WebGL上下文对象。该对象提供了与OpenGL ES 2.0 API相似的方法来执行3D图形渲染。
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
在WebGL中,可以通过顶点来描述3D对象的形状和坐标。一些基本形状的顶点已经被定义,如立方体(cube)、球(sphere)等。当然,也可以根据需要自定义顶点。
//定义正方体的顶点坐标
const vertices = [
-1, -1, 1,
1, -1, 1,
1, 1, 1,
-1, 1, 1,
-1, -1, -1,
-1, 1, -1,
1, 1, -1,
1, -1, -1,
-1, 1, -1,
-1, 1, 1,
1, 1, 1,
1, 1, -1,
-1, -1, -1,
1, -1, -1,
1, -1, 1,
-1, -1, 1,
1, -1, -1,
1, 1, -1,
1, 1, 1,
1, -1, 1,
-1, -1, -1,
-1, -1, 1,
-1, 1, 1,
-1, 1, -1,
];
//定义顶点颜色
const colors = [
1, 0, 0, 1,
1, 0, 0, 1,
1, 0, 0, 1,
1, 0, 0, 1,
0, 1, 0, 1,
0, 1, 0, 1,
0, 1, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
0, 0, 1, 1,
0, 0, 1, 1,
0, 0, 1, 1,
1, 1, 0, 1,
1, 1, 0, 1,
1, 1, 0, 1,
1, 1, 0, 1,
0, 1, 1, 1,
0, 1, 1, 1,
0, 1, 1, 1,
0, 1, 1, 1,
1, 0, 1, 1,
1, 0, 1, 1,
1, 0, 1, 1,
1, 0, 1, 1,
];
着色器是WebGL中必不可少的一部分。着色器控制着顶点的绘制方式和颜色等属性。在WebGL中,有两种类型的着色器:顶点着色器和片段着色器。顶点着色器负责处理顶点的位置和颜色等属性,而片段着色器则负责处理像素的颜色。
在WebGL中,可以通过以下方式来定义着色器:
//定义顶点着色器
const vertexShaderSrc = `
attribute vec3 a_position;
attribute vec4 a_color;
varying vec4 v_color;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * vec4(a_position, 1.0);
v_color = a_color;
}
`;
//定义片段着色器
const fragmentShaderSrc = `
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
`;
//编译顶点着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);
//编译片段着色器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);
在WebGL中,程序对象是将顶点着色器和片段着色器连接到一起的最终对象。可以通过以下方式来创建程序对象:
//创建程序对象
const program = gl.createProgram();
//将顶点着色器连接到程序对象
gl.attachShader(program, vertexShader);
//将片段着色器连接到程序对象
gl.attachShader(program, fragmentShader);
//连接着色器程序
gl.linkProgram(program);
WebGL中的缓冲区对象用于存储顶点坐标和颜色等属性。可以通过以下方式来创建并绑定缓冲区对象:
//创建并绑定顶点坐标缓冲区对象
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
//创建并绑定颜色缓冲区对象
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
属性指针是一组指令,它们告诉WebGL如何从缓冲区对象中获取顶点数据。可以通过以下方式来设置属性指针:
//设置顶点着色器中的属性指针
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
//设置顶点着色器中的颜色属性指针
const colorAttributeLocation = gl.getAttribLocation(program, 'a_color');
gl.enableVertexAttribArray(colorAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(colorAttributeLocation, 4, gl.FLOAT, false, 0, 0);
矩阵用于旋转、缩放和位移3D物体。可以使用以下代码创建一个旋转矩阵并设置WebGL中的矩阵:
//创建旋转矩阵
const matrix = mat4.create();
mat4.rotate(matrix, matrix, angleInRadians, [0, 1, 0]);
//将矩阵传递到顶点着色器中
const matrixLocation = gl.getUniformLocation(program, 'u_matrix');
gl.uniformMatrix4fv(matrixLocation, false, matrix);
完成以上步骤后,就可以开始绘制顶点了。可以通过以下代码来完成绘制:
//启用WebGL并绘制顶点
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 36);
下面是一个完整的WebGL-旋转实例:
<html>
<head>
<title>WebGL-旋转</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script>
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl');
const vertices = [
-1, -1, 1,
1, -1, 1,
1, 1, 1,
-1, 1, 1,
-1, -1, -1,
-1, 1, -1,
1, 1, -1,
1, -1, -1,
-1, 1, -1,
-1, 1, 1,
1, 1, 1,
1, 1, -1,
-1, -1, -1,
1, -1, -1,
1, -1, 1,
-1, -1, 1,
1, -1, -1,
1, 1, -1,
1, 1, 1,
1, -1, 1,
-1, -1, -1,
-1, -1, 1,
-1, 1, 1,
-1, 1, -1,
];
const colors = [
1, 0, 0, 1,
1, 0, 0, 1,
1, 0, 0, 1,
1, 0, 0, 1,
0, 1, 0, 1,
0, 1, 0, 1,
0, 1, 0, 1,
0, 1, 0, 1,
0, 0, 1, 1,
0, 0, 1, 1,
0, 0, 1, 1,
0, 0, 1, 1,
1, 1, 0, 1,
1, 1, 0, 1,
1, 1, 0, 1,
1, 1, 0, 1,
0, 1, 1, 1,
0, 1, 1, 1,
0, 1, 1, 1,
0, 1, 1, 1,
1, 0, 1, 1,
1, 0, 1, 1,
1, 0, 1, 1,
1, 0, 1, 1,
];
const vertexShaderSrc = `
attribute vec3 a_position;
attribute vec4 a_color;
varying vec4 v_color;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * vec4(a_position, 1.0);
v_color = a_color;
}
`;
const fragmentShaderSrc = `
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSrc);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSrc);
gl.compileShader(fragmentShader);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
const colorAttributeLocation = gl.getAttribLocation(program, 'a_color');
gl.enableVertexAttribArray(colorAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.vertexAttribPointer(colorAttributeLocation, 4, gl.FLOAT, false, 0, 0);
function drawScene(angleInRadians) {
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
const matrix = mat4.create();
mat4.rotate(matrix, matrix, angleInRadians, [0, 1, 0]);
const matrixLocation = gl.getUniformLocation(program, 'u_matrix');
gl.uniformMatrix4fv(matrixLocation, false, matrix);
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 36);
}
let angle = 0;
function render() {
angle += Math.PI / 100;
drawScene(angle);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
</script>
</body>
</html>
通过以上介绍,我们了解了WebGL-旋转的基本实现方式。WebGL提供了丰富的API,对于需要使用3D图形渲染的应用和网站开发者来说,WebGL是一个十分强大的工具。使用WebGL,可以将更加生动、真实的3D场景呈现在用户面前。