如何构建一个面向对象的webgl渲染引擎

techbrood 发表于 2019-07-19 18:25:30

标签: webgl, engine, architecture

- +

WebGL渲染引擎主流的有three.js和babylon.js,

如果我们要自己实现一个类似的引擎,该如何设计实现呢?

基本上我们可以分解为以下5个部分:

  1. webgl渲染部分的封装

  2. 可渲染实例的抽象

  3. 光照和相机

  4. 场景和资源管理

  5. 常用的图形运算库

其中第1部分主要是整合绘制方面的一些对象,比如webgl渲染上下文(WebGL2RenderingContext),shader相关的一些对象(shader program、vertex shader、fragement shader、attributes、uniforms),以及和渲染有关的一些全局变量设置(global变量)和宏定义(macros)。我们可以把这部分视为面向画布的“画笔”对象。


第2部分一般又包含如下几个组成:

  1. 几何模型或者导入的三维模型数据,需要支持fbx、dae、gltf等主流数据格式;

  2. 材质、贴图、自定义的一些变换动画

  3. 附着在该对象上的一些控制或特效组件

第2部分的渲染,可以通过给具体的渲染实例(Render Instance)传递“画笔”对象(比如取名为shader),来调用实例具体的绘制实现(比如取名为render)方法,其基本过程就是通过shader里面设定的变量和程序来绘制模型的顶点数据(顶点数据包含顶点坐标、颜色color和法向量normal),在GPU上执行shader program,本质上还是使用webgl的drawArray或drawElements API来实际完成。


第3部分是设置3D场景可见性的核心对象,有光照我们才能看见物体,有了相机才可以确定以何种方式(距离、角度、范围)来观看场景。

对于光照和相机都会出现物体遮挡的情况,光照的遮挡产生阴影,我们预先生成阴影贴图(shadowmap)来处理,相机的遮挡出现基于深度的裁剪,我们预先生成深度贴图(depthmap)来处理。


第4部分是3D场景的管理,通常以场景树(Scene Tree)的方式来管理3D场景中所有的对象,每个节点(Scene Node)上可以加载可渲染的实体组件或者一些用于控制的组件(Component),通过组件的方式我们可以解耦和实体的表现和实体的控制,并使得功能在场景节点之间得到很好的复用。场景节点之间的位置关系是相对关系。场景中加载的所有资源,需要进行统一管理(注册、查询、销毁以及序列化和反序列化)。整个场景的渲染以及编辑修改动作,我们可以触发一些关键的事件,以让组件能对这些事件做出响应,比如一个afterRender事件,我们的组件可以侦听场景的这个事件,并在发生这个事件的时候,做一个后置处理,实现一些特效(Post Effects)。


第5部分是和计算机图形学相关的一些工具库,比如2维向量(vec2)、3维向量(vec3)、4维向量(vec4)的运算,矩阵(matrix)的运算,常用变换(平移、旋转、缩放)等、四元数(quaternion)和欧拉角及相互转换等等。


可参考的整体架构图如下:

image.png

possitive(12) views4850 comments0

发送私信

最新评论

请先 登录 再评论.
相关文章