2011-07-03 12 views
6

これは長いですが、面白いことを約束します。 :)GLSLでの複数テクスチャのブレンド

私は、jMonkeyEngineを使用して別のアプリケーションのテクスチャの外観を模倣しようとしています。私は頂点のリストを持っていて、 "風景メッシュ"を構成する面(三角形)は、(風景の地形に応じて)約7-15の異なるテクスチャでテクスチャ化する必要があります。各三角形には、それに関連するテクスチャコードがあり、そのテクスチャが主に構成すべきテクスチャを示します。もちろん、テクスチャは各面の間で滑らかに混ざり合っている必要があります。

私はこれを可能にする戦略を開発しようとしています(あらかじめ作成されたアルファマップPNGファイルを利用しないで、実行時にテクスチャアルファを実行する必要があります)。今は、頂点シェーダの各頂点で各テクスチャの「強さ」を計算すると、それは隣接するすべての面の地形タイプを考慮に入れることで(これを行う方法はわかりません)ピクセルが頂点からどのくらい離れているかに基づいてアルファ値を設定します。生成された「アルファマップ」は、ピクセルごとに各テクスチャをブレンドするために、フラグシェーダによって使用されます。

これは実現可能なのでしょうか、まったく別の戦略を検討する必要がありますか?私は私が模倣しようとしている(しかし、彼らはHLSLであり、私はGLSLを使用しています)アプリケーションのためのシェーダコードを持っているが、彼らが他の場所で、このブレンド工程やっているように思える:

sampler MeshTextureSampler = sampler_state { Texture = diffuse_texture; AddressU = WRAP; AddressV = WRAP; MinFilter = LINEAR; MagFilter = LINEAR; }; 

を私はこのHLSL「MeshTextureSampler」が何であるかは不明ですが、このアプリケーションでは必要に応じてすべてのテクスチャをあらかじめブレンドしておき、顔/地形のコードデータに基づいてメッシュ全体に対して単一のテクスチャを作成するようです。それはちょうど影、照明、などですその後

float4 tex_col = tex2D(MeshTextureSampler, In.Tex0); 

- 私をリード私の知る限りでは、すべてのテクスチャブレンディングのない並べ替え、:ピクセル/フラグメントシェーダでは、彼らが本当にやるように見えるすべてが、このありませんこのテクスチャのブレンド作業がCPU上であらかじめ実行されていると私は考えています。どんな提案も大歓迎です。私が正しくあなたを理解していれば

+0

+1最初の文に+1してください。 –

答えて

3

は、ここに私の最初のショットがどうなるかです:

あなたの問題は、多かれ少なかれ、どのように頂点の上にあなたのあたりの顔値を分配すること、です。これは、実際にはメッシュ上の通常の世代と似ています。まず、各三角形の法線を生成し、それを頂点ごとに計算します。 Googleの "通常の世代"とあなたはそこに着くだろうが、ここに要点がある。隣接する各三角形について、重み付け係数(しばしば、頂点を使用するコーナーの角度、または三角形の表面積、またはその組み合わせ)を見つけ、その値を合計します(通常の場合または「強さ」の場合)計量係数で合計の結果にする。ノーマライズすると完了です。

だから、頂点シェーダに送ることができるテクスチャ「強さ」があります。近代的な解決方法は、ピクセルシェーダーで文字を使用し、テクスチャ配列をサンプリングすることです。

だから、私が正しくあなたの問題を取得する場合:

を前処理:

forearch vertex in mesh 
    vertexvalue = 0 
    normalization = 0 
    foreach adjacent triangle of vertex 
     angle = calculateAngleBetween3Vertices(vertex,triangle.someothervertex,triangle.theotherothervertex) 
     vertexvalue += triangle.value * angle 
     normalization += angle 
    vertexvalue/=normalization 

レンダリング時間:fragmentshaderに各頂点の値(S)、およびはでこれを行う

パイプをフラグメントシェーダ:

basecolour = 0; 
foreach value  
    basecolour = mix(basecolour, texture2D(textureSamplerForThisValue,uv), value) 
    //this is simple, but we could do better once we have this working 

また、あなたのジオメトリで。大きな三角形と小さな三角形を組み合わせた場合、データの不均一な広がりがあり、データが頂点ごとにあるため、より多くのジオメトリが詳細に表示されます。その場合、おそらく他の人がやっていることをやり、ブレンドマップを使ってジオメトリからテクスチャリングを切り離したいと思うでしょう。これらは低解像度であり、メモリ消費量やシェーダの実行時間をそれほど増やすべきではありません。

+0

私が立ち往生しようとしているのは、一般に、「それぞれの隣接する三角形について、計量係数を見つけてください...」 - どこでこれを行うのですか?そして、シェーダー内からどのようにアクセスするのですか?まだこれを視覚化するのに苦労しています。 – Manius

+0

あなたはしません。これは単なる前処理段階です(値はレンダリング時に静的です)。すべての三角形に対して1の重み付け係数が機能するはずですが、それは高品質です。さもなければ頂点に触れる三角コーナーの角度としてそれを取ることができます。頂点の値はFOREACHNの値になります+ angle_of_triangle * value_at_triange –

+0

私は考えられた解決策を考えましたが、これをもう一度読んで、基本的にはあなたが提案したものと同じだと思います。私は、すべての頂点に対して「重み付けされた」アルファ値(テクスチャごと)を渡してみようと思っています。そして、その部分をテクスチャアルファとして使用してください。 (これはあなたが言っていることですか?)私はjMonkeyEngineでこれを行う方法を決定するのに苦労していましたが、このデータを "texCoordX"頂点バッファタイプとして頂点属性として渡すことができればと思っています。あなたが提案したように、エリア/角度を使って体重を計算するだけです... – Manius