渲染流水线(一)

什么是渲染流水线

渲染流水线的工作任务在于由一个三维场景出发、生成(或者说渲染)一张二维图像。换句话说,计算机需要从一系列的顶点数据、纹理等信息出发,把这些信息最终转换成一张人眼可以看到的图像。这个工作通常是由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链接

相关推荐
山有木兮木有枝_15 分钟前
JavaScript 设计模式--单例模式
前端·javascript·代码规范
一大树29 分钟前
Vue3 开发必备:20 个实用技巧
前端·vue.js
颜渊呐34 分钟前
uniapp中APPwebview与网页的双向通信
前端·uni-app
10年前端老司机1 小时前
React 受控组件和非受控组件区别和使用场景
前端·javascript·react.js
夏晚星1 小时前
vue实现微信聊天emoji表情
前端·javascript
停止重构1 小时前
【方案】前端UI布局的绝技,响应式布局,多端适配
前端·网页布局·响应式布局·grid布局·网页适配多端
極光未晚1 小时前
TypeScript在前端项目中的那些事儿:不止于类型的守护者
前端·javascript·typescript
ze_juejin1 小时前
Vue3 + Vite + Ant Design Vue + Axios + Pinia 脚手架搭建
前端·vue.js
lichenyang4531 小时前
React项目(移动app)
前端
用户61848240219511 小时前
Vue-library-start,一个基于Vite的vue组件库开发模板
前端