Deferred系技術を知っておかねばならない状況に置かれそうなので…
まずはDeferred系をやる前の準備としてMRT(Multi Render Target)をやってみました。
自前ライブラリを新規作成中でまだ出来上がっていない状態なので,サンプルがしょっぱいのは勘弁してください。
Multi Render Target
★ 1.はじめに…
★ 2.MRTとは…
MRTは一度のレンダリングパスで複数バッファに異なる値を同時出力する機能です。KILLZONE2では4枚同時出力しているとのことなので,サンプルも4枚同時出力にしてみました。
さてOpenGLでの実装ですが,シンプルです。フレームバッファオブジェクトで,いつも1回だけ呼んでいるglFramebufferTexture2DEXT()を出力バッファ数分呼びます。このとき引数には出力先となるカラーアタッチメントを指定しておきます。
次に,フレームバッファをバインドしglDrawBuffers()を使って,描画するカラーバッファのリストを指定します。あとは普通に描画するだけ。
GL側の処理は以上。シェーダ側はピクセルシェーダの出力をいつもはCOLORになっているものをCOLOR0〜COLOR3として,出力したいバッファに値を出力するように変更します。
たぶんコードみた方がわかりやすいと思うので,下記のコードを参照してください。
さて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を用いています。
本ソースコードおよびプログラムは自己責任でご使用ください。
プログラムの作成にはMicrosoft Visual Studio 2008 SP1 Professional, NVIDIA Cg Toolkit 3.0 July 2010を用いています。