マルチプルレンダーターゲット
2019年9月24日 (火) 02:41時点におけるimported>Administratorによる版
対応状況
- DirectX 9から使えるが、DirectX 9.0cくらいまでは対応・非対応の製品が乱立していた。
- MonoGameではHiDefに設定すると使える。
- OpenGL ESではOpenGL ES 3.0以降で使える。
概要
3DテレビやVR
3DテレビやVR向けに映像を出力する際には、人間の目と目の間隔分だけ微妙にカメラ視点をズラした2つの画像を出力する。つまり1フレームを表示するには「右目用」と「左目用」の2枚の画像を描くことになる。
シェーダーは「実行速度」よりも「起動速度」が段違いに遅いので呼び出す回数を減らせれば劇的に速くなる。つまりカメラの座標がちょっと違うだけなのに2回もシェーダーを回すとかまったくイケてない。
そこで出力先のレンダーターゲット(テクスチャ)を複数指定できるようにすれば1回のシェーダー呼び出しで完結できるじゃないか、という代物である。
遅延レンダリング
遅延レンダリングでは「色」や「法線」、「深度」などを複数のレンダーターゲットに出力する。
ならば出力先のレンダーターゲットを複数指定できるようにすれば1回のシェーダー呼び出しで完結できるじゃないか、という代物である。
メリット
シェーダーの呼び出し、いわゆる「Drawコール」が減る。
デメリット
当然ながらMRT向けにシェーダーを書き直さなければならない。
COBOLやJavaやPHPを愛するIT土方的な考えであれば「既存のシェーダーを2回呼び出せばいいじゃん」となるところである。
一方、ゲーム業界はそこへ突撃して「このゲームのここがすごい!」と宣伝材料にしようとする。
彼らは相見えない。「プログラマー」と一括にはできないほど根本的な思想に違いがある。
記述例
ピクセルシェーダーの戻り値を構造体にして一度に複数の色を返す感じになる。 HLSLの記述例。
// Rec. 709グレースケール変換定数
const float3 luma = float3(0.2126, 0.7152, 0.0722);
// ピクセルシェーダー出力
struct PS_OUTPUT
{
float4 rgba:COLOR0; //RendarTargetの0番目に出力
float4 gray:COLOR1; //RendarTargetの1番目に出力
};
// ピクセルシェーダー本体
// 一般的なピクセルシェーダーの戻り値はRGBAを表す「float4」だが、
// マルチプルレンダーターゲットでは構造体で複数の色を返す。
PS_OUTPUT psMain( float2 texCoord:TEXCOORD )
{
PS_OUTPUT psout;
// そのまま出力
float4 color = tex2D(ScreenTexSampler,texCoord);
psout.rgba = color;
// グレースケールに変換して出力
float gray = dot(color.rgb, luma);
psout.gray = float4(gray,gray,gray,1);
return psout;
}