• DirectX12 - Triangle Culling and Winding Order(三角形的剔除与绕序)


    这里是SunshineBooming,GPU公司一枚小小的Driver工程师,主要工作是写DirectX12 Driver,我会持续更新这个DX12 Spec系列,可能比较冷门,但是都是干货和工作中的心得体会,有任何GPU相关的问题都可以在评论区互动,知无不言:

    DirectX12 Spec 总目录

    1. 什么是Triangle Culling(三角形剔除)?

    • 我们都知道,在现有的3D图形框架中,3D模型都是由Triangle有序排列起来的。例如一个长方体有6个面,每个面可以拆分成2个Triangle。那么我们就可以用[Tri0…Tri11]这样12个Triangle有序排列,最后还原成一个长方体的3D模型:
      Triangles
    • 同时我们也可以发现,在正对着长方体某个面的观察视角上,例如这样:
      CameraView
      在此视角下,只能观察到Tri0、Tri1两个三角形组成的平面,Tri2/3/4/5是无法看见的,因此这部分Triangle在DirectX12的Rendering Pipeline中可以预先剔除(Culling),这样做可以减少不必要的计算量,提高渲染效率。

    2. 什么是Winding Order(绕序)?

    • Winding Order是几何图形学中的知识。假设一个Triangle由3个Vertex构成,且3个Vertex输入到DX12驱动的Input Layout顺序,为Ver0->Ver1->Ver2,这个Vertex的排布顺序,就是Triangle的绕序(Winding Order)
      VertexOrder
      根据左手定则,在该绕序条件下,Triangle的法向量,为传出纸向外,且垂直于该平面的单位向量。
    • 注意:DirectX12判定平面法向量用的是左手定则,OGL正好相反,用的是右手定则
    • 所以我们可以看出,每个Triangle的Vertex绕序,决定了该Triangle图形的法向量方向

    3. 如何用Winding Order(绕序)做Culling(剔除)?

    • 有了绕序的概念,做剔除的原理其实很简单。
    • 我们知道DirectX12做渲染过程中,所有3D模型最后都要统一到观察空间(View Space)。每个3D模型先在局部空间建模,然后通过世界矩阵->世界空间,然后根据Camera在世界空间中摆放的参数,得到观察矩阵,再通过观察矩阵,将世界空间->观察空间(扯远了。。。)。
    • 那么观察空间也是一个三维空间:
      ViewSpace
      Camera观察方向指向+Z方向,所以我们规定,任何一个Triangle的法向量,和-Z方向的单位向量(比如(0,0,-1))做比较,2个向量夹角在[0,Pi/2)范围留下,在[Pi/2,Pi]范围剔除,因为大于Pi/2角度的平面,是背向观察方向的平面,所以是不可见的:
      Culling
      法向量如何确定呢?就是根据之前说的的绕序确定。
    • 所以剔除的整个原理就是这样简单,其中算法向量和算向量夹角都有数学公式支撑,这里不做赘述。
    • 另外剔除的整个计算和判定过程都是由GPU Hardware端做的,因为一个简单的3D模型,都可能有成千上万个Triangle组成,计算量是非常大的。
  • 相关阅读:
    苍穹外卖01-项目概述、环境搭建
    list和tuple的区别:
    DStream操作
    算法----组合总和(Kotlin)-面试真题
    代码随想录-021-349.两个数组的交集
    【勇敢饭饭,不怕刷题之链表】两个链表的操作
    ES之倒排索引
    #每日一题合集#牛客JZ3-JZ12
    【微服务】Sentinel 适配网关进行流量控制
    Qt在Android上设置连接到指定的WIFI
  • 原文地址:https://blog.csdn.net/sunshinebooming/article/details/128112239