从零开始手撸WebGL3D引擎8:里程碑3-一个多光源场景

里程碑3

好久没写笔记了,本周又搞了几天,基本实现了基于多pass的多光源前向渲染,加上之前实现的基本的scene和transform,暂且算作里程碑3:simple scene。虽然代码里面还有很多TODO,但勉强可以看些效果了。先上个视频:

mini3d.js多光源逐像素 Blinn-Phong光照

现在把demo网页部署到了码云上mini3d.js_examples,国内访问比github快多了。

这个demo是在一个简单的场景里面,有两个胶囊体,有一个平行光和两个点光源,点光源会在场景中做螺旋运动。地面和胶囊体会接受这三个光源的光照(使用Blinn-Phong逐像素光照)。初始位置在左边的胶囊体会自动旋转同时在世界up轴(y轴)上自动上下移动,屏幕左右滑动可以改变该胶囊体在x,z平面上的位置。而右边的这个胶囊体会平滑的旋转以让自己面向可以移动的胶囊体。

虽然内容不是很多,但已经具备一些3D引擎的要素了。而且最近投入到mini3d.js上的时间少了很多(因为时间都用在刷leetcode了。。),所以从显示单个模型的demo2到这个有场景和光照的demo已经过了很久。这中间可以总结和记录的东西还是挺多的。本篇是总体介绍,可能会写几篇介绍一下某些东西的细节。

新增功能

为了实现这个基本的demo,mini3d.js添加了很多功能(当然很多还不完善,一些采用了临时替代方案)。

  • 基本的节点场景系统
    搞了个类似Unity的组件系统(不是ECS)。为了方便,没有独立出Transform组件,而是把transform相关的功能放入到SceneNode里面了。场景的主要功能是管理节点局部矩阵和世界矩阵的更新,以及管理Camera,Light和可渲染节点,为渲染服务。同时由于Transform功能的需要,math模块也更新了,新增了Matrix3专门用于处理旋转,另外增加了四元数相关的内容,包括四元数和Matrix3之间的相互转化,基于四元数和Matrix3的LookAt以及四元数的Slerp插值。可能有的同学说了,连基本的frustum culling都没有啊。。是的,暂时没有场景管理和剔除,没有LOD,没有材质排序,没有渲染队列,没有透明渲染,没有Batch,没有PostProcessing。。。没有的东西太多了,但是路一步一步走吧。
  • 多光源前向渲染框架
    这个参考了Unity的一些设计(但是暂时简化了),光源相关的pass分为ForwardBase和ForwardAdd (还有一个ShadowCaster没实现)。一个材质中可以包含任意多的pass,按顺序逐个渲染。如果是ForwardBase 的Pass,会输入最重要的平行光,并只渲染一次该Pass。如果是ForwardAdd的Pass,会输入其他多个光源,包含平行光和点光源,并且对于每个光源,渲染一次该Pass,并且把本次渲染的结果叠加到上一次。其他Pass只渲染一次,包括ShadowCaster和非光照Pass。注意,熟悉Unity的同学可能会说你这也不对啊,ForwardBase里面还能处理点光源呢!是的,所以说是简化了 ,因为这些其实是关系到效率的东西,暂时不急加,等mini3d.js实现了很多看上去很棒的东西后再开始优化。
  • 材质的实现
    为了和前向渲染框架配合,实现了一个材质类,考虑到开发速度,没有搞材质文件,直接用代码实现自定义材质,但是提供了一个框架,用来定义材质包含的Pass,需要的Unifrom,以及每个Pass使用到的顶点属性。系统提供了很多系统公用Uniform,只要在材质初始化时描述一下用到的uniform类型,就会在渲染前自动填充,并且材质也可以使用自定义Uniform,需要自己在合适的时候设置。基于这个框架,理论上可以实现任意渲染效果(PostProcessing除外,因为还没实现GrabPass)。目前简单实现了基于Blinn-Phong模型的逐顶点和逐像素光照材质,未来实现ShadowMap后会实现一个标准材质,后期还会实现PBR材质。当然卡通渲染,菲涅尔反射,CubeMap反射,玻璃折射,海水渲染这些都会一一尝试一下。
  • 其他
    新增了程序生成模型,目前只能生成立方体和平面。其中平面可以定义宽度长度和分段数,可以创建为wireframe模型(由于WebGL不支持全局的wireframe模式,所以采用GL_LINES绘制)

Next

  • Normal Mapping : 由于Obj格式不带切线数据,还需要自己计算出切线。(如果用Unity,Unity直接就给你切线了,所以自己从零开始撸能学很多东西吧,之前说的顶点法线计算就是)
  • RenderTexture的封装
  • PostProcessing 这个主要是要做个框架出来,可以尝试几种效果
  • Shadow Mapping 这个在很多教程里面很简单就出来效果,但是实际实现的时候很多坑,而且我们需要软阴影。
  • Shader变体:也许某个时刻我觉得必须要实现了,否则会阻碍实现新的效果。但估计会对代码结构调整比较大
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章