游戏客户端相关-一些面经-图形学(记录向)

不一定准确,记录向,记录一哈看过的游戏客户端开发的图形学面经,如有错误可以在评论区指出

从自己的wolai粘过来的,可能格式有点混乱

  • 渲染管线

  • 光栅化

    光栅化(Rasterzation) 在裁切后,顶点会投影到屏幕坐标。概念性的有以下5个执行步骤:

    插值(Interpolate),大部分计算如:顶点级别的纹理坐标、颜色、法线都要在着色前计算好。 深度测试(Depth test),剔除掉被遮住的像素。这里计算也可能是在着色后计算。 着色(Shader):为像素计算颜色。一般先光照后雾化,输出的颜色包含透明值,即RGBA。 透明测试(Alpha test),丢弃过度透明的物体。有透明的物体不需要写入深度缓冲。 写入(Write),通过深度和透明测试的像素,会更新帧缓存和深度缓冲。深度缓存用新值直接替换旧值。帧缓存没有开启混合,则可直接替换,否则需要用alpha值混合。

  • 背面剔除

    移除没有面对这镜头的三角形,只考虑三角形与摄像机的相对位置而不依赖与摄像机朝向。依靠三角形顶点顺序直接判断法向量方向(左手法则)。

    顺时针法向量朝外,逆时针朝内,剔除。

  • unity渲染过程

    1)CPU检查场景中每个对象,决定他们是否应该被渲染。(这些对象只有满足一定的条件才会被渲染。)

    2)CPU收集即将被渲染的对象信息,并把这些信息分类为渲染指令(也就是draw calls,我们在之前的文章中也有提到,Draw Call实际上就是一个命令)。一个draw call包含网格数据以及网格如何被渲染。在某些场景,共享设置的一些对象可能会被合并为一个draw call。合并不同对象的数据到同一个draw call被称作batching。

    3)CPU给每个draw call创建一个数据包,称为batch。每一个batch必须包含一个draw call

    4)CPU会发出指令,使GPU改变一些渲染状态。这个指令被称为SetPass call。SetPass call通知GPU,如何去渲染下一个网格。只有在渲染下一个网格时,其渲染状态相对于渲染上一个网格发生了变化时,才会调用SetPass call。

    5)CPU把draw call发送给GPU。draw call通知GPU使用最近的SetPass call去渲染指定的网格。

    6)有时,batch可能需要不止一个的pass。pass是shader代码的一部分,而新的pass需要改变渲染状态。对于batch中的每个pass,CPU必须发送一个新的SetPass call然后必须要再次发送draw call。

    7)GPU按照CPU发送的指令顺序处理这些指令

    如果当前任务是SetPass call,那么GPU更新渲染状态。

    如果当前任务是draw call,那么GPU渲染网格。渲染网格发生在很多阶段,不同阶段的shader代码可以定义渲染。其中:顶点着色器vertex shader告诉GPU怎么处理网格的顶点。片元着色器fragment shader告诉GPU怎么绘制单独的像素。

    10)以上过程会重复执行,直到所有CPU发送的任务都被GPU完成。

  • z-fighting 

    让各模型渲染结果不要在同一个像素出现相同深度值 人为设置渲染顺序

  • 阴影

    1. 实时渲染中,使用的是ShadowMap技术,原理是把摄像机的位置放在与光源重合位置上,摄像机看不到的地方就是该光源的阴影区。在前向渲染中,当最重要的平行光开启了阴影,unity会为这光源计算出它的阴影映射纹理(深度图),记录的是该光源的位置能看到的场景中距离它最近的表面位置(深度信息)。调用LightMode为ShadowCaster的Pass得到阴影映射纹理。
    2. 当使用了屏幕空间的阴影映射技术,是延迟渲染中产出阴影的方法。调用LightMode为ShadowCaster的Pass得到可投射阴影的光源的阴影映射纹理和摄像机的深度纹理。然后根据这两张纹理得到屏幕空间的阴影图。
  • 复杂场景怎么做优化

    • **降低SetPass:**发送命令到GPU花费时间过长是引起CPU限制的最常见的原因,其最耗时的操作是SetPass call。如果CPU限制是由发送命令到GPU引起的,那么降低SetPass的数量通常是最好的改善性能的方式。

    • Occlusion Culling(遮挡剔除)

    • 摄像机Clipping Planes:Far裁剪远端,从而降低摄像机的绘制范围

    • 减少渲染对象的渲染次数

      1.Lightmap(光照贴图)

      2.阴影

      3.反射探头

    • 合并要渲染的对象的数据

      • 静态批处理

        静态批处理时,其网格会合并,这也是进行静态批处理的一个重要过程,我们需要他们使用同一个网格同一个材质。静态批处理没动态批处理的诸多限制,且不会造成CPU损耗,但会有更高的内存占用。
        使用静态批处理时,只需要同一个材质且批处理的物体处于静态,同时勾上Static。

      • 纹理图集

    • GPU渲染优化

      • 优化GPU渲染问题主要从三个方面来进行,分别是顶点,填充,带宽。我们需要明确这三个方面的概念。
      1. 纹理压缩

      2. Mipmap

        模型的贴图会根据摄像机距离模型的远近而调整不同质量的贴图显示

      3. LOD

  • Early-Z

    • Early-z就是提前在片元着色器前进行深度测试,而后面就不需要进行深度测试,把后面的步骤省略了,不让片元白白渲染,解决过多不必要的片元计算

      • early-z 什么情况失效?
        1. 开启Alpha Test 或 clip/discard 等手动丢弃片元操作
        2. 手动修改GPU插值得到的深度
        3. 开启Alpha Blend(Zwrite off)
        4. 关闭深度测试Depth Test
    • Z-PrePass

      方式1:双Pass法

      这样就不需要cpu的排序了,当然这个pass之前也会有Early-z阶段,提升一点效率。当然一个物体有多个pass会带来动态批处理的问题,drawCall的问题

      方式2:提前分离的PrePass

      仍然使用两个Pass,但:

      1. 在第一个Pass即Z-Prepass中仅仅只写入深度,不计算输出任何颜色,
      2. 在第二个Pass中关闭深度写入,并且将深度比较函数设置为相等
      3. 将原先第一个Pass(即Z-Prepass)单独分离出来为单独一个Shader,并先使用这个Shader将整个场景的Opaque的物体渲染一遍。
      4. 而原先材质只剩下原先的第二个Pass,仍然关闭深度写入,并且将深度比较函数设置为相等。
  • 模板测试Stencil Test

    利用模板测试,我们可以将物体只渲染在指定的区域(超出区域外的部分将被剔除)

    拿当前像素对应的Stencil Buffer里的值(StencilBufferValue)与StencilRef作比较的一个操作,然后根据比较的结果来判断是否通过测试,通过测试则保留当前像素,否则则丢弃

    该三角形也覆盖了6个像素(如图),当它们到了模板测试阶段的时候,由于此时的模板比较函数为EQUAL,且StencilRef为1,因此只有①③④这三个像素可以通过模板测试(它们的StencilBufferValue为1),而②⑤⑥无法通过,直接被丢弃。同样假设深度测试通过,那么①③④的PS结果最终会被更新到Back Buffer上,得到结果如下:

  • 延迟渲染

    是将着色计算延迟到深度测试之后进行处理。

    这种方法的主要优势在于将光源的数目和场景中物体的数目在复杂度层面上完全分开,使得渲染拥有成百上千光源的场景的同时依然保持较高的帧率。此外,延迟渲染还能节省计算量,因为它只渲染可见的像素,并且对后处理支持良好

    GBuffer阶段光照阶段

    1. 执行一个GBuffer Pass,通过多目标渲染(Multiple Render Targets,MRT)技术,将最终会显示到屏幕上的像素的颜色(BaseColor)、深度(Depth)、法线(Normal)等信息写入多个RT/纹理中,这些纹理组成了GBuffer。
    2. 执行Lighting Pass,逐像素分别从GBuffer的纹理中取出需要的信息,运行像素着色器计算出最终的颜色缓冲进行显示。
    • 延迟渲染怎么做MSAA?
  • 点乘和叉乘在渲染管线的应用()

    • 点乘:

      求两个向量的夹角

      求投影

      比较两个向量的接近程度(方向上)

    • 叉乘:

      二维空间判断左右

      三维空间求法向量

      判断点是否在三角形/矩形内

  • 深度测试可能在哪个阶段

    片元着色器处理之后,alpha test之前

  • 图形学中表示旋转有哪些形式(数学形式)

    旋转矩阵,旋转向量,欧拉角,四元数

  • 四元数和欧拉角

  • OpenGL渲染管线中,MVP三个矩阵的作用

    Model矩阵:将局部坐标转化为世界坐标,主要是对模型进行一些变换,如缩放、旋转、平移等。

    View矩阵:将世界坐标转化为观察坐标,也就是相对于摄像机的坐标。

    Project矩阵:将观察空间转化为裁影空间,也就是将三维空间映射到二维空间的过程,其中有两种投影方式,透视投影:遵循远小近大的3D视觉效果,正交投影:不考虑物体的距离,直接进行投影。

  • 如何计算空间中点到线段距离

  • culling了解哪些,说一下视锥剔除的计算过程

    背面剔除 深度剔除

    判断对象是否在相机视锥体内(相交也算),在则不剔除,不在则剔除

  • GPUInstancing

    将这些静态的物件如植被等全部从场景中剔除,而保存其位置、缩放、uv偏移、lightmapindex_等相关信息,在需要渲染的时候,根据其保存的信息,通过Instance_来渲染,这能够减少那些因为内存原因而不能合批的大批量相同物件的渲染时间。

  • mipmap

    多级渐远纹理(Mipmap)

    mipmap的主要作用便是模型的贴图会根据摄像机距离模型的远近而调整不同质量的贴图显示,以达到优化目的。其用法如下图所示

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值