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


    一、前置内容

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

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

    二、在线运行HTML

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

    在线运行Html5

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

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

    三、WebGL练习

    demo来至AI

    3.1、绘制正方形

    在这个 Demo 中,我们首先获取了 WebGL 上下文,然后定义了一个顶点着色器和一个片元着色器。接着,我们创建了着色器程序对象,并将顶点着色器和片元着色器附加到这个程序对象上,并进行链接。

    然后,我们创建了一个顶点缓冲区,并将顶点坐标存储在这个缓冲区中。我们启用了顶点属性,并将顶点缓冲区对象绑定到这个属性上。

    接下来,我们设置了视口大小,并清空了画布。最后,我们使用 gl.drawArrays() 方法绘制了一个正方形。

    需要注意的是,绘制图形时,我们使用的是 gl.TRIANGLE_FAN,它表示绘制一个三角形扇形,也就是一个由五个三角形组成的正方形。这样可以减少绘制的顶点数量,提高性能。

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>WebGL 基础 Demo</title>
    6. <style>
    7. canvas {
    8. border: 1px solid black;
    9. }
    10. </style>
    11. </head>
    12. <body>
    13. <canvas id="canvas" width="500" height="500"></canvas>
    14. <script>
    15. // 获取 WebGL 上下文
    16. const canvas = document.getElementById('canvas');
    17. const gl = canvas.getContext('webgl');
    18. // 定义顶点着色器代码
    19. const vertexShaderCode = `
    20. attribute vec3 a_position;
    21. void main() {
    22. gl_Position = vec4(a_position, 1.0);
    23. }
    24. `;
    25. // 定义片元着色器代码
    26. const fragmentShaderCode = `
    27. precision mediump float;
    28. void main() {
    29. gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    30. }
    31. `;
    32. // 创建顶点着色器对象
    33. const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    34. gl.shaderSource(vertexShader, vertexShaderCode);
    35. gl.compileShader(vertexShader);
    36. // 创建片元着色器对象
    37. const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    38. gl.shaderSource(fragmentShader, fragmentShaderCode);
    39. gl.compileShader(fragmentShader);
    40. // 创建着色器程序对象
    41. const shaderProgram = gl.createProgram();
    42. gl.attachShader(shaderProgram, vertexShader);
    43. gl.attachShader(shaderProgram, fragmentShader);
    44. gl.linkProgram(shaderProgram);
    45. // 获取着色器变量位置
    46. const positionLocation = gl.getAttribLocation(shaderProgram, 'a_position');
    47. // 创建顶点数据
    48. const vertices = [
    49. -0.5, -0.5, 0.0,
    50. 0.5, -0.5, 0.0,
    51. 0.5, 0.5, 0.0,
    52. -0.5, 0.5, 0.0
    53. ];
    54. // 创建顶点缓冲区对象
    55. const vertexBuffer = gl.createBuffer();
    56. // 绑定缓冲区对象
    57. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    58. // 将数据写入缓冲区对象
    59. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    60. // 启用顶点属性
    61. gl.enableVertexAttribArray(positionLocation);
    62. // 将缓冲区对象绑定到顶点属性上
    63. gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
    64. // 设置视口
    65. gl.viewport(0, 0, canvas.width, canvas.height);
    66. // 清空画布
    67. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    68. gl.clear(gl.COLOR_BUFFER_BIT);
    69. // 使用着色器
    70. gl.useProgram(shaderProgram);
    71. // 绘制图形
    72. gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
    73. </script>
    74. </body>
    75. </html>

    3.2、清屏

    这个 Demo 创建了一个空的 WebGL 上下文并在 canvas 上进行了清屏操作。可以通过更改 clearColor() 的参数来修改屏幕上的颜色。

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>WebGL Demo</title>
    6. <style>
    7. html, body {
    8. margin: 0;
    9. padding: 0;
    10. height: 100%;
    11. overflow: hidden;
    12. }
    13. canvas {
    14. width: 100%;
    15. height: 100%;
    16. }
    17. </style>
    18. </head>
    19. <body>
    20. <canvas id="canvas"></canvas>
    21. <script>
    22. const canvas = document.getElementById('canvas');
    23. const gl = canvas.getContext('webgl');
    24. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    25. gl.clear(gl.COLOR_BUFFER_BIT);
    26. </script>
    27. </body>
    28. </html>

    3.3、WebGL 三角形渲染

    1. 它包括以下步骤:
    2. 获取 canvas 元素和 WebGL 上下文对象。
    3. 定义顶点着色器和片段着色器。
    4. 创建顶点着色器和片段着色器对象。
    5. 创建着色器程序对象。
    6. 定义三角形顶点坐标并写入缓冲区。
    7. 获取顶点着色器中 aPosition 的地址并启用。
    8. 清除画布并绘制三角形。
    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>WebGL Demo</title>
    6. </head>
    7. <body>
    8. <canvas id="glCanvas" width="640" height="480"></canvas>
    9. <script>
    10. function init() {
    11. // 获取 canvas 元素
    12. var canvas = document.getElementById("glCanvas");
    13. // 获取 WebGL 上下文
    14. var gl = canvas.getContext("webgl");
    15. // 定义顶点着色器
    16. var vertexShaderSource = `
    17. attribute vec3 aPosition;
    18. void main() {
    19. gl_Position = vec4(aPosition, 1.0);
    20. }
    21. `;
    22. // 定义片段着色器
    23. var fragmentShaderSource = `
    24. void main() {
    25. gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    26. }
    27. `;
    28. // 创建顶点着色器
    29. var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    30. gl.shaderSource(vertexShader, vertexShaderSource);
    31. gl.compileShader(vertexShader);
    32. // 创建片段着色器
    33. var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    34. gl.shaderSource(fragmentShader, fragmentShaderSource);
    35. gl.compileShader(fragmentShader);
    36. // 创建着色器程序
    37. var program = gl.createProgram();
    38. gl.attachShader(program, vertexShader);
    39. gl.attachShader(program, fragmentShader);
    40. gl.linkProgram(program);
    41. gl.useProgram(program);
    42. // 定义三角形顶点坐标
    43. var vertices = [
    44. 0.0, 0.5, 0.0,
    45. -0.5, -0.5, 0.0,
    46. 0.5, -0.5, 0.0
    47. ];
    48. // 创建缓冲区并写入数据
    49. var vertexBuffer = gl.createBuffer();
    50. gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    51. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    52. // 获取顶点着色器中 aPosition 的地址
    53. var aPosition = gl.getAttribLocation(program, "aPosition");
    54. gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
    55. gl.enableVertexAttribArray(aPosition);
    56. // 清除画布并绘制三角形
    57. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    58. gl.clear(gl.COLOR_BUFFER_BIT);
    59. gl.drawArrays(gl.TRIANGLES, 0, 3);
    60. }
    61. init();
    62. </script>
    63. </body>
    64. </html>

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

    WebGL 绘制了一个红色的三角形,该三角形的顶点坐标分别为 (0.0, 0.5)(-0.5, -0.5) 和 (0.5, -0.5)。在绘制过程中,我们首先编译和链接了顶点着色器和片元着色器,并创建了一个着色器程序。然后我们创建了一个顶点缓冲,并将顶点数据绑定到该缓冲上。接下来我们通过顶点属性将顶点数据传递给顶点着色器,在片元着色器中设置了颜色,并通过调用 gl.drawArrays(gl.TRIANGLES, 0, 3) 绘制了该三角形。

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>WebGL Demo</title>
    6. <style>
    7. canvas {
    8. border: 1px solid black;
    9. }
    10. </style>
    11. </head>
    12. <body>
    13. <canvas id="my-canvas" width="500" height="500"></canvas>
    14. <script>
    15. const canvas = document.getElementById('my-canvas');
    16. const gl = canvas.getContext('webgl');
    17. // 定义顶点着色器
    18. const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    19. gl.shaderSource(vertexShader, `
    20. attribute vec4 a_position;
    21. void main() {
    22. gl_Position = a_position;
    23. }
    24. `);
    25. gl.compileShader(vertexShader);
    26. // 定义片元着色器
    27. const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    28. gl.shaderSource(fragmentShader, `
    29. precision mediump float;
    30. uniform vec4 u_color;
    31. void main() {
    32. gl_FragColor = u_color;
    33. }
    34. `);
    35. gl.compileShader(fragmentShader);
    36. // 创建着色器程序
    37. const program = gl.createProgram();
    38. gl.attachShader(program, vertexShader);
    39. gl.attachShader(program, fragmentShader);
    40. gl.linkProgram(program);
    41. gl.useProgram(program);
    42. // 定义顶点数据
    43. const vertices = [
    44. 0.0, 0.5,
    45. -0.5, -0.5,
    46. 0.5, -0.5,
    47. ];
    48. // 创建顶点缓冲
    49. const buffer = gl.createBuffer();
    50. gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    51. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    52. // 绑定顶点属性
    53. const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
    54. gl.enableVertexAttribArray(positionAttributeLocation);
    55. gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
    56. // 设置颜色
    57. const colorUniformLocation = gl.getUniformLocation(program, 'u_color');
    58. gl.uniform4f(colorUniformLocation, 1.0, 0.0, 0.0, 1.0);
    59. // 清空画布
    60. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    61. gl.clear(gl.COLOR_BUFFER_BIT);
    62. // 绘制三角形
    63. gl.drawArrays(gl.TRIANGLES, 0, 3);
    64. </script>
    65. </body>
    66. </html>

    3.5、WebGL 绘制颜色渐变矩形

    在这个 Demo 中,我们首先创建了一个 WebGL 上下文,并定义了一个顶点着色器和一个片元着色器。接着,我们创建了一个着色器程序对象,并将顶点着色器和片元着色器附加到这个程序对象上,并进行链接。

    然后,我们创建了一个顶点缓冲区,并将顶点坐标存储在这个缓冲区中。我们还设置了视图和投影矩阵,并使用着色器程序。接下来,我们启用了顶点属性,并将顶点缓冲区绑定到这个属性上。最后,我们使用 gl.drawArrays() 方法绘制了一个矩形。

    在片元着色器中,我们使用了 mix() 函数来计算每个像素的颜色,从而实现了颜色渐变效果。我们还定义了两个 uniform 变量 u_colorA 和 u_colorB,用于控制矩形的颜色。

    在这个 Demo 中,我们只是绘制了一个简单的颜色渐变矩形,但你可以根据需要对其进行修改和扩展。

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8" />
    5. <title>WebGL Demo</title>
    6. <script type="text/javascript">
    7. window.onload = function() {
    8. const canvas = document.getElementById("canvas");
    9. const gl = canvas.getContext("webgl");
    10. // 顶点着色器代码
    11. const vertexShaderSource = `
    12. attribute vec2 a_position;
    13. void main() {
    14. gl_Position = vec4(a_position, 0.0, 1.0);
    15. }
    16. `;
    17. // 片元着色器代码
    18. const fragmentShaderSource = `
    19. precision mediump float;
    20. uniform vec4 u_colorA;
    21. uniform vec4 u_colorB;
    22. void main() {
    23. gl_FragColor = mix(u_colorA, u_colorB, gl_FragCoord.y / 500.0);
    24. }
    25. `;
    26. // 创建顶点着色器对象
    27. const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    28. gl.shaderSource(vertexShader, vertexShaderSource);
    29. gl.compileShader(vertexShader);
    30. // 创建片元着色器对象
    31. const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    32. gl.shaderSource(fragmentShader, fragmentShaderSource);
    33. gl.compileShader(fragmentShader);
    34. // 创建着色器程序对象
    35. const program = gl.createProgram();
    36. gl.attachShader(program, vertexShader);
    37. gl.attachShader(program, fragmentShader);
    38. gl.linkProgram(program);
    39. // 获取顶点着色器中的变量位置
    40. const positionLocation = gl.getAttribLocation(program, "a_position");
    41. // 创建顶点缓冲区
    42. const positionBuffer = gl.createBuffer();
    43. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    44. const positions = [
    45. 0, 0,
    46. 0, 500,
    47. 500, 0,
    48. 500, 500,
    49. ];
    50. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
    51. // 设置视图和投影矩阵
    52. gl.viewport(0, 0, canvas.width, canvas.height);
    53. gl.clearColor(0, 0, 0, 1);
    54. gl.clear(gl.COLOR_BUFFER_BIT);
    55. // 使用着色器程序
    56. gl.useProgram(program);
    57. // 启用顶点属性
    58. gl.enableVertexAttribArray(positionLocation);
    59. // 将顶点缓冲区绑定到顶点属性
    60. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    61. gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
    62. // 设置 uniform 变量
    63. const colorALocation = gl.getUniformLocation(program, 'u_colorA');
    64. const colorBLocation = gl.getUniformLocation(program, 'u_colorB');
    65. gl.uniform4f(colorALocation, 1, 0, 0, 1);
    66. gl.uniform4f(colorBLocation, 0, 0, 1, 1);
    67. // 绘制矩形
    68. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
    69. };
    70. </script>
    71. <style>
    72. canvas {
    73. border: 1px solid black;
    74. }
    75. </style>
    76. </head>
    77. <body>
    78. <canvas id="canvas" width="500" height="500"></canvas>
    79. </body>
    80. </html>

    3.6、绘制一个彩色三角形

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="utf-8" />
    5. <title>WebGL Demo</title>
    6. <style>
    7. body {
    8. margin: 0;
    9. padding: 0;
    10. }
    11. #glcanvas {
    12. width: 100vw;
    13. height: 100vh;
    14. display: block;
    15. }
    16. </style>
    17. </head>
    18. <body>
    19. <canvas id="glcanvas"></canvas>
    20. <script>
    21. const canvas = document.querySelector("#glcanvas");
    22. const gl = canvas.getContext("webgl");
    23. const vertexShaderSource = `
    24. attribute vec3 aPosition;
    25. attribute vec3 aColor;
    26. varying vec3 vColor;
    27. void main() {
    28. gl_Position = vec4(aPosition, 1.0);
    29. vColor = aColor;
    30. }
    31. `;
    32. const fragmentShaderSource = `
    33. precision mediump float;
    34. varying vec3 vColor;
    35. void main() {
    36. gl_FragColor = vec4(vColor, 1.0);
    37. }
    38. `;
    39. const shaderProgram = createShaderProgram(gl, vertexShaderSource, fragmentShaderSource);
    40. const positionAttributeLocation = gl.getAttribLocation(shaderProgram, "aPosition");
    41. const colorAttributeLocation = gl.getAttribLocation(shaderProgram, "aColor");
    42. const positionBuffer = gl.createBuffer();
    43. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    44. const positions = [-0.5, 0.5, 0.0, 0.5, 0.5, 0.0, 0.0, -0.5, 0.0];
    45. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
    46. const colorBuffer = gl.createBuffer();
    47. gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    48. const colors = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];
    49. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
    50. function createShaderProgram(gl, vertexShaderSource, fragmentShaderSource) {
    51. const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    52. gl.shaderSource(vertexShader, vertexShaderSource);
    53. gl.compileShader(vertexShader);
    54. if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
    55. console.log("Error compiling vertex shader:", gl.getShaderInfoLog(vertexShader));
    56. return null;
    57. }
    58. const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    59. gl.shaderSource(fragmentShader, fragmentShaderSource);
    60. gl.compileShader(fragmentShader);
    61. if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
    62. console.log("Error compiling fragment shader:", gl.getShaderInfoLog(fragmentShader));
    63. return null;
    64. }
    65. const shaderProgram = gl.createProgram();
    66. gl.attachShader(shaderProgram, vertexShader);
    67. gl.attachShader(shaderProgram, fragmentShader);
    68. gl.linkProgram(shaderProgram);
    69. if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    70. console.log("Error linking shader program:", gl.getProgramInfoLog(shaderProgram));
    71. return null;
    72. }
    73. return shaderProgram;
    74. }
    75. function render() {
    76. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    77. gl.clear(gl.COLOR_BUFFER_BIT);
    78. gl.useProgram(shaderProgram);
    79. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    80. gl.enableVertexAttribArray(positionAttributeLocation);
    81. gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    82. gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    83. gl.enableVertexAttribArray(colorAttributeLocation);
    84. gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
    85. gl.drawArrays(gl.TRIANGLES, 0, 3);
    86. }
    87. requestAnimationFrame(render);
    88. </script>
    89. </body>
    90. </html>

    3.7、旋转的立方体

    本例的代码中,我们使用 THREE.js 库创建了一个场景,相机和渲染器。我们还创建了一个立方体,并将其添加到场景中。最后,我们创建了一个动画函数,使立方体绕 X 和 Y 轴旋转,并在每个帧中更新渲染器。

    运行上面的代码,您将在浏览器中看到一个绿色的立方体,它在不断旋转。

    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <title>WebGL Demo</title>
    5. <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    6. <style>
    7. body { margin: 0; }
    8. canvas { width: 100%; height: 100%; display: block; }
    9. </style>
    10. </head>
    11. <body>
    12. <script>
    13. // 初始化场景
    14. var scene = new THREE.Scene();
    15. // 初始化相机
    16. var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    17. camera.position.z = 5;
    18. // 初始化渲染器
    19. var renderer = new THREE.WebGLRenderer();
    20. renderer.setSize(window.innerWidth, window.innerHeight);
    21. document.body.appendChild(renderer.domElement);
    22. // 创建立方体
    23. var geometry = new THREE.BoxGeometry();
    24. var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
    25. var cube = new THREE.Mesh(geometry, material);
    26. scene.add(cube);
    27. // 创建动画
    28. function animate() {
    29. requestAnimationFrame(animate);
    30. cube.rotation.x += 0.01;
    31. cube.rotation.y += 0.01;
    32. renderer.render(scene, camera);
    33. }
    34. animate();
    35. </script>
    36. </body>
    37. </html>

    3.8、彩色三角形

    1. 获取 WebGL 上下文;
    2. 编写顶点着色器和片元着色器代码;
    3. 初始化着色器程序和获取 attribute 变量和 uniform 变量的位置;
    4. 准备顶点数据和颜色数据,并创建对应的缓冲区;
    5. 设置绘制参数,包括启用 attribute 位置、绑定缓冲区和设置指针;
    6. 设置投影矩阵和模型视图矩阵,并绘制三角形。
    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <title>WebGL Demo</title>
    5. <script src="https://cdn.bootcdn.net/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
    6. </head>
    7. <body>
    8. <canvas id="canvas" width="800" height="600"></canvas>
    9. <script>
    10. const canvas = document.getElementById('canvas');
    11. const gl = canvas.getContext('webgl');
    12. if (!gl) {
    13. alert('WebGL not supported.');
    14. }
    15. // 顶点着色器代码
    16. const vsSource = `
    17. attribute vec4 aVertexPosition;
    18. attribute vec4 aVertexColor;
    19. uniform mat4 uModelViewMatrix;
    20. uniform mat4 uProjectionMatrix;
    21. varying lowp vec4 vColor;
    22. void main() {
    23. gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
    24. vColor = aVertexColor;
    25. }
    26. `;
    27. // 片元着色器代码
    28. const fsSource = `
    29. varying lowp vec4 vColor;
    30. void main() {
    31. gl_FragColor = vColor;
    32. }
    33. `;
    34. // 初始化着色器程序
    35. const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
    36. // 获取 attribute 变量和 uniform 变量的位置
    37. const programInfo = {
    38. program: shaderProgram,
    39. attribLocations: {
    40. vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
    41. vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'),
    42. },
    43. uniformLocations: {
    44. projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
    45. modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
    46. },
    47. };
    48. // 设置顶点数据
    49. const positions = [
    50. 0, 0.5, 0,
    51. -0.5, -0.5, 0,
    52. 0.5, -0.5, 0,
    53. ];
    54. const colors = [
    55. 1, 0, 0, 1,
    56. 0, 1, 0, 1,
    57. 0, 0, 1, 1,
    58. ];
    59. // 创建顶点缓冲区
    60. const positionBuffer = gl.createBuffer();
    61. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    62. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
    63. const colorBuffer = gl.createBuffer();
    64. gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    65. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
    66. // 设置绘制参数
    67. gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);
    68. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    69. gl.vertexAttribPointer(programInfo.attribLocations.vertexPosition, 3, gl.FLOAT, false, 0, 0);
    70. gl.enableVertexAttribArray(programInfo.attribLocations.vertexColor);
    71. gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    72. gl.vertexAttribPointer(programInfo.attribLocations.vertexColor, 4, gl.FLOAT, false, 0, 0);
    73. gl.useProgram(programInfo.program);
    74. // 设置投影矩阵和模型视图矩阵
    75. const projectionMatrix = mat4.create();
    76. mat4.perspective(projectionMatrix, 45 * Math.PI / 180, canvas.width / canvas.height, 0.1, 100.0);
    77. const modelViewMatrix = mat4.create();
    78. mat4.translate(modelViewMatrix, modelViewMatrix, [-0.0, 0.0, -3.0]);
    79. // 绘制
    80. gl.uniformMatrix4fv(programInfo.uniformLocations.projectionMatrix, false, projectionMatrix);
    81. gl.uniformMatrix4fv(programInfo.uniformLocations.modelViewMatrix, false, modelViewMatrix);
    82. gl.drawArrays(gl.TRIANGLES, 0, 3);
    83. // 初始化着色器程序函数
    84. function initShaderProgram(gl, vsSource, fsSource) {
    85. const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
    86. const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
    87. const shaderProgram = gl.createProgram();
    88. gl.attachShader(shaderProgram, vertexShader);
    89. gl.attachShader(shaderProgram, fragmentShader);
    90. gl.linkProgram(shaderProgram);
    91. if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    92. alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
    93. return null;
    94. }
    95. return shaderProgram;
    96. }
    97. // 加载着色器函数
    98. function loadShader(gl, type, source) {
    99. const shader = gl.createShader(type);
    100. gl.shaderSource(shader, source);
    101. gl.compileShader(shader);
    102. if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    103. alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
    104. gl.deleteShader(shader);
    105. return null;
    106. }
    107. return shader;
    108. }
    109. </script>
    110. </body>
    111. </html>

    3.9、绘制圆形

    1. 获取 canvas 元素和绘图上下文
    2. 定义 顶点着色器 和 片元着色器,顶点着色器用于处理顶点数据,片元着色器用于处理每个像素的颜色值
    3. 创建 顶点着色器 和 片元着色器,并编译
    4. 创建 程序对象,并将 顶点着色器 和 片元着色器 附加到程序对象上
    5. 链接程序对象,并使用
    6. 定义圆形顶点数据(分割成 n 个三角形)
    7. 创建缓冲对象并绑定到目标上
    8. 向缓冲对象写入数据
    9. 获取 属性变量 位置
    10. 设置 属性变量,并启用
    11. 获取 uniform 变量位置
    12. 设置背景颜色
    13. 清空画布
    14. 绘制圆形
    15. 这个 demo 绘制了一个红色的圆形。
    1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <title>WebGL Demo</title>
    5. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    6. <script src="https://cdn.bootcdn.net/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
    7. <script type="text/javascript">
    8. window.onload = function () {
    9. // 获取 canvas 元素
    10. var canvas = document.getElementById('myCanvas');
    11. // 获取绘图上下文
    12. var gl = canvas.getContext('webgl');
    13. // 定义顶点着色器
    14. var vertexShaderSource = `
    15. attribute vec4 a_Position;
    16. void main() {
    17. gl_Position = a_Position;
    18. }
    19. `;
    20. // 定义片元着色器
    21. var fragmentShaderSource = `
    22. precision mediump float;
    23. uniform vec4 u_FragColor;
    24. void main() {
    25. gl_FragColor = u_FragColor;
    26. }
    27. `;
    28. // 创建顶点着色器
    29. var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    30. gl.shaderSource(vertexShader, vertexShaderSource);
    31. gl.compileShader(vertexShader);
    32. // 创建片元着色器
    33. var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    34. gl.shaderSource(fragmentShader, fragmentShaderSource);
    35. gl.compileShader(fragmentShader);
    36. // 创建程序对象
    37. var program = gl.createProgram();
    38. gl.attachShader(program, vertexShader);
    39. gl.attachShader(program, fragmentShader);
    40. gl.linkProgram(program);
    41. gl.useProgram(program);
    42. // 定义圆形顶点数据
    43. var circleVertices = [];
    44. var r = 0.5; // 半径
    45. var centerX = 0; // 圆心 X 坐标
    46. var centerY = 0; // 圆心 Y 坐标
    47. var n = 360; // 分割成 n 个三角形,每个三角形有三个顶点
    48. var angle = 0;
    49. for (var i = 0; i < n; i++) {
    50. circleVertices.push(centerX, centerY, 0);
    51. circleVertices.push(centerX + r * Math.cos(angle), centerY + r * Math.sin(angle), 0);
    52. angle += 2 * Math.PI / n;
    53. circleVertices.push(centerX + r * Math.cos(angle), centerY + r * Math.sin(angle), 0);
    54. }
    55. // 创建缓冲对象并绑定到目标
    56. var buffer = gl.createBuffer();
    57. gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    58. // 向缓冲对象写入数据
    59. var vertices = new Float32Array(circleVertices);
    60. gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
    61. // 获取属性变量位置
    62. var a_Position = gl.getAttribLocation(program, 'a_Position');
    63. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0);
    64. gl.enableVertexAttribArray(a_Position);
    65. // 获取 uniform 变量位置
    66. var u_FragColor = gl.getUniformLocation(program, 'u_FragColor');
    67. // 设置背景颜色
    68. gl.clearColor(0.9, 0.9, 0.9, 1.0);
    69. // 清空画布
    70. gl.clear(gl.COLOR_BUFFER_BIT);
    71. // 绘制圆形
    72. gl.uniform4f(u_FragColor, 1.0, 0.0, 0.0, 1.0); // 设置颜色(红色)
    73. gl.drawArrays(gl.TRIANGLES, 0, circleVertices.length / 3);
    74. };
    75. </script>
    76. </head>
    77. <body>
    78. <canvas id="myCanvas" width="400" height="400"></canvas>
    79. </body>
    80. </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博客

  • 相关阅读:
    STM32两轮平衡小车原理详解(开源)
    【Java】day01 - Java基础语法
    148-153-Hadoop-调优-多目录-黑白名单
    java计算机毕业设计中美医院病历管理系统源代码+系统+数据库+lw文档
    [二进制学习笔记]LibcSearcher报错no matched libc
    测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
    网页文档阅读的学习笔记
    物联网应用-分布式对象储存工具-MinIO 对象存储win部署及使用
    Quarto Dashboards 教程 1:Overview
    服务器被墙是什么原因,怎么解决服务器被墙
  • 原文地址:https://blog.csdn.net/snowball_li/article/details/134164447