从零开始:轻松上手WebGL的10个实用案例教程

2026-08-27 0 阅读

引言

WebGL(Web Graphics Library)是一种在网页上实现三维图形的JavaScript API。它允许开发者使用HTML5 Canvas元素在浏览器中创建和显示3D图形。对于想要在网页上展示动态、交互式3D内容的人来说,WebGL是一个非常有用的工具。本教程将为你提供10个实用的WebGL案例教程,帮助你从零开始,轻松上手WebGL。

案例一:绘制基本形状

在WebGL中,首先需要了解如何绘制基本形状,如点、线、三角形等。以下是一个简单的示例,展示如何使用WebGL绘制一个三角形。

// 初始化WebGL上下文
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');

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

// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 设置顶点着色器
var vertexShader = `
    attribute vec3 position;
    void main() {
        gl_Position = vec4(position, 1.0);
    }
`;

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

// 设置片元着色器
var fragmentShader = `
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
`;

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

// 创建程序对象
var program = gl.createProgram();
gl.attachShader(program, vertexShaderObject);
gl.attachShader(program, fragmentShaderObject);
gl.linkProgram(program);
gl.useProgram(program);

// 获取顶点位置变量
var positionLocation = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);

// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);

案例二:绘制立方体

在了解了如何绘制基本形状后,接下来我们将学习如何绘制一个立方体。以下是一个示例,展示如何使用WebGL绘制一个立方体。

// 初始化WebGL上下文
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');

// 定义顶点数据
var vertices = new Float32Array([
    // 前面
    -1.0, -1.0,  1.0,
     1.0, -1.0,  1.0,
     1.0,  1.0,  1.0,
    -1.0,  1.0,  1.0,
    // 后面
    -1.0, -1.0, -1.0,
     1.0, -1.0, -1.0,
     1.0,  1.0, -1.0,
    -1.0,  1.0, -1.0,
    // 左面
    -1.0, -1.0, -1.0,
    -1.0, -1.0,  1.0,
    -1.0,  1.0,  1.0,
    -1.0,  1.0, -1.0,
    // 右面
     1.0, -1.0, -1.0,
     1.0, -1.0,  1.0,
     1.0,  1.0,  1.0,
     1.0,  1.0, -1.0,
    // 上面
    -1.0,  1.0, -1.0,
    -1.0,  1.0,  1.0,
     1.0,  1.0,  1.0,
     1.0,  1.0, -1.0,
    // 下面
    -1.0, -1.0, -1.0,
    -1.0, -1.0,  1.0,
     1.0, -1.0,  1.0,
     1.0, -1.0, -1.0
]);

// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 设置顶点着色器
var vertexShader = `
    attribute vec3 position;
    void main() {
        gl_Position = vec4(position, 1.0);
    }
`;

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

// 设置片元着色器
var fragmentShader = `
    void main() {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
`;

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

// 创建程序对象
var program = gl.createProgram();
gl.attachShader(program, vertexShaderObject);
gl.attachShader(program, fragmentShaderObject);
gl.linkProgram(program);
gl.useProgram(program);

// 获取顶点位置变量
var positionLocation = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);

// 绘制立方体
gl.drawArrays(gl.TRIANGLES, 0, 36);

案例三:绘制球体

球体是三维图形中常见的形状之一。以下是一个示例,展示如何使用WebGL绘制一个球体。

// 初始化WebGL上下文
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');

// 定义顶点数据
var vertices = new Float32Array([
    // 球体顶点数据
]);

// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 设置顶点着色器
var vertexShader = `
    attribute vec3 position;
    void main() {
        gl_Position = vec4(position, 1.0);
    }
`;

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

// 设置片元着色器
var fragmentShader = `
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
`;

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

// 创建程序对象
var program = gl.createProgram();
gl.attachShader(program, vertexShaderObject);
gl.attachShader(program, fragmentShaderObject);
gl.linkProgram(program);
gl.useProgram(program);

// 获取顶点位置变量
var positionLocation = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);

// 绘制球体
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3);

案例四:绘制粒子系统

粒子系统是一种在三维场景中创建大量粒子的技术。以下是一个示例,展示如何使用WebGL绘制一个简单的粒子系统。

// 初始化WebGL上下文
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');

// 定义顶点数据
var vertices = new Float32Array([
    // 粒子顶点数据
]);

// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 设置顶点着色器
var vertexShader = `
    attribute vec3 position;
    void main() {
        gl_Position = vec4(position, 1.0);
    }
`;

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

// 设置片元着色器
var fragmentShader = `
    void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
`;

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

// 创建程序对象
var program = gl.createProgram();
gl.attachShader(program, vertexShaderObject);
gl.attachShader(program, fragmentShaderObject);
gl.linkProgram(program);
gl.useProgram(program);

// 获取顶点位置变量
var positionLocation = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);

// 绘制粒子系统
gl.drawArrays(gl.POINTS, 0, vertices.length / 3);

案例五:绘制光照效果

光照效果是三维图形中非常重要的一部分。以下是一个示例,展示如何使用WebGL绘制一个具有光照效果的立方体。

// 初始化WebGL上下文
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');

// 定义顶点数据
var vertices = new Float32Array([
    // 立方体顶点数据
]);

// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 设置顶点着色器
var vertexShader = `
    attribute vec3 position;
    attribute vec3 normal;
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    uniform vec3 lightPosition;
    void main() {
        vec3 normal = normalize(normalMatrix * normal);
        vec3 lightDir = normalize(lightPosition - position);
        float diff = max(dot(normal, lightDir), 0.0);
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0) * diff;
    }
`;

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

// 设置片元着色器
var fragmentShader = `
    void main() {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    }
`;

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

// 创建程序对象
var program = gl.createProgram();
gl.attachShader(program, vertexShaderObject);
gl.attachShader(program, fragmentShaderObject);
gl.linkProgram(program);
gl.useProgram(program);

// 获取顶点位置变量
var positionLocation = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);

// 获取法线变量
var normalLocation = gl.getAttribLocation(program, 'normal');
gl.vertexAttribPointer(normalLocation, 3, gl.FLOAT, false, 0, 12);
gl.enableVertexAttribArray(normalLocation);

// 设置模型视图矩阵和投影矩阵
var modelViewMatrix = mat4.create();
var projectionMatrix = mat4.create();
mat4.lookAt(modelViewMatrix, [0, 0, 5], [0, 0, 0], [0, 1, 0]);
mat4.perspective(projectionMatrix, glMatrix.toRadian(45), canvas.width / canvas.height, 0.1, 100.0);

// 设置光照位置
var lightPosition = [5.0, 5.0, 5.0, 1.0];

// 绘制立方体
gl.uniformMatrix4fv(gl.getUniformLocation(program, 'modelViewMatrix'), false, modelViewMatrix);
gl.uniformMatrix4fv(gl.getUniformLocation(program, 'projectionMatrix'), false, projectionMatrix);
gl.uniform3fv(gl.getUniformLocation(program, 'lightPosition'), lightPosition);
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3);

案例六:绘制纹理映射

纹理映射是将二维图像映射到三维物体表面的技术。以下是一个示例,展示如何使用WebGL绘制一个具有纹理映射的立方体。

// 初始化WebGL上下文
var canvas = document.getElementById('canvas');
var gl = canvas.getContext('webgl');

// 定义顶点数据
var vertices = new Float32Array([
    // 立方体顶点数据
]);

// 定义纹理坐标数据
var texCoords = new Float32Array([
    // 立方体纹理坐标数据
]);

// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

var texCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW);

// 设置顶点着色器
var vertexShader = `
    attribute vec3 position;
    attribute vec2 texCoord;
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    varying vec2 vTexCoord;
    void main() {
        gl_Position = vec4(position, 1.0);
        vTexCoord = texCoord;
    }
`;

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

// 设置片元着色器
var fragmentShader = `
    varying vec2 vTexCoord;
    uniform sampler2D texture;
    void main() {
        gl_FragColor = texture2D(texture, vTexCoord);
    }
`;

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

// 创建程序对象
var program = gl.createProgram();
gl.attachShader(program, vertexShaderObject);
gl.attachShader(program, fragmentShaderObject);
gl.linkProgram(program);
gl.useProgram(program);

// 获取顶点位置变量
var positionLocation = gl.getAttribLocation(program, 'position');
gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);

// 获取纹理坐标变量
var texCoordLocation = gl.getAttribLocation(program, 'texCoord');
gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(texCoordLocation);

// 加载纹理
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
var image = new Image();
image.src = 'path/to/texture.jpg';
image.onload = function() {
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.bindTexture(gl.TEXTURE_2D, null);
};

// 设置模型视图矩阵和投影矩阵
var modelViewMatrix = mat4.create();
var projectionMatrix = mat4.create();
mat4.lookAt(modelViewMatrix, [0, 0, 5], [0, 0, 0], [0, 1, 0]);
mat4.perspective(projectionMatrix, glMatrix.toRadian(45), canvas.width / canvas.height, 0.1, 100.0);

// 绘制立方体
gl.uniformMatrix4fv(gl.getUniformLocation(program, 'modelViewMatrix'), false, modelViewMatrix);
gl.uniformMatrix4fv(gl.getUniformLocation(program, 'projectionMatrix'), false, projectionMatrix);
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3);

案例七:绘制动画效果

动画效果是三维图形中非常重要的一部分。以下是一个示例,展示如何使用WebGL绘制一个具有动画效果的立方体。

”`javascript // 初始化WebGL上下文 var canvas = document.getElementById(‘canvas’); var gl = canvas.getContext(‘webgl’);

// 定义顶点数据 var vertices = new Float32Array([

// 立方体顶点数据

]);

// 创建缓冲区对象 var vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 设置顶点着色器 var vertexShader = `

attribute vec3 position;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main() {
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

`;

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

// 设置片元着色器 var fragmentShader = `

void main() {
    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}

`;

// 编译片元着色器 var fragmentShaderObject = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader

分享到: