Three.js中文网 Three.js中文网
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • 文章
WebGPU教程
  • WebGL教程
  • ES GLSL着色器语言
  • WebGL教程(旧版本)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原官网文档 (opens new window)
首页
免费视频
系统课 (opens new window)
  • Three.js基础课程
  • Vue3+Threejs 3D可视化
  • Threejs进阶课程
  • 展厅3D预览漫游
  • Threejs Shader
  • Blender建模基础
  • 文章
WebGPU教程
  • WebGL教程
  • ES GLSL着色器语言
  • WebGL教程(旧版本)
3D案例
  • 本站部署(打开快) (opens new window)
  • 原官网文档 (opens new window)
Web3D系统课程视频
  • 1. WebGL绘制一个点(HTML框架文件)
  • 2. WebGL绘制一个矩形
  • 3. WebGL坐标系(投影)
  • 4. WebGL平移变换
  • 5. 绘制一个立方体(WebGL旋转变换)
  • 6. WebGL顶点索引绘制
  • 7. varying变量和颜色插值
  • 8. 立方体(每个面一种颜色)
  • 9. WebGL光照渲染立方体
  • 10 .立方体旋转动画
    • 11. WebGL绘制多个几何体
    • 12. 纹理贴图
    • 13. 彩色图转灰度图
    • 14. 切换着色器程序
    • 15. WebGL透明度与α融合
    • 16. 深度测试与α融合
    • WebGL教程-原旧版本
    郭隆邦
    2026-05-22
    目录

    10 .立方体旋转动画

    # 立方体旋转动画

    要通过WebGL渲染出立方体旋转的动画效果,你首要了解“帧”这个概念,比如你观看的视频其实就是一帧一帧的图片连续播放的效果,只要图片刷新的频率的不是太低,人的眼睛都不会察觉,一般30~60FPS就可以。 WebGL如何产生一帧一帧的图片,这个很简单,执行一次绘制函数gl.drawArrays(),WebGL图形系统就会通知GPU渲染管线处理顶点数据生成一帧RGB像素数据显示在屏幕canvas画布上。只要周期性保持一定的频率调用gl.drawArrays()就可以生成一帧一帧的图片, 在这个过程中同时要利用Javascript程序更新顶点的旋转矩阵,如果顶点的位置不变化,渲染出来的都是一样的图片,自然也没有动画的效果。

    浏览器提供了一个方法requestAnimationFrame()可以实现周期性调用某个函数,主要用于动画,该方法如何使用可以查看文章《HTML5定时器》 (opens new window)。

    在1.9节光照立方体的基础上进行更改,一方面是周期性执行绘制方法gl.drawArrays(),另一方面以一定的旋转速度更新立方体的旋转矩阵,原来使用着色器语言定义的旋转矩阵更改为使用Javascript语句创建好再传递给顶点着色器, gl.drawArrays()每次执行的时候,都会重新传入着色器顶点旋转矩阵数据,并渲染出来。

    # 声明矩阵变量

    /**uniform声明旋转矩阵变量mx、my**/
    uniform mat4 mx;//绕x轴旋转矩阵
    uniform mat4 my;//绕y轴旋转矩阵
    

    在顶点着色器代码中使用关键字uniform声明两个旋转矩阵变量mx和my,分别表示绕x轴、y轴的旋转矩阵。旋转矩阵数据和光照数据一样适用于所有的非顶点数据,使用关键字uniform声明,不能使用attribute关键字声明。

    # 传入mx矩阵数据

    /**从program对象获得旋转矩阵变量mx、my地址**/
    var mx = gl.getUniformLocation(program,'mx');
    var my = gl.getUniformLocation(program,'my');
    
    /**绕x轴旋转45度**/
    var mxArr = new Float32Array([
        1,0,0,0,
        0,Math.cos(Math.PI/4),-Math.sin(Math.PI/4),0,
        0,Math.sin(Math.PI/4),Math.cos(Math.PI/4),0,
        0,0,0,1
    ]);
    //把数据mxArr传递给着色器旋转矩阵变量mx
    gl.uniformMatrix4fv(mx, false, mxArr);
    
    

    上节课定义顶点旋转矩阵使用的着色器语言,下面的案例是先在Javascript程序中使用类型数组Float32Array()创建旋转矩阵的数据,然后使用WebGL APIgl.uniformMatrix4fv()把数据传递给着色器。WebGL中给着色器中不同关键字声明的不同类型变量传递数据, 要使用不同的WebGL API,uniform关键字声明的mat4类型变量使用WebGL APIgl.uniformMatrix4fv(),uniform关键字声明的mat2类型变量使用WebGL APIuniformMatrix2fv(),uniform关键字声明的一个浮点数使用gl.uniform1f()传递, uniform关键字声明的vec4类型变量和mat4一样使用uniform4fv(变量地址名,new Float32Array([a,b,c,d]))传递,也可以使用uniform4f(变量地址名,a,b,c,d)传递,attribute关键字声明的变量使用WebGL APIgl.vertexAttribPointer()传递。

    # 绘制函数draw()

    该绘制函数draw()可以使用第requestAnimationFrame(draw);代码实现draw()函数的循环调用,因为要实现立方体绕y轴旋转,所以要在draw函数中更新my旋转矩阵的数据,同时利用WebGL APIgl.uniformMatrix4fv()把新的矩阵数据传递给着色器矩阵变量my, 在函数重复调用gl.drawArrays(gl.TRIANGLES,0,36);不停绘制旋转后的顶点数据,所有需要更新的数据都要写在draw函数中,不需要反复执行的代码写在draw函数外,比如mx旋转矩阵只需要执行传入一次不在改变。

    /**
     * 定义绘制函数draw(),定时更新旋转矩阵数据,并调用WebGL绘制API
     ***/
    var angle = Math.PI/4;//起始角度
    function draw() {
        // gl.clear(gl.COLOR_BUFFER_BIT);//清空画布上一帧图像
        /**
         * 立方体绕y轴旋转
         ***/
        angle += 0.01;//每次渲染角度递增,每次渲染不同的角度
        var sin = Math.sin(angle);//旋转角度正弦值
        var cos = Math.cos(angle);//旋转角度余弦值
        var myArr = new Float32Array([cos,0,-sin,0,  0,1,0,0,  sin,0,cos,0,  0,0,0,1]);
        gl.uniformMatrix4fv(my, false, myArr);
        requestAnimationFrame(draw);
        /**执行绘制命令**/
        gl.drawArrays(gl.TRIANGLES,0,36);
    }
    draw();
    
    9. WebGL光照渲染立方体
    11. WebGL绘制多个几何体

    ← 9. WebGL光照渲染立方体 11. WebGL绘制多个几何体→

    Theme by Vdoing | Copyright © 2016-2026 豫ICP备16004767号-2
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式