【THREE源码解析篇】THREE中透明物体绘制原理解析

1.WebGL中透明物体绘制原理

1.1开启深度测试和Blend功能

开启深度测试
gl.enable(gl.DEPTH_TEST)
开启混合
gl.enable(gl.BLEND)
指定混合函数
gl.blendFunc(gl.SRC_ALPHA,gl.ONE.MINUS_SRC_ALPHA)

1.2首先绘制所有不透明的物体队列

Three中是在render函数中分类函数遍历将非透明物体和透明服务装入的currentRenderList中

1.3关闭深度写入功能

准备绘制透明物体前的准备工作,先gl.depthMask(false),对应THREE中的材质中的DepthWrite参数为false,主要为了用于透明物体绘制,使得锁定隐藏面消除的深度缓冲区的写入操作,使之只读。

1.4绘制所有半透明的物体

绘制之前应当将透明物体根据深度排序好,然后从后往前绘制,绘制过程中利用之前不透明对象绘制后的深度缓冲区进行深度测试,通过深度测试才会绘制不透明三角面片,具体就要用到Blending相关算法

1.5释放深度缓冲区,使之可读可写

gl.depthMask(true),绘制完透明物体就要开启深度写入功能了,用于下一帧的非透明物体数组的绘制

2.THREE中透明物体绘制相关流程解析

2.1 render函数中的projectObject

用于遍历对象,深度排序,
在这里插入图片描述

2.2 透明和不透明分组

currentRenderList.sort(_opaqueSort, _transparentSort);
此处的currentRenderList是WebGLRenderLists.js的WebGLRenderList对象,sort函数传入透明对象和非透明对象的排序函数规则
在这里插入图片描述
此处非透明函数用默认函数painterSortStable,透明函数排序用reversePainterSortStable
具体非透明函数实现如下图所示

在这里插入图片描述
从非透明排序函数可以看出,排序优先级groupOrder>renderOrder>program.id>material.id>z深度
透明函数排序
在这里插入图片描述
从透明排序函数可以看出,排序优先级groupOrder>renderOrder>z深度

综上,可以知道排序规则,因为非透明和透明是两个渲染队列,因此Order互不影响,只是本身队列可以提高优先级,order默认都是0

2.3 开始渲染

可以看到此处先渲染不透明的,再渲染透明的在这里插入图片描述

2.3.1 renderObjects至renderBufferDirect

在这里插入图片描述

2.3.2 setprogram

var program = setProgram(camera, scene, material, object);此处进行uniform等值的赋值等操作
在这里插入图片描述
在这里插入图片描述
最终将uniforms组装进materialProperties.uniformsList = uniformsList;
在这里插入图片描述

2.3.2 state.setMaterial(material)

在这里插入图片描述

该类在render函数中使用setMaterial方法,读入当前待渲染对象的material,读取材质中的有关深度状态和混合blend等信息。

该类中的DepthBuffer用于管理深度缓冲状态
setTest(true|false) 用于深度测试状态管理
setMask(true|false)用于深度写的状态管理
setFunc(depthFunc枚举)用于深度缓冲规则的确认,一般默认即可

此处开始进入正题,研究threejs对透明物体的渲染状态处理

在这里插入图片描述

2.3.3 renderer.render(drawStart, drawCount);

进行最终的绘制
在这里插入图片描述

3 透明材质正确打开方式

3.1 transparent

在场景中,绘制transparent必须要打开,否则会将该对象默认分类到非透明渲染队列

3.2depthWirte

在材质中的depthWrite用于深度写的状态控制,depthTest用于深度测试状态控制,默认打开即可,通常情况下绘制透明物体在配置透明属性外还需要关闭depthWrite

(2020-3-26)近期较忙,暂记录待后续补充…

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值