DirectX11--HLSL语法入门(6)
时间:2022-12-14 22:18 来源:网络整理 作者:采集插件 点击:次
Constant Buffers:常量缓冲区对常量值的读取有所优化。他们被设计用于CPU对这些数据的频繁更新,所以他们有额外的大小、布局和访问限制。 着色器常量着色器常量存在内存中的一个或多个缓冲区资源当中。他们能够被组织成两种类型的缓冲区:常量缓冲区(cbuffers)和纹理缓冲区(tbuffers)。关于纹理缓冲区,咱们不在这讨论。 常量缓冲区(Constant Buffer)常量缓冲区容许C++端将数据传递给HLSL中使用,在HLSL端,这些传递过来的数据不可更改,于是是常量。常量缓冲区对这种使用方式有所优化,表现为低延迟的访问和容许来自CPU的频繁更新,所以他们有额外的大小、布局和访问限制。 声明方式以下: cbuffer VSConstants { float4x4 g_WorldViewProj; fioat3 g_Color; uint g_EnableFog; float2 g_ViewportXY; float2 g_ViewportWH; }因为咱们写的是原生HLSL,当咱们在HLSL中声明常量缓冲区时,还须要在HLSL的声明中使用关键字register手动指定对应的寄存器索引,而后编译器会为对应的着色器阶段自动将其映射到15个常量缓冲寄存器的其中一个位置。这些寄存器的名字为b0到b14: cbuffer VSConstants : register(b0) { float4x4 g_WorldViewProj; fioat3 g_Color; uint g_EnableFog; float2 g_ViewportXY; float2 g_ViewportWH; }在C++端是经过ID3D11DeviceContext::*SSetConstantBuffers指定特定的槽(slot)来给某一着色器阶段对应的寄存器索引提供常量缓冲区的数据。 若是是存在多个不一样的着色器阶段使用同一个常量缓冲区,那就须要分别给这两个着色器阶段设置好相同的数据。 综合前面几节内容,下面演示了顶点着色器和常量缓冲区的用法: cbuffer ConstantBuffer : register(b0) { float4x4 g_WorldViewProj; } void VS_Main( in float4 inPos : POSITION, // 绑定变量到输入装配器 in uint VID : SV_VertexID, // 绑定变量到系统生成值 out float4 outPos : SV_Position) // 告诉管线将该值解释为输出的顶点位置 { outPos = mul(inPos, g_WorldViewProj); }上面的代码也能够写成: cbuffer ConstantBuffer : register(b0) { float4x4 g_WorldViewProj; } struct VertexIn { float4 inPos : POSITION; // 源自输入装配器 uint VID : SV_VertexID; // 源自系统生成值 }; float4 VS_Main(VertexIn vIn) : SV_Position { return mul(vIn.inPos, g_WorldViewProj); }有关常量缓冲区的打包规则,建议在阅读到时索引缓冲区、常量缓冲区一章时,再来参考杂项篇的HLSL常量缓冲区的打包规则。 DirectX11 With Windows SDK完整目录 Github项目源码 欢迎加入QQ群: 727623616 能够一块儿探讨DX11,以及有什么问题也能够在这里汇报。 (责任编辑:admin) |