效果 10 和效果 11 之间的差异
本主题介绍效果 10 和效果 11 之间的差异。
设备上下文、线程和克隆
ID3D10Device 接口已拆分为 Direct3D 11 中的两个接口:ID3D11Device 和 ID3D11DeviceContext。 可以创建多个 ID3D11DeviceContexts,以促进多个线程上的并发执行。 效果 11 将此概念扩展到效果框架。
Effects 11 运行时是单线程的。 因此,不应同时使用具有多个线程的单个 ID3DX11Effect 实例。
若要对多个实例使用 Effects 11 运行时,必须创建单独的 ID3DX11Effect 实例。 由于 ID3D11DeviceContext 也是单线程的,因此应将不同的 ID3D11DeviceContext 实例传递给 Apply 上的每个效果实例。 可以使用这些单独的设备上下文来创建命令列表,以便呈现线程可以在即时设备上下文中应用它们。
创建封装相同功能的多个效果(用于多个线程)的最简单方法是创建一个效果,然后创建克隆的副本。 克隆在从头开始创建多个副本具有以下优势:
- 克隆例程比创建例程快。
- 克隆的效果共享创建的着色器、状态块和类实例(因此无需重新创建它们)。
- 克隆的效果可以共享常量缓冲区。
- 克隆的效果以与当前效果匹配的状态(无论是否优化了变量值)开始。
有关详细信息,请参阅 克隆效果。
效果池和组
到目前为止,Direct3D 10 中最普遍的效果池的使用用于分组材料。 效果池已从效果 11 中删除,并且已添加组,这是一种更高效的分组材料方法。
效果组只是一组技术。 有关详细信息,请参阅 效果组语法(Direct3D 11)。
请考虑以下效果层次结构,其中包含四个子效果和一个效果池:
// Effect Pool
cbufer A { ... }
PixelShader pPSGrass;
PixelShader pPSWater;
// Effect Child 1
#include "EffectPool.fx"
technique10 GrassMaterialLowSpec { ... }
// Effect Child 2
#include "EffectPool.fx"
technique10 GrassMaterialHighSpec { ... }
// Effect Child 3
#include "EffectPool.fx"
technique10 WaterMaterialLowSpec { ... }
// Effect Child 4
#include "EffectPool.fx"
technique10 WaterMaterialHighSpec { ... }
可以使用组在 Effects 11 中实现相同的功能:
cbufer A { ... }
PixelShader pPSGrass;
PixelShader pPSWater;
fxgroup GrassMaterial
{
technique10 LowSpec { ... }
technique10 HighSpec { ... }
}
fxgroup WaterMaterial
{
technique10 LowSpec { ... }
technique10 HighSpec { ... }
}
新的着色器阶段
Direct3D 11 中有三个新的着色器阶段:外壳着色器、域着色器以及计算着色器。 效果 11 以类似于顶点着色器、几何着色器和像素着色器的方式处理这些对象。
已将三个新变量类型添加到效果 11:
- 赫尔沙德
- DomainShader
- ComputeShader
如果在技术中使用这些着色器,则必须将该技术标记为“技术 11”,而不是“技术 10”。 无法将计算着色器设置为与其他任何图形状态相同的传递(其他着色器、状态块或呈现目标)。
新纹理类型
Direct3D 11 支持以下纹理类型:
无序访问视图
效果 11 支持获取和设置新的无序访问视图类型。 这的工作方式与纹理类似。
请考虑以下效果 HLSL 示例:
RWTexture1D<float> myUAV;
可以在C++中设置此变量,如下所示:
ID3D11UnorderedAccessView* pUAVTexture1D = NULL;
ID3DX11EffectUnorderedAccessViewVariable* pUAVVar;
pUAVVar = pEffect->GetVariableByName("myUAV")->AsUnorderedAccessView();
pUAVVar->SetUnorderedAccessView( pUAVTexture1D );
Direct3D 11 支持以下无序访问视图类型:
- RWBuffer
- RWByteAddressBuffer
- RWStructuredBuffer
- RWTexture1D
- RWTexture1DArray
- RWTexture2D
- RWTexture2DArray
- RWTexture3D
接口和类实例
有关接口和类语法,请参阅 接口和类。
有关在效果中使用接口和类,请参阅效果 中的接口和类。
可寻址流出
在 Direct3D 10 中,几何着色器可以将一个数据流输出到流输出单元和光栅器单元。 在 Direct3D11 中,几何着色器最多可以将四个数据流输出到流输出单元,最多可将其中一个流输出到光栅器单元。 ConstructGSWithSO 内部函数已更新,以反映此新功能。
有关详细信息,请参阅 流出语法。
设置和取消设置设备状态
在效果 10 中,可以使用 ID3D10EffectConstantBuffer::SetConstantBuffer 和 SetTextureBuffer 函数,使常量缓冲区和纹理缓冲区由用户管理。 调用这些函数后,Effects 10 运行时不再管理常量缓冲区或纹理缓冲区,用户必须使用 ID3D10Device 接口填充数据。
在 Effects 11 中,还可以使用以下调用使状态块(混合状态、光栅器状态、深度模具状态和采样器状态)由用户管理:
- ID3DX11EffectBlendVariable::SetBlendState
- ID3DX11EffectRasterizerVariable::SetRasterizerState
- ID3DX11EffectDepthStencilVariable::SetDepthStencilState
- ID3DX11EffectSamplerVariable::SetSampler
调用这些函数后,Effects 11 运行时不再管理状态块变量,并且存在值将保持不变。 请注意,由于状态块是不可变的,因此用户必须设置新的状态块才能更改值。
还可以将常量缓冲区、纹理缓冲区和状态块还原为非用户托管状态。 如果取消设置这些变量,则 Effects 11 运行时将在必要时继续更新它们。 可以使用以下调用来取消设置用户托管变量:
- ID3DX11EffectConstantBuffer::UndoSetConstantBuffer
- ID3DX11EffectConstantBuffer::UndoSetTextureBuffer
- ID3DX11EffectBlendVariable::UndoSetBlendState
- ID3DX11EffectRasterizerVariable::UndoSetRasterizerState
- ID3DX11EffectDepthStencilVariable::UndoSetDepthStencilState
- ID3DX11EffectSamplerVariable::UndoSetSampler
效果虚拟机
已删除计算函数外部复杂表达式的效果虚拟机。
不支持复杂表达式的以下示例:
- SetPixelShader(myPSArray(i * 3 + j ) ;
- SetPixelShader(myPSArray(float)i ;
- FILTER = i + 2;
支持以下非复杂表达式的示例:
- SetPixelShader(myPS );
- SetPixelShader(myPS[i] );
- SetPixelShader(myPS[ uIndex ] ] ;uIndex 是一个 uint 变量
- FILTER = i;
- FILTER = ANISOTROPIC;
这些表达式可以出现在状态块表达式(如 FILTER)和传递表达式(如 SetPixelShader) 中。
源可用性和位置
效果 10 在 D3D10.dll中分布。 效果 11 作为源分发,具有相应的 Visual Studio 解决方案进行编译。 创建效果类型应用程序时,建议将这些应用程序中直接包含 Effects 11 源。
可以从 Direct3D 11 Update 的效果获取效果 11。
相关主题