渲染流水线(一)

什么是渲染流水线

渲染流水线的工作任务在于由一个三维场景出发、生成(或者说渲染)一张二维图像。换句话说,计算机需要从一系列的顶点数据、纹理等信息出发,把这些信息最终转换成一张人眼可以看到的图像。这个工作通常是由CPU和GPU共同完成的。(unity shader入门精要 冯乐乐 p6)

图出处Kerry佬

为什么要用渲染流水线

可以提高单位时间的生产量,提高生产率。

CPU端具体实现

渲染流水线的起点是CPU,即应用阶段。应用阶段大致可分为下面三个阶段:

  1. 把数据加载到显存中。
  2. 设置渲染状态。
  3. 调用DrawCall

把数据加载到显存中

我们渲染物体往往需要很多信息,这些数据需要从硬盘中加载到系统内存,然后,网格和纹理等信息又被加载到显存中,这样做的原因是因为大部分显卡对于内存没有直接的访问权利,且显卡对于显存的访问更快。 那么这么多数据,是不是所有的数据都是我们需要的呢? 我们知道,我们看到的图像,是在摄像机视锥体范围内的。如下图我们只能看到立方体,看不到猴头。

从这里看,猴头,也就是视锥体外的数据就可以不处理,这样子可以节省性能。 这步叫做视锥体剔除。

那么我们如何判断物体有没有在视锥体内呢?

我们需要判断物体有没有和视锥体相交,可是物体形状千奇百怪,还有些复杂的,那计算量就会很大,此时,往往采用物体的包围盒(bounding box),最常见的包围盒算法有AABB包围盒(Axis-aligned bounding box),包围球(Sphere), 方向包围盒OBB(Oriented bounding box)。

包围盒怎么求呢?

常用的是取所有点中最小的和最大的x,y,z作为包围盒的边界。如下是求三角形的平面包围盒,取得三角形三个点的x,y的最小值和最大值。

c++ 复制代码
// Bounding Box
    int min_x = std::min(v[0].x(), std::min(v[1].x(), v[2].x())), min_y = std::min(v[0].y(), std::min(v[1].y(), v[2].y())), max_x = std::max(v[0].x(), std::max(v[1].x(), v[2].x())), max_y = std::max(v[0].y(), std::max(v[1].y(), v[2].y()));

这块三维引擎往往会帮你处理好。

除了视锥体剔除,还有层级剔除等,层级剔除通过设置摄像机和物体的layer用来控制物体是否剔除。 THREEJS中的层级剔除

现代化图形api比如DX12,vulkan,WebGPU等还会有一个渲染队列,用来控制渲染顺序,来处理透明,不透明,半透明物体的渲染,Opengl的话没有自带,threejs中需要自己设置渲染顺序来达到类似效果。.renderOrder

渲染状态

渲染状态:定义了场景中的网格是怎样被渲染的。 比如顶点着色器,片元着色器,光源属性,材质等。 个人理解是把数据怎么组合。比如给三个mesh,用同一组材质。

调用DrawCall

Draw Call就是一个命令,它的发起方是CPU,接收方是GPU。这个命令仅仅会指向一个需要被渲染的图元列表。给定了一个Draw Call时,GPU就会根据渲染状态和所有输入的顶点数据来进行计算,计算过程就是GPU流水线。

观察视锥体剔除和Drawcall

对比上述两张图,当两个立方体在视锥体内时,drawcall为4,当一个立方体移出视锥体外时,drawcall为3,可见视锥体剔除确实节省了性能。 github链接

相关推荐
Agent世界9 小时前
用 CDP 做发布自动化:四道机器闸门与产物验收
前端·javascript
FungLeo9 小时前
成为全栈·Vue 管理后台篇·编辑器图片上传:从文件选择到文章附件关联
前端·vue.js·编辑器·markdown·文件上传·formdata·附件管理
西伯利亚小火龙9 小时前
我以为是流体解算,结果只是一张贴图:复刻 Lusion 的屏幕流体特效
webgl·three.js
某哈压力大9 小时前
SSH 突然 Connection reset?不是密钥坏了,是 OpenSSL 把 sshd 干趴了
前端·node.js·命令行
程序员大阳9 小时前
副队长ES6+教程(3)--解构赋值
前端·javascript·es6·赋值·解构
神膘护体小月半10 小时前
css - 元素背景图由 hover 触发,初次加载时闪动的解决办法
前端·javascript·css
程序员大阳10 小时前
副队长ES6+教程(2)--let 与 const
前端·javascript·es6·const·let·var
deli00710 小时前
写满 200GB 后 SSD 为什么掉到 95MB/s?SLC 缓存模型实测
前端
曦樂~11 小时前
【Web Development】03JavaScript 基础和事件
开发语言·前端·javascript
deli00711 小时前
HTTPS 的锁是怎么挂上的?TLS 1.3 握手 6 步实测
前端