Multi Render Target


 1.はじめに…
Deferred系技術を知っておかねばならない状況に置かれそうなので…
まずはDeferred系をやる前の準備としてMRT(Multi Render Target)をやってみました。
自前ライブラリを新規作成中でまだ出来上がっていない状態なので,サンプルがしょっぱいのは勘弁してください。




 2.MRTとは…
MRTは一度のレンダリングパスで複数バッファに異なる値を同時出力する機能です。KILLZONE2では4枚同時出力しているとのことなので,サンプルも4枚同時出力にしてみました。
さてOpenGLでの実装ですが,シンプルです。フレームバッファオブジェクトで,いつも1回だけ呼んでいるglFramebufferTexture2DEXT()を出力バッファ数分呼びます。このとき引数には出力先となるカラーアタッチメントを指定しておきます。
次に,フレームバッファをバインドしglDrawBuffers()を使って,描画するカラーバッファのリストを指定します。あとは普通に描画するだけ。
GL側の処理は以上。シェーダ側はピクセルシェーダの出力をいつもはCOLORになっているものをCOLOR0〜COLOR3として,出力したいバッファに値を出力するように変更します。
たぶんコードみた方がわかりやすいと思うので,下記のコードを参照してください。
00081:  ///----------------------------------------------------------------------
00082:  ///<summary>
00083:  ///初期化処理
00084:  ///</summary>
00085:  ///----------------------------------------------------------------------
00086:  bool MRTRenderer::Initialize()
00087:  {
00088:      const int WIDTH = 512;
00089:      const int HEIGHT = 512;
00090:  
00091:      // GLEWの初期化
00092:      if ( glewInit() != GLEW_OK )
00093:      {
00094:          return false;
00095:      }
00096:  
00097:      // テクスチャ4枚生成
00098:  	glGenTextures( 4, mTexture );
00099:  
00100:      // 4枚分の設定をしておく
00101:      glEnable( GL_TEXTURE_2D );
00102:      for( int i=0; i<4; i++ )
00103:      {
00104:          glBindTexture( GL_TEXTURE_2D, mTexture[i] );
00105:          glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
00106:      	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
00107:      	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
00108:      	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
00109:          glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
00110:          glBindTexture( GL_TEXTURE_2D, 0 );
00111:      }
00112:      glDisable( GL_TEXTURE_2D );
00113:  
00114:      // レンダーバッファの設定
00115:      glGenRenderbuffersEXT( 1, &mRenderBuffer );
00116:      glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, mRenderBuffer );
00117:      glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, WIDTH, HEIGHT );
00118:  
00119:      // フレームバッファの設定
00120:      glGenFramebuffersEXT( 1, &mFrameBuffer );
00121:      glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mFrameBuffer );
00122:      glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexture[0], 0 );
00123:      glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mTexture[1], 0 );
00124:      glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, mTexture[2], 0 );
00125:      glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT3_EXT, GL_TEXTURE_2D, mTexture[3], 0 );
00126:      glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mRenderBuffer );
00127:      glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
00128:  
00155:  ///----------------------------------------------------------------------
00156:  ///<summary>
00157:  ///レンダリング処理
00158:  ///</summary>
00159:  ///----------------------------------------------------------------------
00160:  void MRTRenderer::Render()
00161:  {
00162:      // フレームバッファをバインド
00163:      glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, mFrameBuffer );
00164:  
00165:      // 4枚に出力
00166:      GLuint attachments[4] = 
00167:      {
00168:          GL_COLOR_ATTACHMENT0_EXT,
00169:          GL_COLOR_ATTACHMENT1_EXT,
00170:          GL_COLOR_ATTACHMENT2_EXT,
00171:          GL_COLOR_ATTACHMENT3_EXT,
00172:      }; 
00173:      glDrawBuffers( 4, attachments );
00174:  
00175:      // ビューポート設定
00176:      glViewport( 0, 0, 512, 512 );
00177:  
00178:      // FBOのバッファをクリア
00179:      glClearColor( 100.0/255.0f, 149.0f/255.0f, 237.0f/255.0f, 1.0f );
00180:      glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00181:   
00182:      // シェーダで描画
00183:      for( unsigned int i=0; i<mpEffect->GetNumPasses( 0 ); ++i )
00184:      {
00185:          cgSetPassState( mpEffect->GetPass( 0, i ) );
00186:      	glBegin( GL_TRIANGLES );
00187:      	glVertex3f( -0.75f, -0.75f, 0.0f );
00188:      	glVertex3f( 0.0f, 0.75f, 0.0f );
00189:      	glVertex3f( 0.75f, -0.75f, 0.0f );
00190:      	glEnd();
00191:          cgResetPassState( mpEffect->GetPass( 0, i ) );
00192:      }
00193:  
00194:      // ビューポートを元に戻す
00195:      int width = SampleProgram::DemoApp::GetInstance()->GetWidth();
00196:      int height =  SampleProgram::DemoApp::GetInstance()->GetHeight();
00197:      glViewport( 0, 0, width, height );
00198:  
00199:      // フレームバッファのアンバインド
00200:      glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
00201:  }
				
つづいてシェーダ側です。
00019:  ////////////////////////////////////////////////////////////////////////
00020:  // VSInput structure
00021:  ////////////////////////////////////////////////////////////////////////
00022:  struct VSInput
00023:  {
00024:      float4 Position : POSITION;
00025:      float2 TexCoord : TEXCOORD0;
00026:      float3 Normal : NORMAL;
00027:  };
00028:  
00029:  /////////////////////////////////////////////////////////////////////////
00030:  // VSOutput structure
00031:  /////////////////////////////////////////////////////////////////////////
00032:  struct VSOutput
00033:  {
00034:      float4 Position : POSITION;
00035:      float2 TexCoord : TEXCOORD0;
00036:      float3 Normal : TEXCOORD1;
00037:  };
00038:  
00039:  /////////////////////////////////////////////////////////////////////////
00040:  // PSOutput structure
00041:  /////////////////////////////////////////////////////////////////////////
00042:  struct PSOutput
00043:  {
00044:      float4 Color0 : COLOR0;
00045:      float4 Color1 : COLOR1;
00046:      float4 Color2 : COLOR2;
00047:      float4 Color3 : COLOR3;
00048:  };
00049:  
00050:  //----------------------------------------------------------------------
00051:  // Name : VSFunc()
00052:  // Desc : 頂点シェーダ
00053:  //----------------------------------------------------------------------
00054:  VSOutput VSFunc( VSInput input )
00055:  {
00056:      VSOutput output = (VSOutput)0;
00057:  
00058:      output.Position = mul( input.Position, WVP );
00059:      output.TexCoord = input.TexCoord;
00060:      output.Normal = input.Normal;
00061:  
00062:      return output;
00063:  }
00064:  
00065:  //----------------------------------------------------------------------
00066:  // Name : PSFunc()
00067:  // Desc : ピクセルシェーダ
00068:  //----------------------------------------------------------------------
00069:  PSOutput PSFunc( VSOutput input )
00070:  {
00071:      PSOutput output = (PSOutput)0;
00072:  
00073:      output.Color0 = float4( 1.0f, 0.0f, 0.0f, 1.0f );
00074:      output.Color1 = float4( 0.0f, 1.0f, 0.0f, 1.0f );
00075:      output.Color2 = float4( 0.0f, 0.0f, 1.0f, 1.0f );
00076:      output.Color3 = float4( 1.0f, 1.0f, 1.0f, 1.0f );
00077:  
00078:      return output;
00079:  }
				


 Download
本ソースコードおよびプログラムを使用したことによる如何なる損害も製作者は責任を負いません。
本ソースコードおよびプログラムは自己責任でご使用ください。
プログラムの作成にはMicrosoft Visual Studio 2008 SP1 Professional, NVIDIA Cg Toolkit 3.0 July 2010を用いています。







Flashを利用するためにはPluginが必要です。 <!-- </body> -->