技术美术TA面试题汇总

1. 渲染分几个阶段?
渲染3个阶段:应用阶段.几何阶段.光栅化阶段.
应用阶段:由CPU处理。把视野外的物体剔除掉,然后设置要渲染的状态(材质纹理、纹理、Shader等),然后把图元(点、线、三角面)传递到几何阶段。
几何阶段:由GPU处理。处理传来的顶点和三角面。这个阶段重要任务就是把模型坐标转换到屏幕坐标。这一阶段会输出屏幕空间的二维顶点坐标、顶点的深度值、颜色等相关属性。
光栅化阶段:由GPU处理。图元所包含的像素进行处理。然后哪些像素要被输出到屏幕上。
2. 什么是DrawCall?
CPU设置好了渲染状态,然后告诉GPU要渲染什么。这一告诉的阶段被称之为DrawCall。
3. GPU渲染的过程?
顶点数据->顶点着色器->曲面细分->几何处理->裁剪->屏幕映射->三角形设置->三角形遍历->片元着色器->逐片元操作->打印屏幕图像
顶点着色器:可完全编程。最主要的是把模型空间的位置转换到裁剪空间。同时处理顶点颜色。
曲面细分:可完全编程。这个阶段细分图元用的。比如实现LOD效果,加顶点实现更细节的动画,用低模加细分在运行的时候实现高模效果。
曲面细分详细分为三个阶段。Hull Shader Stage、Tessellator Stage、Domain Shader Stage。
Hull Shader Stage基本是配置的。告诉第二个阶段(Tess)要怎么细分。比如用是用三角形,还是四边形细分。细分的每个边有分成几个点。
Tessellator Stage是自动完成的。通过HS配置的数据,利用重心坐标系、贝赛尔曲线等生成新的面。
Domain Shader Stage是处理新产生的面。比如设置它们的Normal之类的。
几何着色器。是完全可编程的。在顶点着色器阶段我们不能得知顶点和顶点的关系,但是在几何着色器可以。几何着色器主要是添加或者减少图元。
裁剪阶段。是只能配置的。在裁剪坐标系(其次坐标系)下裁减掉不再视野外的图元。如果一个图元一半在视野内,一半在视野外。则会裁剪掉视野外的然后添加新的顶点完成。比如实现双面效果,我们可以用两个Pass 分别Cull Front Cull Back来实现。
屏幕映射:不能配置和编程。即每个图元的X和Y坐标转换到二维的屏幕坐标系。坐标跟分辨率有关。OpenGL和DirectX的顶点和方向不一样,需要用UV_STARTS_AT_TOP宏来判断。
三角形设置:不能配置和编程。计算三角网格表示数据的过程。
三角遍历:不能配置和编程。一个三角形所覆盖的片元情况。此时片元还不是真正的像素。
片元着色器:可完全变成。进行片元的效果处理。
逐片元操作:只能配置。先进行测试工作,比如模版测试->深度测试->透明测试。如果通过所有测试还要进行颜色混合。当然如果没有透明的话片元测试会在片元着色器前面。最后输出像素到颜色缓冲区。
屏幕映射:利用双重缓冲技术,把颜色打印到屏幕上。
4. CommandBuffer是什么做什么用?
可以利用指令渲染一些东西,不用摄像机。比如直接在一个RT用指令渲染一个人。
5. 也可以用CommandBuffer和GrabPass?
GrabPass和CommandBuffer 都可以进行捕捉。GrabPass只有在每帧第一次的时候进行捕捉,CommandBuffer可以每帧多次捕捉。
6. 人物描边的几种做法?
一.屏幕后处理方法。先用获取深度图,再比较点和周围八个点的Normal和Depth是否大于一定的阀值,如果是则是边,添加颜色。
二.视角和法线的点积,进行描边。
三.写两个Pass, 然后第一个pass的顶点根据法线外移一定的量进行描边。
7. 屏幕模糊处理?
一.压缩像素模糊。获取屏幕图片,然后放在低像素的RT进行压缩,再放回到原像素。
二.快速模糊。获取屏幕图片,像素点取周围4或8个点的颜色累加,然后再除以4或8。
三.卷积核模糊(高斯模糊)。获取屏幕图片,按照周围的点用一定的卷积核(按权系数)进行平均颜色。
四.运动模糊1。储存多帧图片。图片按权融合作为最后的屏幕图片。
五.运动模糊2。获取上一帧和当前帧的深度纹理。建立当前片元的NDC。当前的世界坐标*上一帧的VP再除以上一帧的齐次坐标的w,得到上一帧数的lastNDC,再lastNDC-ndc=>speed,沿speed方向进行多次采样。作为颜色,
六.深度模糊(景深DOF)。获取深度图,深度大于一定的阀值取周围点进行模糊。
8. Bloom的做法?
在C#中OnRenderImage中获取当前屏幕图片,然后用Luminance(光亮度,即RGB*一定系数)的方法找出曝光区域,曝光区域进行模糊处理,最后和原图叠加。
9. Glow的做法?
一.在C#中利用Shader的RenderType 用RenderWithShader 替换要发亮的Shader 然后再在C#中进混合。
二.利用CommandBuffer提前把人物渲染进行混合。
三.如果人物的Alpha通道没有用则可以利用Alpha通道进行发光处理。
10. FXAA的做法?
先用Depth和Normal进行识别边缘,在判断哪个边缘的方向需要补齐,再取周围的点进行混合。
11. Fog的做法?
一.利用深度图,像素点和Fog的深度进行比较,然后乘一定的灰度值。
二.利用Unity_Fog 的方法,Unity_CALC_FOG_FACTOR_RAW(CameraWorldPos-ObjectWorldPos)来实现Fog.
12. 实现降低亮度的感觉?
颜色输入,通过卷积核进行颜色校正,实现暗的感觉。
13. HDR?
通过色调映射,将原来的颜色进行映射处理得到新的颜色。
14. ShadowMap的实现?
一.在灯的位置用相机渲染一个LightMode 为ShadowCaster Pass通道来得到可投射阴影的光源的阴影映射纹理以及摄像机的深度纹理,利用这两个纹理来得到屏幕空间的阴影图,如果摄像机的深度图中记录的表面深度大于转换到阴影映射纹理中的深度值,则说明该表面是可见的但是却处于阴影当中。
二.接受阴影直接用Unity 的Shadow_Coords、Transfer_Shadow和 Shadow_Attenuation。光照衰减用Unity_Light_Attenuation
15. BRDF的参数?
BRDF(Albedo(基础颜色),Spec(反射颜色),OneMinusRefl,Smoothness(光滑度),WorldNormal,WorldViewDir,UnityLight(光颜,光方向,物体法线和光的点积(NDOTL)),
UnityIndirect(漫反射,镜面反射)。
16. BRDF 漫反射公式?
Disney BRDF F->菲尼尔 D->法线 G->阴影遮挡
17. 延迟渲染GBUFFER参数。
GBufer.0.rgb=albedo
GBufer.0.a=occlusion
GBuffer.1.rgb=spec Color
GBuffer.1.a=smooth
GBuffer.2=normal
GBuffer.3=emission color
18. UI的原理?
Mesh组成,即面片。然后将UI图片渲染在上面。
19. 九宫格UI的原理?
Mesh 的顶点拉伸。
20. UI的描边?
即复制UI的顶点外移。
21. RectMas2D和 Mask 的区别?
RectMask2D不会合批,如果只有一个MASK 优先使用。Mask 多个内部会合批,但是不会和外部的合批,2个以上建议用。
22. ETC压缩的原理的和比例?
ETC1将图片分为4x4的块来压缩,由4x4x24=384bit压缩为64bit,压缩倍率为6。对像素块的颜色进行编码,修改像素块的亮度得到最终纹理。
23. 延迟渲染和正向渲染的区别?
正向渲染先着色计算,再深度测试。光数量为n物体数量为m,复杂度n*m。
延迟渲染先深度测试,在着色计算。光数量为n物体数量为m,复杂度n+m。
延迟渲染渲染的优势:就是把光源数目和场景数目分开了所以复杂度低,
只渲染可见的像素节省计算量,用更少的Shader,对后处理支持良好,在大量光源的场景尤为明显。
延迟渲染缺点:内存开销大,GBuffer读写的性能瓶颈,透明物体存在问题渲染需要结合正向渲染,对MSAA抗锯齿支持不好。
24. 如何降低GC?
一.频繁使用的临时变量提升为成员变量
二.共享的成员提升为静态变量(单例化)
三.GC大的函数尽量绕过去(切换场景执行GC.Collect)
四.使用合理的数据结构(Struct Class out ref)
五.使用合理的复用策略,减少new Object(ObjectPool,StringBuilder)
六.减少设计的耦合防止循环引用(桥接模式)
25. UI渲染的优化?
一.UI减少DC用图集(2的幂整数),也可以动态生成图集
二.图片尽量别重叠。
三.Z值为0可以减少DC。
四.动静分离(细分Canvas拆分UIPlanes)。
五.不可见的设置Size为0或者设置Layer不可见,别SetActive。
六.关闭UI的Mipmap,减少内存开销
七.不透明UI,顶点数量换像素减少Over Draw开销
八.视野外的不一定会剔除(会有DC),建议手动不可见
九.减少特效字体(颜色、渐变、内容频繁更改(会导致频繁渲染)),Rich Text
十.不要用空纹理Image来增加触碰范围,会增加DC,OverDraw,用Empty4Raycast 代替
26. 场景的优化?
一.少动态光和物体顶点,一些曲面棱角用法线图代替。
二.不透明物体减少DC,减少材质数量,减少面片(开销DC>材质数量>面片)
三.Combine 一些小的Mesh。
四.Static Batching、Dynamic Batching 、GPU Instance 渲染合批
五.设置视野距离、ShadowDistance、ShadowMap质量(开销高>中约等于低) 。
六.LOD,甚至远处直接用面片。
七.使用剔除组
八.开启多线程渲染,但是会增加不透明和UI的渲染开销
九.现在的手机分辨率高,可以降低分辨率来提高Frag Shader,同时降低我们开的RT的分辨率来提高效率
十.地形和多贴图的PBR材质用Texture2DArray(降低glbindTexture)
27. 粒子和动画优化?
一.减少粒子系数数量和粒子数量(开销粒子系统数量>粒子数量)
二.粒子使用让粒子处于调用Play去播放 而不是 setactive
三.使用粒子池
四.多粒子系统可用一套图集
五.调节动画误差值、浮点精度可以适当调节大来减少包占用
六.视野外的Visible不播放动画
七.通过贴图来完成顶点动画
28.HSR?
隐藏表面消除(Hidden-surface removal):Early-Z技术。是指消除实体物体被其他物体所遮挡的那部分(隐藏直线消除与此类似,有用线性模型);实现隐藏表面消除的最简单方法是使用深度缓冲区(又称z缓冲区)。深度缓冲区原理是把一个距离观察平面(通常是近侧裁剪平面)的深度值或者距离与窗口中的每个元素相关联。
29.FPK?
FPK 是 Forward pixel kill(FPK) 即arm mali gpu中的一种隐藏面消除方法。
对于不透明的物体,当按照从后往的次序渲染的时,可以改善性能。
与Earyly zs test 的区别是 , Early-ZS 从前往后的次序渲染可以kill 掉 overdraw 。
但是实际情况不一定都是前往后,所以设计了FPK与Early-ZS提高GPU的性能
一句话总结:FPK 是 作用在安卓ARM GPU下的,针对于不透明物体,在从后往前渲染下的一种隐藏面消除方法,用于改善性能。Early ZS Test 是从前往后渲染的kill overdraw来提高性能的方法。FPK 与 Early ZS 互补提高GPU性能。
触发FPK的条件:必须通过Early ZS Test 并做了Early ZS Buffer 更新的fragment才可以Kill 其他的fragment.每个fragment有两个状态To Kill(Kill 别的Fragment) To Be Kill(被别的Fragment Kill)只有当前被标记成To KIll ,然后后进入FIFO队列,这样就能Kill 前面的To be Kill Fragment。
作用方法:标记成To Kill 的fragment 后进入FIFO 队列 杀死前面的To be Kill Fragment。
30.GPU的IMR和TBR?
IMR(immediate mode rendering):用于桌面(PC)的GPU的渲染模式。对于每一个draw call,vertex shading做完拼成图元后直接做fragment shading,pipeline不会中断执行。
IMR优点:架构简单,顶点输出结构经过裁剪等直接进入片元。这样不用额外的内存来储存中间结果,并且节省写出、读入的内存带宽。
IMR缺点:如果先渲染远的,再渲染近的,被近的遮挡会产生无效渲染。
TBR(tile based rendering):TBR是指对于一个FBO(帧缓冲), 将其拆成许多小的tile,先执行所有draw call的vertex shading,拼装成相应的图元后,接着对于每一个tile,各用一张链表(polygon list)来记录位于该tile中的图元;然后对于每一个tile中的每一个图元进行光栅化和fragment shading。
TBR优点:一、节省带宽,将FBO拆分成小Tile,这样内存中储存的就是很多个小Tile来保存渲染结果,可以用片内Memory来储存,片内Memory的优势是访问速度快。二、FBO的vertex shading完了之后,可以知道每个drawcall物体的相对位置,可以用Early ZS Test 和 FPK 来Kill 掉不必要的Fragment,减少不必要的运算。
TBR缺点:一、Vertex shading的计算结果以及每个tile和triangle list需要存到物理内存。Fragment Shading又要从物理内存里面读回。所以需要额外的储存空间和执行效率。随着模型复杂度的增加,缺点逐渐增强。二、一帧数里面有>=2的渲染,且后面渲染需要前面渲染的结果. TBR需要所有的图元执行完毕之后再执行frag,因为>=2的渲染,这时候后面的draw命令需要前面的渲染生成结果,那么不得不要求GPU把缓存的draw都执行完毕,然后放弃当前的缓存内容.极端的时候,每次draw都需要前面的渲染结果,TBR直接退化成IMR