Skip to content

程序化几何

Procedural Geometry,即程序化几何体,通过算法、数学公式和节点逻辑等创建模型,而非使用雕刻、布线等传统的方式进行建模。

程序化几何的基础是通过网格存储几何体的信息,在Direct 12 龙书中使用GeometryGenerator类进行管理。

Vertex

Vertex结构体定义了顶点信息,包括坐标、法线等信息,并重载了两个构造器。完整的定义如下:

Vertex
    // Vertex structure represents a single vertex with position, normal, tangent, and texture coordinates.
    // Instantiation of this structure needs float data or DirectX::XMFLOAT3/XMFLOAT2 data .
    struct Vertex {
        DirectX::XMFLOAT3 Position;
        DirectX::XMFLOAT3 Normal;
        DirectX::XMFLOAT3 TangentU;
        DirectX::XMFLOAT2 TexC;

        Vertex() = default;
        Vertex(
            float px, float py, float pz,
            float nx, float ny, float nz,
            float tx, float ty, float tz,
            float u, float v
        ):
            Position(px, py, pz),
            Normal(nx, ny, nz),
            TangentU(tx, ty, tz),
            TexC(u, v){}

        Vertex(
            const DirectX::XMFLOAT3& position,
            const DirectX::XMFLOAT3& normal,
            const DirectX::XMFLOAT3& tangentU,
            const DirectX::XMFLOAT2& texC
        ) :
            Position(position),
            Normal(normal),
            TangentU(tangentU),
            TexC(texC) {}
    };

MeshData

MeshData是用于存储顶点列表和索引列表的结构体,其完整定义如下:

MeshData
    struct MeshData {
        std::vector<Vertex> Vertices;
        std::vector<uint32> Indices32;

        std::vector<uint16>& GetIndices16(){
            if(mIndices16.empty()) {
                mIndices16.resize(Indices32.size());
                for(size_t i = 0; i < Indices32.size(); ++i) {
                    mIndices16[i] = static_cast<uint16>(Indices32[i]);
                }
            }
            return mIndices16;
        }

    private:
        std::vector<uint16> mIndices16;
    };

其中,GetIndices16()方法用于将索引数据从UINT32转换成UINT16缓存到私有成员mIndices16并返回;使用16位索引能够节省显存资源和提高内存带宽的效率,但只能在单个模型顶点数量小于\(65535\)时使用。

柱体

在创建一个柱体网格前需要理解柱体网格的构成。