UE4渲染模块学习笔记

注:转载自知乎文章:https://zhuanlan.zhihu.com/p/57561144
本文仅为个人阅读笔记,归纳整理。

优化的方法论

图形工程师一直在追求渲染质量、性能、功能这三者的平衡。一个空场景性能必然是最佳的,但这没有意义,另一方面若场景都用最高精度的图片或是堆砌各种功能点,游戏卡得根本玩不了,也是不行的。

在图形优化的路上有很多具体的实现,但都可以归纳成以下六点方法论:

1)流水线:并发多线程,使硬件的利用率达到最高;

2)预计算:能事先计算的就尽量事先做,降低Runtime的计算成本,比如静态光的lightmap;

3)局部化:只在可见的局部区域里做事情,比如屏幕空间反射的计算(SSR);

4)先粗后精:先用消耗低的方法缩小计算范围,再用消耗大的方法执行精确计算,比如八叉树遮挡查询;

5)时空互换:用时间换空间或是空间换时间,比如lightmap就是空间换时间的例子;

6)负担转移:使用stat unit查看如果是CPU的瓶颈,又不可进一步优化了,可以考虑将CPU的计算移至GPU计算,如骨骼动画计算可以移至GPU做。

DrawCall Example

所谓drawcall,是指CPU向GPU发出的一次渲染指令,让GPU绘制指定的几何体。
在这里插入图片描述
在这里插入图片描述
CPU会提交六次drawcall,一次天空,一次地面,左侧两个柱子各一次(因为是三个独立的模型),最右侧柱子上下两部分采用了不同的材质,所以需要提交两次渲染信息,这样就多一次drawcall,共计6次drawcall。这张图展示了渲染的顺序,蓝色的是地面,因为事先做了prez,所以为地图上原来柱子的区域留空了没去绘制。

从左到右依次是:渲染地面,渲染右侧柱子的下半截,渲染中间柱子,渲染左侧柱子,渲染右侧柱子的上半截,渲染天空。

渲染顺序也就侧面反映了提交drawcall的次序,其实对于图形工程师而言,不必特别注意drawcall提交次序,只要最终结果是对的就行。不过这里也可以发现一个问题,那就是为啥没有完整地渲染完右侧的柱子,再去渲染中间的呢?那是因为渲染器会把相同材质的对象放到相邻drawcall中处理,这样可以节省让硬件切换渲染状态的耗时。可以注意到这里右侧柱子下半截的材质与其他柱子材质是一样的,所以会放到连续的drawcall中处理,而右侧柱子上半截材质不同,被放到了所有相同材质柱子渲染完成后才进行绘制。

材质应用流程

在这里插入图片描述
.usf模板文件中提供了基础的材质变量和函数,这些不能改变,但同时也把可以变化的代码段留了空,这时开发同学就可以利用材质编辑器,自动将图形化的连线转成HLSL代码插入到.usf文件里(print到.usf中的%s处):
在这里插入图片描述

反射

  • 反射捕获(Reflection Capture)
  • 平面捕获(Planar Reflection)
  • 屏幕空间反射(SSR)

屏幕空间反射(SSR)

待补充

光照

静态光照

  • lightmap存储静态光的直接光分量
  • 采样点存储间接光分量

动态光照

动态阴影

  • 常规动态阴影(Regular Dynamic Shadows)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章