パイプライン ステート
Stride は、グラフィックスパイプラインステートを完全にコントロールできます。パイプラインステートには、以下のものが含まれます。
- ラスタライザーステート
- 深度ステンシルステート
- ブレンドステート
- エフェクト
- 入力レイアウト
- 出力記述
ステートは不変の PipelineState オブジェクトにコンパイルされ、これによってパイプライン全体が記述されます。これらのオブジェクトは、CommandList を使って結合されます。
コード: ステートオブジェクトを作成する
// パイプラインステートオブジェクトの作成
// Creating pipeline state object
var pipelineStateDescription = new PipelineStateDescription();
var pipelineState = PipelineState.New(GraphicsDevice, ref pipelineStateDescription);
// ステートをパイプラインに適用
// Applying the state to the pipeline
CommandList.SetPipelineState(pipelineState);
MutablePipelineState クラスを使うと、基礎となるパイプラインの状態をキャッシュしつつ、独立してステートを設定することができます。
コード: 可変パイプラインステート
// パイプラインステートオブジェクトの作成
// Creating the pipeline state object
var mutablePipelineState = new MutablePipelineState();
// 値を設定して再構築
// Setting values and rebuilding
mutablePipelineState.State.BlendState = BlendStates.AlphaBlend
mutablePipelineState.Update
// ステートをパイプラインに適用
// Applying the state to the pipeline
CommandList.SetPipelineState(mutablePipelineState.CurrentState);
ラスタライザーステート
ラスタライザーは、RasterizerState プロパティで設定することができます。RasterizerStates クラスには定義済みの記述がいくつか保持されています。これらはカリングモードに関するもので、ほとんどの使用例には十分でしょう。
コード: カリングモードを設定する
pipelineStateDescription.RasterizerState = RasterizerStates.CullNone;
pipelineStateDescription.RasterizerState = RasterizerStates.CullFront;
pipelineStateDescription.RasterizerState = RasterizerStates.CullBack;
独自のカスタムステートを作成することもできます。オプションと既定値の一覧については、RasterizerStateDescription API ドキュメントを参照してください。
コード: カスタム ラスタライザー ステート
var rasterizerStateDescription = new RasterizerStateDescription(CullMode.Front);
rasterizerStateDescription.ScissorTestEnable = true; // enables the scissor test
pipelineStateDescription.RasterizerState = rasterizerStateDescription;
深度ステンシル ステート
DepthStencilState プロパティは、深度とステンシルのステートを表します。DepthStencilStates クラスでは、よく使われるステートのセットが定義されています。
- Default: 比較条件に「<」(less)を使う深度値の Read/Write
- DefaultInverse: 比較条件に「≧」(greater or equal)を使う Read/Write
- DepthRead: 比較条件に「<」(less)を使う read only
- None: Read/Write のいずれも不可
コード: 深度ステンシルステートを設定する
pipelineStateDescription.DepthStencilState = DepthStencilStates.Default;
pipelineStateDescription.DepthStencilState = DepthStencilStates.DefaultInverse;
pipelineStateDescription.DepthStencilState = DepthStencilStates.DepthRead;
pipelineStateDescription.DepthStencilState = DepthStencilStates.None;
また、独自の深度ステンシルステートを設定することもできます。オプションと既定値の一覧については、DepthStencilStateDescription API ドキュメントを参照してください。
コード: カスタム深度ステンシルステート
// 深度テストは有効、Write は不可。
// depth test is enabled but it doesn't write
var depthStencilStateDescription = new DepthStencilStateDescription(true, false);
pipelineStateDescription.DepthStencilState = depthStencilStateDescription;
ステンシル参照は PipelineState の一部ではありません。ステンシル参照の値は SetStencilReference(int) を使って設定します。
コード: ステンシル参照を設定する
CommandList.SetStencilReference(2);
ブレンドステート
BlendState プロパティと SampleMask プロパティにより、ブレンドを制御することができます。BlendStates クラスには、よく使われるブレンドステートのセットが定義されています。
- Additive: 加算合成
- AlphaBlend: 転送元の色と転送先のアルファを使った合成
- NonPremultiplied: 転送元のアルファと両方の色を使った合成
- Opaque: 色の置換
コード: ブレンドステートを設定する
// ありふれたブレンドステートの設定
// Set common blend states
pipelineStateDescription.BlendState = BlendStates.Additive;
pipelineStateDescription.BlendState = BlendStates.AlphaBlend;
pipelineStateDescription.BlendState = BlendStates.NonPremultiplied;
pipelineStateDescription.BlendState = BlendStates.Opaque;
// サンプルマスクの設定
// Set the sample mask
pipelineStateDescription.SampleMask = 0xFFFFFFFF;
独自の深度ステートやブレンドステートを設定することができます。オプションと既定値の一覧については、BlendStateDescription API ドキュメントを参照してください。
コード: カスタムブレンドステート
// ターゲットごとのブレンドステートを作成
// create the object describing the blend state per target
var blendStateRenderTargetDescription = new BlendStateRenderTargetDescription();
blendStateRenderTargetDescription.BlendEnable = true;
blendStateRenderTargetDescription.ColorSourceBlend = Blend.SourceColor;
// etc.
// BlentStateDescription オブジェクトを作成
// create the blendStateDescription object
var blendStateDescription = new BlendStateDescription(Blend.SourceColor, Blend.InverseSourceColor);
blendStateDescription.AlphaToCoverageEnable = true; // enable alpha to coverage
blendStateDescription.RenderTargets[0] = blendStateRenderTargetDescription;
pipelineStateDescription.BlendState = blendStateDescription;
ブレンド係数は PipelineState の一部ではありません。ブレンド係数は SetBlendFactor(Color4) を使って設定します。
Code: ブレンド係数の設定
CommandList.SetBlendFactor(Color4.White);
エフェクト
パイプラインステートには、描画で使用するシェーダーも指定します。 Effect をパイプラインにバインドするには、EffectBytecode と PipelineStateDescription の RootSignature プロパティを、エフェクトの一致する値に設定します。
EffectBytecode には、実際のシェーダープログラムが含まれています。詳細については、エフェクトとシェーダーを参照してください。
RootSignature には、エフェクトが必要とするリソースの数と種類が記述されています。次の章では、パイプラインにリソースをバインドする方法について説明します。
コード: エフェクトのバインド
var effectInstance = new EffectInstance(EffectSystem.LoadEffect("MyEffect").WaitForResult());
pipelineStateDescription.EffectBytecode = effectInstance.Effect.Bytecode;
pipelineStateDescription.RootSignature = effectInstance.RootSignature;
入力レイアウト
パイプラインステートには、InputElements と PrimitiveType を介して頂点がデバイスに送られる際のレイアウトを記述します。
頂点の描画のページでは、カスタム頂点バッファの作成方法とその VertexDeclaration について詳しく説明しています。
コード: 入力レイアウトを設定する
VertexDeclaration vertexDeclaration = ...
pipelineStateDescription.InputElements = vertexDeclaration.CreateInputElements();
pipelineStateDescription.PrimitiveType = PrimitiveType.TriangleStrip;
出力記述
Output プロパティには、バインドされたすべてのレンダリングテクスチャーの数と PixelFormat を設定します。
レンダーテクスチャーをパイプラインにバインドする方法については、テクスチャーとレンダーテクスチャーを参照してください。
コード: 出力記述を作成する
var renderOutputDescription = new RenderOutputDescription(GraphicsDevice.Presenter.BackBuffer.Format, GraphicsDevice.Presenter.DepthStencilBuffer.Format);
pipelineStateDescription.Output = renderOutputDescription;
CaptureState(CommandList) を使って、CommandList に最後に設定された出力記述を取得することができます。これは、レンダーターゲットについて前もって知ることができない場合に MutablePipelineState と組み合わせると、特に便利です。
コード: 出力記述をキャプチャする
mutablePipelineState.State.Output.CaptureState(CommandList);
mutablePipelineState.Update();