D3D11
+ -

常量缓冲区

2024-11-25 22 0

1.创建常量缓冲区

    // 设置常量缓存区
    D3D11_BUFFER_DESC cbd;
    ZeroMemory(&cbd, sizeof(cbd));
    cbd.Usage = D3D11_USAGE_DEFAULT;
    cbd.ByteWidth = sizeof(ConstantBuffer);
    cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    cbd.CPUAccessFlags = 0;
    HR(md3dDevice->CreateBuffer(&cbd, nullptr, &mBoxCB));

    //设置VS中的常量缓冲区 0=slot
    //指定特定的槽(slot)来给某一着色器阶段对应的寄存器索引提供常量缓冲区的数据。
    md3dImmediateContext->VSSetConstantBuffers(0, 1, &mBoxCB);

常量缓冲区的结构体内容如下:

    // 常量缓存
    struct ConstantBuffer
    {
        DirectX::XMMATRIX wvp;
        float gTime;
    };

2.在UpdateSence中更新常量缓冲区

    static ConstantBuffer mCBuffer;    // 常量数据结构
    mCBuffer.wvp = world * view * proj;
    mCBuffer.gTime = mTimer.TotalTime();

    // 更新WVP矩阵数据
    md3dImmediateContext->UpdateSubresource(mBoxCB, 0, nullptr, &mCBuffer, 0, 0);

3.在PS或者VS中引用常量缓冲区
Color.fx

cbuffer cbPerObject : register(b0)
{
    row_major matrix wvp;    // 默认列主矩阵
    float gTime;
};

struct VertexIn
{
    float3 PosL : POSITION;
    float4 Color : COLOR;
};

struct VertexOut
{
    float4 PosH : SV_POSITION;
    float4 Color : COLOR;
};

VS中

#include "Color.fx"

VertexOut VS(VertexIn pIn)
{
    // 练习6.6 shader在重新生成时,记得将vso和pso文件给删除 
    //pIn.PosL.xy += 0.5f*sin(pIn.PosL.x)*sin(3.0f*gTime);
    //pIn.PosL.z *= 0.6f + 0.4f*sin(2.0f*gTime);

    VertexOut pOut;
    pOut.PosH = mul(float4(pIn.PosL, 1.0f), wvp);//使用矩阵

    pOut.Color = pIn.Color;
    return pOut;
}

PS由于未调用PSSetConstantBuffers,故没有

#include "Color.fx"

float4 PS(VertexOut pIn) : SV_Target
{
    return pIn.Color;
}

两个常量缓冲区

    // 设置常量缓存区
    D3D11_BUFFER_DESC cbd;
    ZeroMemory(&cbd, sizeof(cbd));
    cbd.Usage = D3D11_USAGE_DEFAULT;
    cbd.ByteWidth = sizeof(ConstantBuffer);
    cbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    cbd.CPUAccessFlags = 0;
    HR(md3dDevice->CreateBuffer(&cbd, nullptr, &mBoxCB));
    md3dImmediateContext->VSSetConstantBuffers(0, 1, &mBoxCB);    // VS常量缓冲区对应b0

    D3D11_BUFFER_DESC cbdFrame;
    ZeroMemory(&cbdFrame, sizeof(cbdFrame));
    cbdFrame.Usage = D3D11_USAGE_DEFAULT;
    cbdFrame.ByteWidth = sizeof(FrameConstantBuffer);
    cbdFrame.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    cbdFrame.CPUAccessFlags = 0;
    HR(md3dDevice->CreateBuffer(&cbdFrame, nullptr, &mFrameBoxCB));
    md3dImmediateContext->PSSetConstantBuffers(1, 1, &mFrameBoxCB);    // PS常量缓冲区对应b1

对应的着色器代码为:

// Shader代码
// 顶点着色器的常量缓存
cbuffer cbPerObject : register(b0)
{
    row_major matrix gWorld;    // 默认列主矩阵
    row_major matrix gWorldInvTranspose;    // World逆转置矩阵,用于将法线从模型坐标系中转换到世界坐标系
    row_major matrix gWorldViewProj;    // wvp
};

// 片元着色器的常量缓存
cbuffer cbPerFrame : register(b1)
{
    DirectionalLight gDirLight;    // 直射光
    PointLight gPointLight;    // 点光源
    SpotLight gSpotLight;    // 聚光灯
    Material gMaterial;    // 物体材质
    float3 gEyePosW;    // 当前点到相机向量
};

0 篇笔记 写笔记

2.2.1缓冲区资源-常量缓冲区
常量缓冲区是我们遇到的第一种资源类型,可从可编程着色器阶段访问,随后在HLSL代码中使用。常量缓冲器用于向在流水线中执行的可编程着色器程序提供常数信息。术语常量是指在执行draw或dispatch调用的整个过程中,该缓冲区内的数据保持不变。仅在管道调用之间更改的任何信息(如世界变换矩阵或对象颜色......
6.4.1默认常量缓冲区
任何在没有static常量修饰符的情况下声明的全局变量都将被编译器视为名为$Globals的默认常量缓冲区内的常量。类似地,标记为统一的着色器入口点函数的参数将被放置在另一个名为$Params的默认常量缓冲区中.......
常量缓冲区
1.创建常量缓冲区 // 设置常量缓存区 D3D11_BUFFER_DESC cbd; ZeroMemory(&cbd, sizeof(cbd)); cbd.Usage = D3D11_USAGE_DEFAULT; cbd.ByteWidth = si......
作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!