WebGL:基础练习 / 简单学习 / demo / canvas3D

一、前置内容

canvas:理解canvas / 基础使用 / 实用demo-CSDN博客

WebGL:开始学习 / 理解 WebGL / WebGL 需要掌握哪些知识 / 应用领域 / 前端值得学WebGL吗_webgl培训-CSDN博客

二、在线运行HTML

用来运行WebGL代码,粘贴--运行(有时候不太好用,莫名报错)

在线运行Html5

三、获取画布、获取上下文环境对象

//获取画布元素
var canvas = document.getElementById('canvas')
//获取到元素的上下文环境对象
var webgl = canvas.getContext('webgl')

三、WebGL练习

demo来至AI

3.1、绘制正方形

在这个 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>

3.2、清屏

这个 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>

3.3、WebGL 三角形渲染

它包括以下步骤:
获取 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>

3.4、WebGL 绘制了一个红色的三角形

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>

3.5、WebGL 绘制颜色渐变矩形

在这个 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>

3.6、绘制一个彩色三角形

<!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>

3.7、旋转的立方体

本例的代码中,我们使用 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>

3.8、彩色三角形

获取 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>

3.9、绘制圆形

获取 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是基于canvas吗

WebGL是基于HTML5中的canvas元素的。WebGL使用OpenGL ES 2.0规范来编写3D图形。WebGL的API允许JavaScript在canvas元素上绘制各种类型的3D图像,并使用GPU加速。所以,可以说WebGL是基于canvas,但它使用了更高级的图形处理技术来实现复杂的3D图像。

记录二、理解 canvas3D

canvas3D是HTML5的一个新特性,它提供了对3D图形的支持,使得在网页上实现3D效果成为可能。canvas3D是基于WebGL实现的,WebGL是一种基于OpenGL ES 2.0的图形库,它可以在网页中实现高性能的3D图形渲染。

使用canvas3D,您可以创建和操作3D对象、应用材质和贴图、添加光照和阴影等等。它提供了一组丰富的API,可以用于绘制和操作3D图形,包括对物体的旋转、缩放、平移等操作。

虽然canvas3D目前还处于实验阶段,但它已经得到了许多浏览器的支持,未来可能会成为HTML5标准的一部分。如果您对3D图形编程感兴趣,可以尝试使用canvas3D来实现您的项目。

----文心一言

五、欢迎交流指正

六、参考链接

什么是WebGL? | 码上动力

【精选】【WebGL】简单入门教程_webgl教程-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/182346.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LangChain+LLM实战---Midjourney(v5.1) Prompt深度剖析

原文&#xff1a;Anatomy of Midjourney Promps: In-Depth Study for effective Prompting Strategies — V5.1 examples 作者&#xff1a;Michael King 你是否曾经发现自己盯着Midjourney的空白画布&#xff0c;手指悬停在键盘上&#xff0c;让我问自己&#xff1a;“我应该…

前端面试题之CSS篇

1、css选择器及其优先级 标签选择器: 1类选择器、属性选择器、伪类选择器&#xff1a;10id选择器&#xff1a;100内联选择器&#xff08;style“”&#xff09;&#xff1a;1000!important&#xff1a;10000 2、display的属性值及其作用 属性值作用none元素不显示&#xff0c…

使用VNC链接远程桌面

一、本地VNC客户端 本地主要需要一个VNC客户端&#xff0c;用来远程连接服务器端的VNC&#xff08;在不安装Web版本VNC情况下&#xff09;。VNC客户端下载地址&#xff1a; VNC客户端下载 二、安装Xfce桌面环境 在远程服务器控制台中安装Xfce桌面&#xff08;这个桌面环境比…

CSC公派遭美德拒签|计算机专业老师终赴意大利都灵理工大学访学

C老师拟申报CSC访学项目&#xff0c;希望先申请美国&#xff0c;并做好了一旦拒签再申请其它国家的心理准备。我们先用普渡大学的邀请函助其申报CSC&#xff0c;并顺利获批&#xff0c;但不出所料地被美国拒签了&#xff1b;很快又申请到德国奥芬堡应用技术大学&#xff0c;但不…

【Linux】简单部署Yearning并结合内网穿透实现公网访问

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单&#xff0c;高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开…

Jakarta-JVM篇

文章目录 一.前言1. 1 JVM-堆常用调参1.2 JVM-方法区常用参数1.3 JVM-codeCache 二.JVM内存结构三. 对象创建四. JVM垃圾回收算法4.1 可达性分析算法4.1.1 对象引用4.1.2 回收方法区. 4.2 分代回收4.3 标记清除4.4 标记复制4.5 标记整理 五.垃圾回收器5.1 根节点枚举5.2 安全点…

打造高效运营底座,极智嘉一体化软件系统彰显科技威能

在仓储成本和物流需求日益增加的今天&#xff0c;创新且高效的物流机器人解决方案能够显著提升物流运营效率&#xff0c;降低物流成本&#xff0c;实现智能化、精益化、一体化的物流管理。全球仓储机器人引领者极智嘉(Geek)以「一套系统&#xff0c;天生全能」为准则&#xff0…

python脚本-网页爬虫获取网页图片

python脚本-网页爬虫获取网页图片 代码 import requests import re import time url"http://10.9.47.154/python-spider/" # 爬取网站的url headers {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like …

亚马逊云科技大语言模型下的六大创新应用功能

目录 前言 亚马逊云科技的AI创新应用 ​编辑 Amazon CodeWhisperer Amazon CodeWhisperer产品的优势 更快地完成更多工作 自信地进行编码 增强代码安全性 使用收藏夹工具 自定义 CodeWhisperer 以获得更好的建议 如何使用Amazon CodeWhisperer 步骤 1 步骤 2 具体…

Flink源码解析八之任务调度和负载均衡

源码概览 jobmanager scheduler:这部分与 Flink 的任务调度有关。 CoLocationConstraint:这是一个约束类,用于确保某些算子的不同子任务在同一个 TaskManager 上运行。这通常用于状态共享或算子链的情况。CoLocationGroup & CoLocationGroupImpl:这些与 CoLocationCon…

【漏洞复现】IIS_7.o7.5解析漏洞

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 1.5、修复建议 1.1、漏洞描述 漏洞原理&#xff1a; cgi.fix_path1 1.png/.php该…

WPF中依赖属性及附加属性的概念及用法

完全来源于十月的寒流&#xff0c;感谢大佬讲解 依赖属性 由依赖属性提供的属性功能 与字段支持的属性不同&#xff0c;依赖属性扩展了属性的功能。 通常&#xff0c;添加的功能表示或支持以下功能之一&#xff1a; 资源数据绑定样式动画元数据重写属性值继承WPF 设计器集成 …

【数据结构】单链表OJ题

前言: 本节博客将讲解单链表的反转&#xff0c;合并有序链表&#xff0c;寻找中间节点及约瑟夫问题 文章目录 一、反转链表二、合并有序链表三、链表的中间结点四、环形链表的约瑟夫问题 一、反转链表 要反转链表&#xff0c;我们需要遍历链表并改变每个节点的 next 指针&#…

大数据毕业设计选题推荐-旅游景点游客数据分析-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

webgoat-Insecure Deserialization不安全的序列化

A&#xff08;8&#xff09;不安全的反序列化 反序列化是将已序列化的数据还原回对象的过程。然而&#xff0c;如果反序列化是不安全的&#xff0c;那么恶意攻击者可以在序列化的数据中夹带恶意代码&#xff0c;从而在反序列化时执行这些代码。这种攻击被称为反序列化。 什么…

雨洪水资源管理远程监控平台

雨洪水资源管理远程监控平台 汛期来临时&#xff0c;及时获得河道水库的水位涨幅数据对开展防汛抗洪工作至关重要&#xff0c;大量河道水库分布在远离城市的区域&#xff0c;而且分散&#xff0c;尤其是在紧急防汛阶段&#xff0c;如果只依靠传统人力巡查获得河道水位数据必将耗…

API接口对于程序员可以提高开发效率、减少错误率、保证数据一致性、增强用户体验

API接口给程序员带来了许多好处。以下是其中一些主要的好处&#xff1a; 提高开发效率&#xff1a;通过API接口&#xff0c;程序员可以避免重复编写代码&#xff0c;直接使用其他应用程序或服务提供的接口和数据&#xff0c;从而极大地提高了开发效率。减少错误率&#xff1a;…

linux修改rocketmq的日志文件位置

文章目录 &#x1f50a;修改rocketmq的日志文件位置&#x1f4d5;原来的文件&#x1f4cc;修改后文件&#x1f4c7;rocketmq中的Rocketmq_client.log文件在配置文件中改不了 需要在代码logback文件中进行修改&#x1f58a;️最后总结 &#x1f50a;修改rocketmq的日志文件位置 …

数据可视化:折线图

1.初看效果 &#xff08;1&#xff09;效果一 &#xff08;2&#xff09;数据来源 2.JSON数据格式 其实JSON数据在JAVA后期的学习过程中我已经是很了解了&#xff0c;基本上后端服务器和前端交互数据大多是采用JSON字符串的形式 &#xff08;1&#xff09;JSON的作用 &#…

uniapp在APP端使用swiper进行页面不卡顿滑动

uniapp在APP端使用swiper进行页面会卡顿&#xff0c;主要是渲染的数据有点多&#xff0c;这里只渲染三个数据就不好那么卡顿了&#xff0c;每次滑动后更新数据 <view><swiper change"changePoint" circular :disable-touch"disableTouch"><…