常量缓冲区
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; // 当前点到相机向量
};