引言 :
学习webgl已经接近2年时间了,对常见的开源3D引擎也比较熟悉了,但是目前为止three.js、babyLon、clayGL、cesium对webgl2新特性的支持也不是特别多。从今天开始,准备着手构建自己的3D引擎,一是希望能有自我提升,二是希望能做一个更快速、更炫酷、更容易扩展的引擎,并且希望能对webgl2的新特性有更多的支持。(目前引擎设计主要参考three.js和clayGL、少部分可能会参考babylon、如果后续做地球部分应该会参考cesium,由于对playCanvas使用不多,后续在引擎设计的时候也会着重去看playCanvas的源码并将好的思想融入进来。总而言之,在设计引擎的过程中自己多思考,然后多看这些开源引擎的思路,取其精华)

  1. 首先介绍下几个开源引擎:

Three.js
https://github.com/mrdoob/three.js
最火的web3D引擎,功能最丰富而且最便于使用,笔者对其的研究比较深入,上层的一些设计可能会对其参考较多

ClayGL
https://github.com/pissang/claygl
ClayGL是一个用于构建可扩展Web3D应用程序的WebGL图形库,目前主要应用到echarts中,笔者对其比较熟悉,后续对它的一些分析可能会比较多

Babylon.js
https://github.com/BabylonJS/Babylon.js
一个完整的JavaScript框架,用于构建HTML5,WebGL,WebVR和Web Audio的3D游戏和体验,该引擎主要使用typescript,性能强大,对webgl2支持较多

Cesium.js
https://github.com/CesiumGS/cesium
一个3D地球引擎,主要是解决地球上的一些计算和大尺度问题,后续做地球可以参考

PlayCanvas
https://github.com/playcanvas/engine
PlayCanvas是一个开源游戏引擎。目前对其使用不多。它是ECS架构,架构比较清晰,渲染列表的标脏处理的不错。

2.搭建工具和语言:

要着手做自己的引擎,首先要构建一套打包工具,我这里使用webpack+gulp+eslint进行构建。由于对typescript不太熟悉,目前还是主要使用es6的语法(后续会逐步适应typescript)。用构建工具构建项目的过程比较简单,这里就不一一记录了。

3.架构和渲染设计:

该如何设计一个架构:我们先看一下three做了什么?
其实只干了两件事
Graph Tree 场景树管理
Render 渲染

如何构建场景树:我们看看three的设计思路:

Render渲染
首先反思一下Three.js,three在渲染上有什么改进空间?
答:对Three比较熟悉的人应该知道,Three的最大痛点就是Renderer的设计包含了太多东西:
更新场景中所有物体的矩阵
生成渲染列表(分类,收集, 视锥裁剪,排序…)
更新灯光信息
执行渲染

Three在renderer中做了太多的事情,这确实不是太合适,主要是为了让用户更加容易使用吧,但是这个设计确实也带来了很多扩展和性能上的问题。
这样设计使其在实现VAO、UniformBlock、MRT这些关键技术的时候带来了极大的困难,现在也没有实现这几个非常关键的技术,这其实才是最大的痛点。
而一个引擎是否强大的核心是有没有强大的延迟渲染系统,显然Three不具备,我们看看为什么?

后期和延迟渲染经常会遇到的场景:
一般在后处理的时候我们希望替换某些物体的材质为材质1,替换另一些物体的材质为材质2,也就是常用的scheme策略
graph LR
场景–>物体
物体–>材质1
物体–>材质2

如果要用Three.js要如何实现那?
scene.traverse(object => {
// change material1
});

renderer.render(scene, camera, target);

scene.traverse(object => {
// change material2
});

renderer.render(scene, camera, target);

// …

实际上:
1.遍历场景替换材质1(遍历浪费)
2.更新场景中所有物体的矩阵
3.生成渲染列表(分类,收集, 视锥裁剪,排序…)
4.执行渲染
5.遍历场景替换材质2(遍历浪费)
6.更新场景中所有物体的矩阵(浪费)
7.生成渲染列表(分类,收集, 视锥裁剪,排序…)(浪费)
8.执行渲染
9…
(参考shawn0326的文章https://juejin.im/post/5e5dbe23e51d4526f363b123)

所以我们在实现Render的时候,希望render能只专注于渲染,而且为了后处理,我们希望render在渲染之前用户可以自定义自己的材质,默认使用MRT
scene.updateMatrix();//将更新矩阵移出renderer,可以手动更新

const renderList = renderer.getRenderList(scene, camera);//获取渲染列表,将渲染列表的获取分离出来

const light = renderer.getLight();//灯光信息单独处理,生成uniformBlock
renderer.renderBackground(scene);//单独渲染背景
// 渲染渲染列表
renderer.renderRenderList(renderList, camera, light, {
getMaterial: item => {
// 这里可以通过item.object动态判断使用哪种材质
return material1;
}
});
//当然我们也提供一个直接的render函数,便于用户使用,该render直接调用上述几个接口组装在一起
renderer.render(scene, camera);

实际上:
1.更新场景树
2.生成渲染列表(分类,收集, 视锥裁剪,排序…)
3.更新并计算灯光和阴影
4.渲染背景
5.使用材质1渲染
目前这样设计思路非常明确,用户可以更加灵活的使用renderer,并以更加优化的方式实现自己的延迟渲染策略。后续还应该思考如何内置一个更加方便的延迟渲染策略以及MRT。
当然渲染这块在实现的时候我会使用VAO和uniformBlock,后续在实现渲染之后再详细说明思路和好的设计方式。

4.矩阵运算设计

矩阵运算的设计:这部分是我们要关注的重点,仔细看了下three的设计,矩阵运算这部分的设计是直接使用数组进行计算的,这种设计不是太理想。为什么那?因为后续很难将矩阵运算移植到webAssembly,而且还有很多的js对象和数组的创建,内存开销也不小。
因此我设计的引擎需要摒弃这种思路,希望后续能更好更快的切换到webAssembly。目前矩阵运算主要借助gl-matrix库(https://github.com/toji/gl-matrix),这个库比较简单轻量而且是直接使用并得到内存数组。接口调用完成可以直接上传uniform,非常方便快捷。
想要让引擎更加快速简单,我还是希望使用dirty机制来触发引擎的更新,特别是矩阵运算的时候。如果你做了position、rotation包括灯光的修改,我希望能有个好的机制直接触发引擎的更新,这样就不用每帧去更新和计算这些参数,能给引擎带来更好的性能。

5.上游工具

第一步先支持gltf以及一些gltf的扩展吧。目前大部分工具都可以导出到gltf。后续希望能实现更加强大的粒子系统和编辑器。

从零开始构建自己的WebGL3D引擎---思考与设计相关推荐

  1. Unity从零开始构建能力体系 Unity Ability System

    从零开始构建能力体系 你会学到什么 如何实施能力体系 如何使用用户界面工具包创建用户界面 如何使用Unity的GraphView API 如何实现保存系统 MP4 |视频:h264,1280×720 ...

  2. 万字干货:如何从零开始构建企业级推荐系统?

    「免费学习 60+ 节公开课:投票页面,点击讲师头像」 作者丨gongyouliu 编辑丨zandy 来源 | 大数据与人工智能(ID: ai-big-data) 最近几个月有很多人咨询作者怎么从零开 ...

  3. 从零开始构建企业级推荐系统

    作者丨gongyouliu 编辑丨zandy 这是作者的第26篇文章,约1.2w字,阅读需60分钟 最近几个月有很多人咨询作者怎么从零开始搭建工业级推荐系统,有做音视频的.有做新闻资讯的.有做在线教育 ...

  4. 使用ThreeJs从零开始构建3D智能仓库——第四章(添加动画及库区)

    使用ThreeJs从零开始构建3D智能仓库--第四章 写在前面 使用TweenJS创建补间动画 TweenJS简介 开关门动画的实现 添加库区与文字 结束语 写在前面 本章我们来探索下如何添加补间动画 ...

  5. 从0到1 构建实时音视频引擎

    最近几年,实时音视频领域越来越热,今年的疫情更是"火上浇油"了一把.网易智企旗下产品网易云信在实时音视频领域深耕多年,积累了不少实践经验.在本文里,笔者将以烹饪为比喻,深入浅出地将 ...

  6. 技术系列课|从0到1 构建实时音视频引擎

    随着5G和AI时代的到来,在线实时互动在越来越多的场景中被使用,支撑这一功能实现的关键性技术--RTC也受到了空前的关注.本节技术系列课,来自网易云信的讲师将以做菜的过程为比喻,深入浅出地讲述如何从0 ...

  7. 从零开始构建一个的asp.net Core 项目(一)

    最近突发奇想,想从零开始构建一个Core的MVC项目,于是开始了构建过程. 首先我们添加一个空的CORE下的MVC项目,创建完成之后我们运行一下(Ctrl +F5).我们会在页面上看到"He ...

  8. 使用PyTorch从零开始构建Elman循环神经网络

    摘要: 循环神经网络是如何工作的?如何构建一个Elman循环神经网络?在这里,教你手把手创建一个Elman循环神经网络进行简单的序列预测. 本文以最简单的RNNs模型为例:Elman循环神经网络,讲述 ...

  9. 从零开始构建自己的爬虫代理IP数据库并定期检验IP有效性...

    ProxyIPPool 从零开始构建自己的代理IP池:根据代理IP网址抓取新的代理IP:对历史代理IP有效性验证 源码地址:https://github.com/TOMO-CAT/ProxyIPPoo ...

最新文章

  1. [原创]安装Ubuntu Server 14.04后
  2. matlab dsp实验报告,matlab实验报告14.pdf
  3. POJ1523:SPF(无向连通图求割点)
  4. 如何处理My lead fiori应用的buffer问题
  5. Python 生成器 迭代器
  6. Hadoop生态Flume(四)拦截器(Interceptor)介绍与使用(2)
  7. pytorch模型加载测试_pytorch模型加载方法汇总
  8. C# 导入CSV文件,导出到CSV文件
  9. Docker简介和安装
  10. ZENG msgbox仿qq提示
  11. 从零开始系类——模拟电子技术
  12. qt Android 基站定位,AT指令获取基站信息
  13. Facebook 上传小游戏流程
  14. JUC学习之共享模型之工具上之线程池浅学
  15. 一个并肩战斗的同事将离开团队,去家乡追寻梦想
  16. 【毕业设计】单片机智能鱼缸系统 - 嵌入式 物联网 stm32
  17. 马尔可夫决策过程和贝尔曼方程
  18. 最新阿里云国际版支付方式以及注册教程和方法
  19. Xamarin.Android之绑定库教程
  20. 十分钟开发出神经网络五子棋

热门文章

  1. IDEA的下载及安装
  2. Fio 命令生产环境测试
  3. 一次由图片引起的致命崩溃问题
  4. 刷车机器人_各位车主注意了!这样的洗车很伤爱车!99%的人都不知道!
  5. 查看linux版本的命令
  6. 英语学习笔记(一)语法
  7. Substrate是什么,为什么要选择Substrate
  8. diagrams 一个完全可以代替visio的软件
  9. 一道技术美术的面试题
  10. spin_lock spin_lock_irq spin_lock_irqsave、spin_lock_bh