Table of Contents

パイプライン ステート

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 クラスには、よく使われるブレンドステートのセットが定義されています。

コード: ブレンドステートを設定する

// ありふれたブレンドステートの設定
// 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 をパイプラインにバインドするには、EffectBytecodePipelineStateDescriptionRootSignature プロパティを、エフェクトの一致する値に設定します。

EffectBytecode には、実際のシェーダープログラムが含まれています。詳細については、エフェクトとシェーダーを参照してください。

RootSignature には、エフェクトが必要とするリソースの数と種類が記述されています。次の章では、パイプラインにリソースをバインドする方法について説明します。

コード: エフェクトのバインド

var effectInstance = new EffectInstance(EffectSystem.LoadEffect("MyEffect").WaitForResult());
pipelineStateDescription.EffectBytecode = effectInstance.Effect.Bytecode;
pipelineStateDescription.RootSignature = effectInstance.RootSignature;

入力レイアウト

パイプラインステートには、InputElementsPrimitiveType を介して頂点がデバイスに送られる際のレイアウトを記述します。

頂点の描画のページでは、カスタム頂点バッファの作成方法とその VertexDeclaration について詳しく説明しています。

コード: 入力レイアウトを設定する

VertexDeclaration vertexDeclaration = new 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();