绘制一个立方体—WebGL旋转变换

优质
小牛编辑
126浏览
2023-12-01

立方体

实现的基本思路很简单,首先提供如上图所示立方体线框所有顶点的三维坐标,然后通过旋转矩阵对所有顶点进行旋转变换,最后调用绘制函数gl.drawArrays把所有点连成线渲染出来。

通过第1.3、1.4两节课案例知道,显示器上显示的实际上是平面的像素,可以简单理解为三维几何体放在你眼睛和显示器之间,几何体在显示器上的投影,视线一定的情况下, 你看到的投影效果取决几何体的位置状态,如果你学过画法几何应该知道轴测图的概念,没学过画法几何,你初高中也应该见过老师在黑板上画立方体的三维效果图, 如果你的视线沿着立方体的边线,投影就是一个平面的正方形,四条边线没有立体效果。如果你想呈现立体效果,你就要调整你看立方体的角度,那么问题来了,立方体8个顶点,如果让 立方体的三条棱线和xyz轴重合,你可以很容易用Javascript的数组写出他的坐标,假设立方体顶点是WebGL坐标系中的相对值±0.5,8各顶点就是(±0.5,±0.5,±0.5),排列组合就可以, 立方体相对WebGL的坐标系如果是倾斜放的(棱线与坐标轴不重合),你就需要笔算出当前8个顶点的坐标值,立方体还算规则,如果一张人脸上千甚至更多的顶点坐标怎么办?这个时候算法上就是需要 矩阵乘法运算来辅助,对于旋转而言就是旋转矩阵,对于硬件而言就是需要GPU,大规模并行处理顶点数据。上一节课说过平移变换,本节课涉及到的就是旋转变换。

体验测试

  • 你可以更改第14行顶点着色器中代码float radian = radians(30.0);的旋转角度数值,刷新浏览器,观察不同角度立方体的效果
//设置几何体轴旋转角度为30度,并把角度值转化为弧度值
float radian = radians(30.0);
  • 尝试更改第99~104行代码绘制函数的第一个参数绘制模式,可以分别测试LINESLINE_LOOPLINE_STRIP,看看有什么不同,进一步加深对绘制模式的理解,对图元装配的理解
//LINE_LOOP模式绘制前四个点
gl.drawArrays(gl.LINE_LOOP,0,4);
//LINE_LOOP模式从第五个点开始绘制四个点
gl.drawArrays(gl.LINE_LOOP,4,4);
//LINES模式绘制后8个点
gl.drawArrays(gl.LINES,8,8);

着色器内置函数

WebGL着色器提供了一系列可以内置函数,也就是说不用声明可以直接调用的函数。

radians()函数:角度值转化为弧度制,参数是浮点数float,比如30度时,要写成30.0

//旋转角度30度转化为弧度值
float radian = radians(30.0);

cos()是余弦函数,参数要求是弧度值且是浮点数

sin()是正弦函数,参数要求是弧度值且是浮点数

//求解旋转角度余弦值
float cos = cos(radian);
//求解旋转角度正弦值
float sin = sin(radian);

关于WebGL着色器内置函数的更多详细介绍,可以查看第二章2.11节。

代码执行流程简述

执行流程和前几节的案例大同小异,主要是多次调用了绘制命令gl.drawArrays。第63行data变量定义的顶点数据初始化时,会存入内存中,执行第91行代码gl.bindBuffer(gl.ARRAY_BUFFER,buffer);内存中的数据一次性传入显存缓冲区中,传入缓冲区中的顶点数据 可以通过drawArrays方法多次调用,每次drawArrays方法调用,顶点经过渲染管线得到的像素相关数据都会存入帧缓存中,后一次调用,前一次调用生成的像素数据不会清空,最终形成一幅完整的立方体线框图。

旋转变换矩阵解析

假设一个点的坐标是(x,y,z),经过旋转变换后的坐标为(X,Y,Z)

绕Z轴旋转γ角度

z的坐标不变不变,x、y的坐标发生变化,在笛卡尔坐标系下通过简单的数学计算就可以知道结果,X=xcosγ-ysinγ,Y=xsinγ+ycosγ

这个过程如何用矩阵的乘法描述,如何利用线性代数进行建模,如果你有足够的数学训练,其实很简单,和上一节课一样为了简化问题, 不做深入线性代数的矩阵变换,仅仅采用矩阵的乘法法则进行验证

绕X轴旋转α角度

x的坐标不变不变,y、z的坐标发生变化,Y=ycosα-zsinα,Z=ysinα+zcosα

绕Y轴旋转β角度

y的坐标不变不变,z、x的坐标发生变化,Z=zsinβ+xcosβ,X=zcosβ-xsinβ

总结

  1. 如果几何体经过多次旋转可以把每一次的旋转矩阵,连续进行乘法运算,最后再左乘顶点的齐次坐标

  2. 旋转变换和平移变换同时存在,旋转矩阵和平移矩阵一样都是四阶矩阵,因此同样可以先进行乘法运算得到的仍是四阶矩阵,最后再左乘顶点的齐次坐标,这种情况也就是复合变换

视觉测试

你可以长时间凝视本案例浏览器页面上的立方体线框,你的大脑中会有两种立体效果来回切换,大脑混淆,立方体的前后位置来回切换, 主要原因是线框模式不符合实际生活物体光学效应。如果想真实模仿生活就要建立光照模型,模拟物体表面与光线的作用,要知光照模型,且听下回分解。 本节课绘制立方体没用采用面,而是投影线,就是因为没有光照模拟的几何体没有任何立体效果。