如何使用多着色器状态?运行时切换渲染状态的最优实现方案
D3D11 光栅化裁切模式切换最优方案
动态修改已有状态对象的方案不可行
D3D11 规定所有管道状态对象(包括 ID3D11RasterizerState、ID3D11DepthStencilState、ID3D11BlendState 等)均为不可变对象,创建完成后属性就无法修改。你调用 ID3D11RasterizerState::GetDesc() 只能拿到当前状态属性的副本,修改这个副本不会对已经创建的状态对象产生任何影响,因此这个方案无法实现。
推荐实现方案:懒加载状态缓存池
不需要提前创建所有状态组合,仅在首次使用时创建、后续复用即可,实现逻辑如下:
- 以状态描述结构体(比如
D3D11_RASTERIZER_DESC)作为缓存的 Key,需要切换状态时先拿新的描述在缓存中查询 - 如果缓存中已存在对应状态对象,直接调用
RSSetState绑定即可 - 如果缓存中不存在,调用
CreateRasterizerState创建新的状态对象,存入缓存后再绑定
该方案的优势: - 无需提前硬编码枚举所有状态组合,运行时按需创建即可
- 同一状态组合只会创建一次,不会产生重复的资源开销
- 绑定逻辑和原有逻辑一致,不会增加额外运行时负担
简化场景适配
如果你的业务场景中只有裁切模式(CullMode)需要切换,其他光栅化属性固定,无需实现通用缓存,直接提前创建2个状态对象即可:一个设置 D3D11_CULL_BACK,一个设置 D3D11_CULL_FRONT,运行时直接切换绑定,实现更简单、性能更高。
内容的提问来源于stack exchange,提问作者Rafael Ferreira
相关产品推荐
相关产品推荐

