This project is read-only.

Stream Output Stage

Stream Output Stageとは

Stream Output(以下SO)とは、DirectX10より使用可能となった新しいシェーダーの仕様です。
以下がSM5.0における描画パイプラインとなります。
(SM4.0の場合は、Hull Shader Stage,Tessellator Stage,Domain Shader Stageが存在しません。)

Stream Output Stageとは、バーテックスシェーダー、もしくはジオメトリシェーダーから出てくるデータを一度バッファに保管する機能です。これを用いることで、MME/MMMのシェーダーの互換性に関する問題を解決することが可能になります。

MME/MMMのシェーダーの互換性問題

MMMのシェーダーはMMEのシェーダーを基に作成されているため、基本的な仕様はMMEと似ているものの、MMM用のシェーダーとしてある程度の書き換えをしなければMMEのシェーダーを利用できません。
これは主にスキニング処理の実装の差によるものです。
MMEでは、MMDよりCPUによるスキニング処理後の頂点情報を受け取りますが、MMMでは、元の頂点情報を渡し、スキニング処理はGPU上で行います。
MMMの場合はスキニング処理を頂点シェーダーで書かなければならず、スキニングを頂点シェーダーで書く必要のないMMEからは少々面倒な変更が必要となります。

MMFでは、初期の入力は以下のMMM型シェーダー入力が利用されますが、次の節で解説する記述を利用することにより、入力前に変換用のジオメトリシェーダーが介されます。

MMM型シェーダー入力
struct GPU_SKINNING_INPUT
{
	float4 Pos:POSITION;//頂点位置
	float4 BoneWeight:BLENDWEIGHT;
	uint4 BlendIndices:BLENDINDICES;//MMM公式仕様ではfloat4であるが、多くの場合そのまま利用できる。
	float3 Normal:NORMAL;
	float2 Tex:TEXCOORD0;
	float4 AddUV1:TEXCOORD1;
	float4 AddUV2:TEXCOORD2;
	float4 AddUV3:TEXCOORD3;
	float4 AddUV4:TEXCOORD4;
	float4 SdefC:TEXCOORD5;
	float3 SdefR0:TEXCOORD6;
	float3 SdefR1:TEXCOORD7;
	float EdgeWeight:TEXCOORD8;
	uint Index:PSIZE15;//MMM公式仕様ではfloatであるが多くの場合そのまま利用できる
};
#define MMM_SKINNNING_INPUT GPU_SKINNING_INPUTが自動的に定義されることにより、MMMのシェーダーは書き換えなくともコンパイルが可能です。

MME型シェーダー入力
struct SKINNED_INPUT
{
 float4 Pos:POSITION;
 float3 Normal:NORMAL;
 float2 Tex:TEXCOORD0;
 float4 AddUV1:TEXCOORD1;
 float4 AddUV2:TEXCOORD2;
 float4 AddUV3:TEXCOORD3;
 float4 AddUV4:TEXCOORD4;
 uint Index:PSIZE15;
};

SOによるこの問題の解決

SOを利用するためにはSM4.0以上のシェーダーモデルが利用できなければなりません。
MMFはSM4.1以上が利用できるので、この問題を解決することができます。
以下の図のように、SOにより、一度データの変換用のジオメトリシェーダーを経由することで、それぞれのシェーダーに対応したフォーマットに変換されます。この変換処理はGPU上で行われるため、MMEのシェーダーを利用してもGPUでスキニングされることになります。

エフェクトの多重適用

以下の例は舞力介入Pとの会議において舞力介入Pから指摘していただいたものを少し噛み砕いて記述したものです。

SOを利用することで同一モデルに対しエフェクトを多重適用することが可能です。

一つのモデルに
(1) Tesselation使用の独自スキニングエフェクト
(2) 捩りエフェクト
(3) Cloneエフェクト
(4) Mechanicシェーダ
(5) Adultシェーダ
と複数のエフェクトを同時適用した場合、(1)~(3)についてはSOを利用することにより、頂点入力を(1)→(2)→(3)という形で受け渡すことにより直列で実行する。
(4)、(5)についてはアルファブレンディングで合成し、(1)~(5)のエフェクトを同時に一つのモデルに適用できるようにする。

SO用のテクニックの拡張

スキニング入力の変換拡張

SOによる変換を行うためには以下のアノテーションをテクニックまたはパスに指定します。
string Skinning=""設定値;
設定値に指定できるのは以下の二つの値のどちらかです。
  • pre
頂点シェーダに入る頂点情報はスキニング前のデータになります。すなわちMMM側のシェーダーの入力に等しい形で入力されます。
  • post
変換用シェーダーが介されます。すなわちMME側のシェーダー入力に等しい形で頂点シェーダに入力されます。

デフォルトでは、preが指定されます。

複数シェーダー適用のための拡張

パスは以下の場合、SOとして処理される。
SetPixelShader及びSetComputeShaderの両方に対しNULLが指定された場合。

この場合、頂点シェーダーもしくはジオメトリシェーダーが返す頂点情報が、次に指定されたエフェクトファイルの入力となる。
ただし、これらのシェーダーの返す頂点情報は必ずSKINNED_INPUTとして解釈される。

残る問題点

MMFは上記の解決手法によって、MMMとMMEのシェーダーを両方とも読み込むことが可能になります。
ただし、完全に書き換えが必要ないというわけではありません。これは、SM3.0からSM5.0への変換が必要となるためです。
techniqueキーワードをtechnique10(もしくはtechnique11)に変換することや、一部のセマンティクスを変換するだけなので、簡単なアプリケーションで自動的に変換することが可能になると思われます。

Last edited Apr 18, 2014 at 10:17 PM by DaikonTakuan, version 16

Comments

No comments yet.