Directx3D

作者: 上官宏竹 | 来源:发表于2022-11-27 23:44 被阅读0次

    DirectX11--深入理解与使用2D纹理资源
    DirectX11--HLSL语法入门

    介绍

    在VS2019中,选择【使用C++的桌面开发】会默认选中一个叫做Windows 10 SDK的组件。这个SDK已经集成DirectX的开发库。


    XNA数学库

    缩放

    XMMatrixScaling

    // 调用 XMMatrixScaling() 函数用以生成缩放矩阵, 该函数 3 个参数分别表示
    // 在 X, Y, Z 轴上的缩放量
    // 在 X, Y, Z 轴上缩小到 1/5 (即 0.2), 然后将生成的缩放矩阵赋值给 mScal
    XMMATRIX mScal = XMMatrixScaling(0.2f, 0.2f, 0.2f);
    

    旋转

    XMMatrixRotation*

    // 绕 Y 轴旋转 45 度, 即 1/4 PI
    // 调用 XMMatrixRotationY() 函数用以生成旋转矩阵, 该函数的参数为旋转的弧度
    // XM_PIDIV4 为 XNA 库定义的数据常量表示 1/4 PI
    XMMATRIX mRota = XMMatrixRotationY(XM_PIDIV4);
    

    平移

    XMMatrixTranslation

    // 在 X 轴平移 1 个单位, 在 Y 轴平移 2 个单位, 在 Z 轴平移 -3 个单位
    // 调用函数 XMMatrixTranslation() 生成平移矩阵
    // 该函数 3 个参数分别表示在 X, Y, Z 轴上的平移量
    XMMATRIX mTrans = XMMatrixTranslation(1.0f, 2.0f, -3.0f);
    

    矩阵相乘

    XMMatrixMultiply

    变换向量

    XMVector4Transform通过矩阵变换一个4D向量,并返回转换后的向量。

    参考: 《基于 DirectX11 的 3D 图形程序设计案例教程》学习二 MatrixTrans

    Directx3D龙书记录

    输入装配阶段

    输入装配(Input Assembler,简称IA)阶段从内存读取几何数据(顶点和索引)并将这些数据组合为几何图元(例如,三角形、直线)

    图元拓扑

    通过指定图元拓扑来告诉Direct3D以何种方式组成几何图元。

    void ID3D11Device::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology); 
    

    顶点着色器阶段

    在完成图元装配后,顶点将被送往顶点着色器(vertex shader)阶段。顶点着色器可以被看成是一个以顶点作为输入输出数据的函数。每个将要绘制的顶点都会通过顶点着色器推送至硬件;实际上,我们可以概念性地认为在硬件上执行了如下代码:

    for(UINT i = 0; i < numVertices; ++i)
        outputVertex[i] = VertexShader(inputVertex[i]);
    

    顶点着色器函数由我们自己编写,但是它会在GPU上运行,所以执行速度非常快。
    许多效果,比如变换(transformation)、光照(lighting)和置换贴图映射(displacement mapping)都是由顶点着色器来实现的。记住,在顶点着色器中,我们不仅可以访问输入的顶点数据,也可以访问在内存中的纹理和其他数据,比如变换矩阵和场景灯光。
    Direct3D也希望我们将深度坐标映射到一个规范化区间[0,1]中。

    规范化设备坐标(NDC)

    透视投影矩阵

    透视投影矩阵可由如下XNA函数生成:

    XMMATRIX XMMatrixPerspective FovLH(// returns projection matrix
         FLOAT FovAngleY, // vertical field of view angle in radians
         FLOAT AspectRatio, // aspect ratio =  width / height
         FLOAT NearZ, // distance to near plane
         FLOAT FarZ);  // distance to far plane
    

    下面的代码片段示范了XMMatrixPerspectiveFovLH函数的使用方法。这里,我们将垂直视域角设为45°,近平面z设为1,远平面z设为1000(这些长度是在观察空间中的)。

    XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathX::Pi,
         AspectRatio(),1.0f,1000.0f);
    float D3Dapp::AspectRatio() const
    {
         return static_cast<float>(mClientWidth)/mClientHeight;
    }
    

    几何着色器阶段

    几何着色器以完整的图元作为输入数据。例如,当我们绘制三角形列表时,输入到几何着色器的数据是构成三角形的三个点。(注意,这三个点是从顶点着色器传递过来的。)几何着色器的主要优势是它可以创建或销毁几何体。例如,输入图元可以被扩展为一个或多个其他图元,或者几何着色器可以根据某些条件拒绝输出某些图元。这一点与顶点着色器有明显的不同:顶点着色器无法创建顶点,只要输入一个顶点,那么就必须输出一个顶点。几何着色器通常用于将一个点扩展为一个四边形,或者将一条线扩展为一个四边形。

    光栅化阶段

    光栅化(rasterization)阶段的主要任务是为投影后的3D三角形计算像素颜色。

    视口变换

    在裁剪之后,硬件会自动执行透视除法,将顶点从齐次裁剪空间变换到规范化设备空间(NDC)。一旦顶点进入NDC空间,构成2D图像的2D x、y坐标就会被变换到后台缓冲区中的一个称为视口的矩形区域内。在该变换之后,x、y坐标将以像素为单位。通常,视口变换不修改z坐标,因为z坐标还要由深度缓存使用,但是我们可以通过D3D11_VIEWPORT结构体的MinDepth和MaxDepth值修改z坐标的取值范围。MinDepth和MaxDepth的值必须在0和1之间。

    顶点属性插值

    除位置外,顶点还可以包含其他属性,比如颜色、法线向量和纹理坐标。在视口变换之后,这些属性必须为三角形表面上的每个像素进行插值。顶点深度值也必须进行插值,以使每个像素都有一个可用于深度缓存算法的深度值。对屏幕空间中的顶点属性进行插值,其实就是对3D空间中的三角形表面进行线性插值(如图5.33所示);这一工作需要借助所谓的透视矫正插值(perspective correct interpolation)来实现。本质上,三角形表面内部的像素颜色都是通过顶点插值得到的。


    图5.34

    图5.34 一条3D线被投影到投影窗口上(在屏幕空间中投影是一条2D线)。我们看到,在3D线上取等距离的点,在2D屏幕空间上的投影点却不是等距离的。所以,我们在3D空间中执行线性插值,在屏幕空间需要执行非线性插值。

    像素着色器阶段

    像素着色器会处理每个像素片段(pixel fragment),它的输入是插值后的顶点属性,由此计算出一个颜色。

    输出合并阶段

    当像素片段由像素着色器生成之后,它们会被传送到渲染管线的输出合并(output merger,简称OM)阶段。在该阶段中,某些像素片段会被丢弃(例如,未能通过深度测试或模板测试)。未丢弃的像素片段会被写入后台缓冲区。混合(blending)工作是在该阶段中完成的,一个像素可以与后台缓冲区中的当前像素进行混合,并以混合后的值作为该像素的最终颜色。某些特殊效果,比如透明度,就是通过混合来实现的

    chili教程记录

    chili的原版英文教程-中文字幕
    chili的原版英文教程

    模板继承

    在第20讲大约13:40中讲到,如果一个子类模板,继承的父类也是一个模板,并且子类需要使用父类模板的父类中的方法,则需要显示指明,如下:

    class Bindable
    {
    public:
        virtual void Bind( Graphics& gfx ) noexcept = 0;
        virtual ~Bindable() = default;
    protected:
        static ID3D11DeviceContext* GetContext( Graphics& gfx ) noexcept;
        static ID3D11Device* GetDevice( Graphics& gfx ) noexcept;
        static DxgiInfoManager& GetInfoManager( Graphics& gfx ) noexcept(IS_DEBUG);
    };
    template<typename C>
    class ConstantBuffer : public Bindable
    {
      ....
    }
    template<typename C>
    class VertexConstantBuffer : public ConstantBuffer<C>
    {
        using ConstantBuffer<C>::pConstantBuffer;
        using Bindable::GetContext;
    public:
        void Bind( Graphics& gfx ) noexcept override
        {
            // 这里这个GetContext需要显示指明
            // 1. 使用using Bindable::GetContext;
            // 2. 使用this->GetContext
            // 3. 使用域作用符Bindable::GetContext
            GetContext( gfx )->VSSetConstantBuffers( 0u,1u,pConstantBuffer.GetAddressOf() );
        }
    };
    

    相关文章

      网友评论

          本文标题:Directx3D

          本文链接:https://www.haomeiwen.com/subject/bvvpxrtx.html