シェーダは、通常我々は、頂点シェーダ、ジオメトリシェーダA、フラグメントシェーダ、これらは今サービス、計算シェーダ後の新しい4.3のOpenGL、汎用コンピューティングのための並列高速化を、グラフィックスレンダリングをラスタライズされている使用していますそれが導入されました。
計算シェーダを導入する必要性を導入する前にImageTextureを:
読み取り専用で共通のGLSLテクスチャ(サンプラのサンプリングデータ取得)、書き込みが任意の場所を指定することはできず、同時に読み取ることができない、結合したフラグメントシェーダバッファフレームに付属書のテクスチャ現在の画素に書き込まれなければなりませんテクスチャ付きライト(私はない試みたが、そこのブログには、それはそれを行うべきではないにも述べられていません)。
1、テクスチャを生成
ボイドWKS :: ImageTexture :: setupTexture(){ glGenTextures(1、&この - > textureID)。 glBindTexture(GL_TEXTURE_2D、この - > textureID); glTexStorage2D(GL_TEXTURE_2D、1 、GL_RGBA32F、幅、高さ)。 //は、フィルタリングとラップモードをオフにし glTexParameteri(GL_TEXTURE_2D、GL_TEXTURE_MIN_FILTER、GL_NEAREST)。 glTexParameteri(GL_TEXTURE_2D、GL_TEXTURE_MAG_FILTER、GL_NEAREST)。 glTexParameteri(GL_TEXTURE_2D、GL_TEXTURE_WRAP_S、GL_CLAMP)。 glTexParameteri(GL_TEXTURE_2D、GL_TEXTURE_WRAP_T、GL_CLAMP)。 glBindTexture(GL_TEXTURE_2D、0 ); }
テクスチャのサイズはglTexStorage2Dで固定()を生成する場合、そのノート、glTexImage2D()を使用することができません
2、ImageTextureを生成
glBindImageTexture(0、この - > inputTexture、0、GL_FALSE、0、GL_READ_ONLY、GL_RGBA32F)。
1相当inputTexture、テクスチャは、テクスチャIDを生成しました。最初のパラメータはImageTextureは重複しないようにしてくださいポイント、テクスチャ及びテクスチャ結合点に結合されます。
3、GLSLが宣言しました
レイアウト(rgba32f、結合= 0)均一image2Dのinput_image。
補足:ImageTexture底は、それがホストにアクセスすることができ、テクスチャであります
、初期設定、着信データ
ボイド WKS :: ImageTexture :: Transfer2Texture(フロート * データ){ glBindTexture(GL_TEXTURE_2D、この - > textureID)。 glTexSubImage2D(GL_TEXTURE_2D、0、0、0 、幅、高さ、GL_RGBA、GL_FLOAT、データ)。 }
B、データが読み込まれます
フロート * WKS ::テクスチャ:: GetTextureData(GLuint幅、高さGLuint、GLuintチャネル、GLuint texID){ フロート *データ= 新しい フロート [幅*高さ* チャネル]。 glBindTexture(GL_TEXTURE_2D、texID)。 もし(チャネル== 1)glGetTexImage(GL_TEXTURE_2D、0 、GL_RED、GL_FLOAT、データ)。 もし(チャネル== 3)glGetTexImage(GL_TEXTURE_2D、0 、GL_RGB、GL_FLOAT、データ)。 もし(チャネル== 4)glGetTexImage(GL_TEXTURE_2D、0 、GL_RGBA、GL_FLOAT、データ)。 glBindTexture(GL_TEXTURE_2D、0); 戻り値のデータ。 }
今紹介する計算 シェーダを:
#version 430 コア レイアウト(local_size_x = 16、local_size_y = 16)において、 均一なフロート V [ 4 ]; レイアウト(rgba32f、結合 = 0 )均一image2Dのinput_image。 レイアウト(rgba32f、結合 = 1 )均一image2Dのoutput_image。 共有vec4がmat_shared [ 16 ] [ 16 ]。 ボイドメイン(ボイド) { ivec2 POS = ivec2(gl_GlobalInvocationID.xy)。 mat_shared [pos.x] [pos.y] =imageLoad(input_image、POS)。 バリア(); vec4データ = mat_shared [pos.x] [pos.y]。 data.r = V [ 0 ] + data.r。 data.g = V [ 1 ] + data.g。 data.b = V [ 2 ] + data.b。 data.a = V [ 3 ] + data.a。 imageStore(output_image、pos.xy、データ)。 }
で完全なユニット、レイアウト(local_size_x = 16、local_size_y = 16)の計算は、組成物16 *の演算部16によるローカルワーキンググループであり、ワークグループは、ローカル変数にShaderedを共有することができます。
からなるローカルグローバル作業グループの複数からなるワーキンググループ:
glDispatchCompute(1、1、1)。
計算されたパラメータを起動すると、ワーキンググループ(ローカルユニットのためのワーキンググループ)、(1,1,1)のみローカルワークグループ手段のグローバルな次元を示します。
注:計算シェーダは一相(通常レンダリング頂点+断片2段階)、コンパイル型の選択であるGL_COMPUTE_SHADER
シェーダ(CONST 文字 * computePath):プログラムID(0 ) { のstd ::ベクトル <ShaderFile> fileVec。 fileVec.push_back(ShaderFile(GL_COMPUTE_SHADER、computePath))。 LOADFROMFILE(fileVec)。 }
例:
4×4行列プラスvec4のVec4全ての要素(0、0.1,0.2,0.3)
初期化:
ボイドSceneRendering :: setupAddData(){ int型 NUM = 4 * 4 * 4 。 この - >引数inputData = 新しい フロート[NUM]。 以下のために(INT iが= 0 ; I <NUM; I ++)引数inputData [I] = I。 以下のために(INT iが= 0 ; I < 4 V [I] = I *、I ++)を0.1F 。 shader_add = 新しいシェーダ(" ./Shader/add.comp " ); WKS :: ImageTexture * texturePtr = 新しいですWKS :: ImageTexture(4、4 ); この - > inputTexture = texturePtr-> GetTextureID(); この - > outputTexture =(新しい WKS :: ImageTexture(4、4)) - > GetTextureID(); texturePtr - > Transfer2Texture(引数inputData)。 }
計算シェーダを呼び出します。
空SceneRendering :: performCompute(){ この - > shader_add-> 使用(); この - > shader_add-> setVecN(" V "、4 、v)は、 glBindImageTexture(0、この - > inputTexture、0、GL_FALSE、0 、GL_READ_ONLY、GL_RGBA32F)。 glBindImageTexture(1、この - > outputTexture、0、GL_FALSE、0 、GL_WRITE_ONLY、GL_RGBA32F)。 glDispatchCompute(1、1、1 )。 glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT)。 glFinish(); }
メイン関数呼び出し、結果の出力:
glClearColor(0.5F、0.5F、0.5F、1.0F )。 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)。// 我们现在不使用模板缓冲// 計算シェーダー この - > performCompute(); フロート *データ= WKS ::テクスチャ:: GetTextureData(4、4、4、この - > outputTexture)。 int型のインデックス= 0 ; 以下のために(INT iが= 0 ; I < 4 ; I ++ ){ ため(INT J = 0 ; J < 4 ; J ++ ){ のstd :: COUT << " (" <<データ[インデックス] << " " <<データ[インデックス+ 1 ] << " " <<データ[インデックス+ 2 ] << " " <<データ[索引+ 3 ] << " )" << " " 。 インデックス + = 4 。 } のstd :: coutの < < はstd ::てendl; } std :: coutの << はstd ::てendl; 無料(データ);
画像: