WebGL是一个非常的接近硬件底层的光栅化API, 从非常类似C/C++风格的API调用方式就可以看出来, 习惯了高级语言的我们会觉得很不友好,觉得特别繁琐. 这个也是很多人觉得WebGL难的原因之一. 如果我们要使用WebGL做一些项目,毫无疑问要么使用Three.js之类的3D库, 要么需要对原生的API进行封装. 这段时间查看了一些WebGL工具库的源代码, 参考封装出了一个简单的工具库,这样往后用WebGL做小项目就方便多了.
经过前面章节的学习, WebGL的知识点掌握的差不多了, 终于到了做特效和Demo的阶段了,来看一下这节实现的特效:WebGL多物体多光源场景
内容大纲
实现图形绕坐标原点旋转, 同时给所有的物体增加环境光, 漫反射, 高光. 其中旋转功能使用矩阵复合变换实现; 光照部分比较复杂,实现了多个光源照射.
- 着色器
- 模型变换
着色器
顶点着色器
代码很简单,逐顶点传入坐标,法向量矩阵,模型矩阵,mvp矩阵.
attribute vec4 a_position; |
片元着色器
分别在左前方和右后方添加了平行光源和点光源, 平行光源的高光使用的是宾氏模型, 它的高光过渡效果比较平滑; 点光源的高光使用的是冯氏模型, 它的高光部分比较明亮, 反射的效果比较好.
最后将两个光源照射产生的漫反射,高光亮度相加,就得到它们的综合光照效果了.
precision mediump float; |
模型变换
js代码部分使用工具库封装了原生WebGL的很多细节, 现在写起代码来要愉快得多了, 感觉和写canvas差不了太多😂. 这里重点介绍模型变换部分, 其他部分代码的细节之前章节已经介绍过了,所以不再详述.
首先初始化着色器,并创建program对象; 这里使用了多种图形(圆球,立方体,圆柱体,圆锥体), 所以分别为它们创建缓冲区, 缓冲区数据主要包括顶点,法向量,索引.
接着创建200个图形对象, 给每个对象赋予 随机x/y轴角速度, 随机初始点, 随机颜色.
最后终于到了动画的环节了, 绕原点旋转可以分解为x轴旋转, y轴旋转和位移. 要注意的是矩阵复合变换相乘的顺序, 也就是左乘和右乘是有区别的, 学过线性代数的应该都有印象. 这里要实现图形先位移z,然后再旋转, 那么对应的复合变换矩阵就是这样
<模型矩阵> = <绕x轴旋转矩阵> * <绕y轴旋转矩阵> * <位移矩阵> |
模型矩阵与视图投影矩阵相乘得出mvp矩阵, 对模型矩阵逆转置后还可以求出逆转置矩阵.
将矩阵和变量的值传递给着色器, 输出对应的图形缓冲区,然后根据图形对象依次绘制图形, 最后调用requestAnimationFrame递归执行动画函数.
var canvas = document.getElementById("canvas"), |
总结
使用工具类省略了很多繁琐无聊的部分,不用再去扣语法细节.比如获取变量地址, 赋值, 创建缓冲区. 我们可以把精力都集中到业务逻辑方面.