canvas:理解canvas / 基础使用 / 实用demo-CSDN博客
WebGL:开始学习 / 理解 WebGL / WebGL 需要掌握哪些知识 / 应用领域 / 前端值得学WebGL吗_webgl培训-CSDN博客
用来运行WebGL代码,粘贴--运行(有时候不太好用,莫名报错)
- //获取画布元素
- var canvas = document.getElementById('canvas')
- //获取到元素的上下文环境对象
- var webgl = canvas.getContext('webgl')
demo来至AI
在这个 Demo 中,我们首先获取了 WebGL 上下文,然后定义了一个顶点着色器和一个片元着色器。接着,我们创建了着色器程序对象,并将顶点着色器和片元着色器附加到这个程序对象上,并进行链接。
然后,我们创建了一个顶点缓冲区,并将顶点坐标存储在这个缓冲区中。我们启用了顶点属性,并将顶点缓冲区对象绑定到这个属性上。
接下来,我们设置了视口大小,并清空了画布。最后,我们使用 gl.drawArrays() 方法绘制了一个正方形。
需要注意的是,绘制图形时,我们使用的是 gl.TRIANGLE_FAN,它表示绘制一个三角形扇形,也就是一个由五个三角形组成的正方形。这样可以减少绘制的顶点数量,提高性能。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>WebGL 基础 Demo</title>
- <style>
- canvas {
- border: 1px solid black;
- }
- </style>
- </head>
- <body>
- <canvas id="canvas" width="500" height="500"></canvas>
-
- <script>
- // 获取 WebGL 上下文
- const canvas = document.getElementById('canvas');
- const gl = canvas.getContext('webgl');
-
- // 定义顶点着色器代码
- const vertexShaderCode = `
- attribute vec3 a_position;
-
- void main() {
- gl_Position = vec4(a_position, 1.0);
- }
- `;
-
- // 定义片元着色器代码
- const fragmentShaderCode = `
- 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, vertexShaderCode);
- gl.compileShader(vertexShader);
-
- // 创建片元着色器对象
- const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragmentShader, fragmentShaderCode);
- gl.compileShader(fragmentShader);
-
- // 创建着色器程序对象
- const shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- // 获取着色器变量位置
- const positionLocation = gl.getAttribLocation(shaderProgram, 'a_position');
-
- // 创建顶点数据
- const vertices = [
- -0.5, -0.5, 0.0,
- 0.5, -0.5, 0.0,
- 0.5, 0.5, 0.0,
- -0.5, 0.5, 0.0
- ];
-
- // 创建顶点缓冲区对象
- const vertexBuffer = gl.createBuffer();
-
- // 绑定缓冲区对象
- gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
-
- // 将数据写入缓冲区对象
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
-
- // 启用顶点属性
- gl.enableVertexAttribArray(positionLocation);
-
- // 将缓冲区对象绑定到顶点属性上
- gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
-
- // 设置视口
- gl.viewport(0, 0, canvas.width, canvas.height);
-
- // 清空画布
- gl.clearColor(0.0, 0.0, 0.0, 1.0);
- gl.clear(gl.COLOR_BUFFER_BIT);
-
- // 使用着色器
- gl.useProgram(shaderProgram);
-
- // 绘制图形
- gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
- </script>
- </body>
- </html>

这个 Demo 创建了一个空的 WebGL 上下文并在 canvas 上进行了清屏操作。可以通过更改 clearColor() 的参数来修改屏幕上的颜色。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>WebGL Demo</title>
- <style>
- html, body {
- margin: 0;
- padding: 0;
- height: 100%;
- overflow: hidden;
- }
-
- canvas {
- width: 100%;
- height: 100%;
- }
- </style>
- </head>
- <body>
- <canvas id="canvas"></canvas>
-
- <script>
- const canvas = document.getElementById('canvas');
- const gl = canvas.getContext('webgl');
-
- gl.clearColor(0.0, 0.0, 0.0, 1.0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- </script>
- </body>
- </html>

- 它包括以下步骤:
- 获取 canvas 元素和 WebGL 上下文对象。
- 定义顶点着色器和片段着色器。
- 创建顶点着色器和片段着色器对象。
- 创建着色器程序对象。
- 定义三角形顶点坐标并写入缓冲区。
- 获取顶点着色器中 aPosition 的地址并启用。
- 清除画布并绘制三角形。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>WebGL Demo</title>
- </head>
- <body>
- <canvas id="glCanvas" width="640" height="480"></canvas>
-
- <script>
- function init() {
- // 获取 canvas 元素
- var canvas = document.getElementById("glCanvas");
-
- // 获取 WebGL 上下文
- var gl = canvas.getContext("webgl");
-
- // 定义顶点着色器
- var vertexShaderSource = `
- attribute vec3 aPosition;
-
- void main() {
- gl_Position = vec4(aPosition, 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.0, 0.5, 0.0,
- -0.5, -0.5, 0.0,
- 0.5, -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);
-
- // 获取顶点着色器中 aPosition 的地址
- var aPosition = gl.getAttribLocation(program, "aPosition");
- gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(aPosition);
-
- // 清除画布并绘制三角形
- gl.clearColor(0.0, 0.0, 0.0, 1.0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- gl.drawArrays(gl.TRIANGLES, 0, 3);
- }
-
- init();
- </script>
- </body>
- </html>

WebGL 绘制了一个红色的三角形,该三角形的顶点坐标分别为 (0.0, 0.5)、(-0.5, -0.5) 和 (0.5, -0.5)。在绘制过程中,我们首先编译和链接了顶点着色器和片元着色器,并创建了一个着色器程序。然后我们创建了一个顶点缓冲,并将顶点数据绑定到该缓冲上。接下来我们通过顶点属性将顶点数据传递给顶点着色器,在片元着色器中设置了颜色,并通过调用 gl.drawArrays(gl.TRIANGLES, 0, 3) 绘制了该三角形。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>WebGL Demo</title>
- <style>
- canvas {
- border: 1px solid black;
- }
- </style>
- </head>
- <body>
- <canvas id="my-canvas" width="500" height="500"></canvas>
- <script>
- const canvas = document.getElementById('my-canvas');
- const gl = canvas.getContext('webgl');
-
- // 定义顶点着色器
- const vertexShader = gl.createShader(gl.VERTEX_SHADER);
- gl.shaderSource(vertexShader, `
- attribute vec4 a_position;
- void main() {
- gl_Position = a_position;
- }
- `);
- gl.compileShader(vertexShader);
-
- // 定义片元着色器
- const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragmentShader, `
- precision mediump float;
- uniform vec4 u_color;
- void main() {
- gl_FragColor = u_color;
- }
- `);
- gl.compileShader(fragmentShader);
-
- // 创建着色器程序
- const program = gl.createProgram();
- gl.attachShader(program, vertexShader);
- gl.attachShader(program, fragmentShader);
- gl.linkProgram(program);
- gl.useProgram(program);
-
- // 定义顶点数据
- const vertices = [
- 0.0, 0.5,
- -0.5, -0.5,
- 0.5, -0.5,
- ];
-
- // 创建顶点缓冲
- const buffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
-
- // 绑定顶点属性
- const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
- gl.enableVertexAttribArray(positionAttributeLocation);
- gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
-
- // 设置颜色
- const colorUniformLocation = gl.getUniformLocation(program, 'u_color');
- gl.uniform4f(colorUniformLocation, 1.0, 0.0, 0.0, 1.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>

在这个 Demo 中,我们首先创建了一个 WebGL 上下文,并定义了一个顶点着色器和一个片元着色器。接着,我们创建了一个着色器程序对象,并将顶点着色器和片元着色器附加到这个程序对象上,并进行链接。
然后,我们创建了一个顶点缓冲区,并将顶点坐标存储在这个缓冲区中。我们还设置了视图和投影矩阵,并使用着色器程序。接下来,我们启用了顶点属性,并将顶点缓冲区绑定到这个属性上。最后,我们使用 gl.drawArrays() 方法绘制了一个矩形。
在片元着色器中,我们使用了 mix() 函数来计算每个像素的颜色,从而实现了颜色渐变效果。我们还定义了两个 uniform 变量 u_colorA 和 u_colorB,用于控制矩形的颜色。
在这个 Demo 中,我们只是绘制了一个简单的颜色渐变矩形,但你可以根据需要对其进行修改和扩展。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <title>WebGL Demo</title>
- <script type="text/javascript">
- window.onload = function() {
- const canvas = document.getElementById("canvas");
- const gl = canvas.getContext("webgl");
-
- // 顶点着色器代码
- const vertexShaderSource = `
- attribute vec2 a_position;
-
- void main() {
- gl_Position = vec4(a_position, 0.0, 1.0);
- }
- `;
-
- // 片元着色器代码
- const fragmentShaderSource = `
- precision mediump float;
-
- uniform vec4 u_colorA;
- uniform vec4 u_colorB;
-
- void main() {
- gl_FragColor = mix(u_colorA, u_colorB, gl_FragCoord.y / 500.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);
-
- // 获取顶点着色器中的变量位置
- const positionLocation = gl.getAttribLocation(program, "a_position");
-
- // 创建顶点缓冲区
- const positionBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- const positions = [
- 0, 0,
- 0, 500,
- 500, 0,
- 500, 500,
- ];
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
-
- // 设置视图和投影矩阵
- gl.viewport(0, 0, canvas.width, canvas.height);
- gl.clearColor(0, 0, 0, 1);
- gl.clear(gl.COLOR_BUFFER_BIT);
-
- // 使用着色器程序
- gl.useProgram(program);
-
- // 启用顶点属性
- gl.enableVertexAttribArray(positionLocation);
-
- // 将顶点缓冲区绑定到顶点属性
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
-
- // 设置 uniform 变量
- const colorALocation = gl.getUniformLocation(program, 'u_colorA');
- const colorBLocation = gl.getUniformLocation(program, 'u_colorB');
- gl.uniform4f(colorALocation, 1, 0, 0, 1);
- gl.uniform4f(colorBLocation, 0, 0, 1, 1);
-
- // 绘制矩形
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- };
- </script>
- <style>
- canvas {
- border: 1px solid black;
- }
- </style>
- </head>
- <body>
- <canvas id="canvas" width="500" height="500"></canvas>
- </body>
- </html>

- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <title>WebGL Demo</title>
- <style>
- body {
- margin: 0;
- padding: 0;
- }
-
- #glcanvas {
- width: 100vw;
- height: 100vh;
- display: block;
- }
- </style>
- </head>
- <body>
- <canvas id="glcanvas"></canvas>
- <script>
- const canvas = document.querySelector("#glcanvas");
- const gl = canvas.getContext("webgl");
-
- const vertexShaderSource = `
- attribute vec3 aPosition;
- attribute vec3 aColor;
- varying vec3 vColor;
- void main() {
- gl_Position = vec4(aPosition, 1.0);
- vColor = aColor;
- }
- `;
-
- const fragmentShaderSource = `
- precision mediump float;
- varying vec3 vColor;
- void main() {
- gl_FragColor = vec4(vColor, 1.0);
- }
- `;
-
- const shaderProgram = createShaderProgram(gl, vertexShaderSource, fragmentShaderSource);
-
- const positionAttributeLocation = gl.getAttribLocation(shaderProgram, "aPosition");
- const colorAttributeLocation = gl.getAttribLocation(shaderProgram, "aColor");
-
- const positionBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- const positions = [-0.5, 0.5, 0.0, 0.5, 0.5, 0.0, 0.0, -0.5, 0.0];
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
-
- const colorBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
- const colors = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
-
- function createShaderProgram(gl, vertexShaderSource, fragmentShaderSource) {
- const vertexShader = gl.createShader(gl.VERTEX_SHADER);
- gl.shaderSource(vertexShader, vertexShaderSource);
- gl.compileShader(vertexShader);
- if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
- console.log("Error compiling vertex shader:", gl.getShaderInfoLog(vertexShader));
- return null;
- }
-
- const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragmentShader, fragmentShaderSource);
- gl.compileShader(fragmentShader);
- if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
- console.log("Error compiling fragment shader:", gl.getShaderInfoLog(fragmentShader));
- return null;
- }
-
- const shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- console.log("Error linking shader program:", gl.getProgramInfoLog(shaderProgram));
- return null;
- }
-
- return shaderProgram;
- }
-
- function render() {
- gl.clearColor(0.0, 0.0, 0.0, 1.0);
- gl.clear(gl.COLOR_BUFFER_BIT);
-
- gl.useProgram(shaderProgram);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- gl.enableVertexAttribArray(positionAttributeLocation);
- gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
- gl.enableVertexAttribArray(colorAttributeLocation);
- gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
-
- gl.drawArrays(gl.TRIANGLES, 0, 3);
- }
-
- requestAnimationFrame(render);
- </script>
- </body>
- </html>

本例的代码中,我们使用 THREE.js 库创建了一个场景,相机和渲染器。我们还创建了一个立方体,并将其添加到场景中。最后,我们创建了一个动画函数,使立方体绕 X 和 Y 轴旋转,并在每个帧中更新渲染器。
运行上面的代码,您将在浏览器中看到一个绿色的立方体,它在不断旋转。
- <!DOCTYPE html>
- <html>
- <head>
- <title>WebGL Demo</title>
- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
- <style>
- body { margin: 0; }
- canvas { width: 100%; height: 100%; display: block; }
- </style>
- </head>
- <body>
- <script>
- // 初始化场景
- var scene = new THREE.Scene();
-
- // 初始化相机
- var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
- camera.position.z = 5;
-
- // 初始化渲染器
- var renderer = new THREE.WebGLRenderer();
- renderer.setSize(window.innerWidth, window.innerHeight);
- document.body.appendChild(renderer.domElement);
-
- // 创建立方体
- var geometry = new THREE.BoxGeometry();
- var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
- var cube = new THREE.Mesh(geometry, material);
- scene.add(cube);
-
- // 创建动画
- function animate() {
- requestAnimationFrame(animate);
- cube.rotation.x += 0.01;
- cube.rotation.y += 0.01;
- renderer.render(scene, camera);
- }
-
- animate();
- </script>
- </body>
- </html>

- 获取 WebGL 上下文;
- 编写顶点着色器和片元着色器代码;
- 初始化着色器程序和获取 attribute 变量和 uniform 变量的位置;
- 准备顶点数据和颜色数据,并创建对应的缓冲区;
- 设置绘制参数,包括启用 attribute 位置、绑定缓冲区和设置指针;
- 设置投影矩阵和模型视图矩阵,并绘制三角形。
- <!DOCTYPE html>
- <html>
- <head>
- <title>WebGL Demo</title>
- <script src="https://cdn.bootcdn.net/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
- </head>
- <body>
- <canvas id="canvas" width="800" height="600"></canvas>
- <script>
- const canvas = document.getElementById('canvas');
- const gl = canvas.getContext('webgl');
-
- if (!gl) {
- alert('WebGL not supported.');
- }
-
- // 顶点着色器代码
- const vsSource = `
- attribute vec4 aVertexPosition;
- attribute vec4 aVertexColor;
- uniform mat4 uModelViewMatrix;
- uniform mat4 uProjectionMatrix;
- varying lowp vec4 vColor;
-
- void main() {
- gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
- vColor = aVertexColor;
- }
- `;
-
- // 片元着色器代码
- const fsSource = `
- varying lowp vec4 vColor;
-
- void main() {
- gl_FragColor = vColor;
- }
- `;
-
- // 初始化着色器程序
- const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
-
- // 获取 attribute 变量和 uniform 变量的位置
- const programInfo = {
- program: shaderProgram,
- attribLocations: {
- vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
- vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'),
- },
- uniformLocations: {
- projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
- modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
- },
- };
-
- // 设置顶点数据
- const positions = [
- 0, 0.5, 0,
- -0.5, -0.5, 0,
- 0.5, -0.5, 0,
- ];
- const colors = [
- 1, 0, 0, 1,
- 0, 1, 0, 1,
- 0, 0, 1, 1,
- ];
-
- // 创建顶点缓冲区
- const positionBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
-
- const colorBuffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
-
- // 设置绘制参数
- gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);
- gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- gl.vertexAttribPointer(programInfo.attribLocations.vertexPosition, 3, gl.FLOAT, false, 0, 0);
-
- gl.enableVertexAttribArray(programInfo.attribLocations.vertexColor);
- gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
- gl.vertexAttribPointer(programInfo.attribLocations.vertexColor, 4, gl.FLOAT, false, 0, 0);
-
- gl.useProgram(programInfo.program);
-
- // 设置投影矩阵和模型视图矩阵
- const projectionMatrix = mat4.create();
- mat4.perspective(projectionMatrix, 45 * Math.PI / 180, canvas.width / canvas.height, 0.1, 100.0);
-
- const modelViewMatrix = mat4.create();
- mat4.translate(modelViewMatrix, modelViewMatrix, [-0.0, 0.0, -3.0]);
-
- // 绘制
- gl.uniformMatrix4fv(programInfo.uniformLocations.projectionMatrix, false, projectionMatrix);
- gl.uniformMatrix4fv(programInfo.uniformLocations.modelViewMatrix, false, modelViewMatrix);
-
- gl.drawArrays(gl.TRIANGLES, 0, 3);
-
- // 初始化着色器程序函数
- function initShaderProgram(gl, vsSource, fsSource) {
- const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
- const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
-
- const shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
- return null;
- }
-
- return shaderProgram;
- }
-
- // 加载着色器函数
- function loadShader(gl, type, source) {
- const shader = gl.createShader(type);
-
- gl.shaderSource(shader, source);
- gl.compileShader(shader);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
- gl.deleteShader(shader);
- return null;
- }
-
- return shader;
- }
- </script>
- </body>
- </html>

- 获取 canvas 元素和绘图上下文
- 定义 顶点着色器 和 片元着色器,顶点着色器用于处理顶点数据,片元着色器用于处理每个像素的颜色值
- 创建 顶点着色器 和 片元着色器,并编译
- 创建 程序对象,并将 顶点着色器 和 片元着色器 附加到程序对象上
- 链接程序对象,并使用
- 定义圆形顶点数据(分割成 n 个三角形)
- 创建缓冲对象并绑定到目标上
- 向缓冲对象写入数据
- 获取 属性变量 位置
- 设置 属性变量,并启用
- 获取 uniform 变量位置
- 设置背景颜色
- 清空画布
- 绘制圆形
- 这个 demo 绘制了一个红色的圆形。
- <!DOCTYPE html>
- <html>
- <head>
- <title>WebGL Demo</title>
- <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
- <script src="https://cdn.bootcdn.net/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
- <script type="text/javascript">
- window.onload = function () {
- // 获取 canvas 元素
- var canvas = document.getElementById('myCanvas');
-
- // 获取绘图上下文
- var gl = canvas.getContext('webgl');
-
- // 定义顶点着色器
- var vertexShaderSource = `
- attribute vec4 a_Position;
- void main() {
- gl_Position = a_Position;
- }
- `;
-
- // 定义片元着色器
- var fragmentShaderSource = `
- precision mediump float;
- uniform vec4 u_FragColor;
- void main() {
- gl_FragColor = u_FragColor;
- }
- `;
-
- // 创建顶点着色器
- 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 circleVertices = [];
- var r = 0.5; // 半径
- var centerX = 0; // 圆心 X 坐标
- var centerY = 0; // 圆心 Y 坐标
- var n = 360; // 分割成 n 个三角形,每个三角形有三个顶点
- var angle = 0;
- for (var i = 0; i < n; i++) {
- circleVertices.push(centerX, centerY, 0);
- circleVertices.push(centerX + r * Math.cos(angle), centerY + r * Math.sin(angle), 0);
- angle += 2 * Math.PI / n;
- circleVertices.push(centerX + r * Math.cos(angle), centerY + r * Math.sin(angle), 0);
- }
-
- // 创建缓冲对象并绑定到目标
- var buffer = gl.createBuffer();
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
-
- // 向缓冲对象写入数据
- var vertices = new Float32Array(circleVertices);
- gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
-
- // 获取属性变量位置
- var a_Position = gl.getAttribLocation(program, 'a_Position');
- gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0);
- gl.enableVertexAttribArray(a_Position);
-
- // 获取 uniform 变量位置
- var u_FragColor = gl.getUniformLocation(program, 'u_FragColor');
-
- // 设置背景颜色
- gl.clearColor(0.9, 0.9, 0.9, 1.0);
-
- // 清空画布
- gl.clear(gl.COLOR_BUFFER_BIT);
-
- // 绘制圆形
- gl.uniform4f(u_FragColor, 1.0, 0.0, 0.0, 1.0); // 设置颜色(红色)
- gl.drawArrays(gl.TRIANGLES, 0, circleVertices.length / 3);
- };
- </script>
- </head>
- <body>
- <canvas id="myCanvas" width="400" height="400"></canvas>
- </body>
- </html>

WebGL是基于HTML5中的canvas元素的。WebGL使用OpenGL ES 2.0规范来编写3D图形。WebGL的API允许JavaScript在canvas元素上绘制各种类型的3D图像,并使用GPU加速。所以,可以说WebGL是基于canvas,但它使用了更高级的图形处理技术来实现复杂的3D图像。
canvas3D是HTML5的一个新特性,它提供了对3D图形的支持,使得在网页上实现3D效果成为可能。canvas3D是基于WebGL实现的,WebGL是一种基于OpenGL ES 2.0的图形库,它可以在网页中实现高性能的3D图形渲染。
使用canvas3D,您可以创建和操作3D对象、应用材质和贴图、添加光照和阴影等等。它提供了一组丰富的API,可以用于绘制和操作3D图形,包括对物体的旋转、缩放、平移等操作。
虽然canvas3D目前还处于实验阶段,但它已经得到了许多浏览器的支持,未来可能会成为HTML5标准的一部分。如果您对3D图形编程感兴趣,可以尝试使用canvas3D来实现您的项目。
----文心一言