2016-11-21 4 views
0

8つのテクスチャをサポートするテクスチャ/テレインスプラッティングGLSLシェーダに取り組んでいます。GLSLシェーダ:var Aの半分の色値、他の半分のvar B、条件付きの文なし

私が作成した最初のバージョンはRGBAを入力として使用しました。各チャンネルは各テクスチャの強度です。

2番目のバージョン「チャネル」を半分に分割して倍増させようとしました。例えば;テクスチャのTexture1

  • R64 =半分に

    • R0 =何もしない1
    • R127 =フルテクスチャ1
    • R128 =何もテクスチャ5
    • R196 =半分のテクスチャ5
    • R254 =フルテクスチャ5

    などです。

    私はシェーダのif文が非常に悪い練習であることを知りました。何か間違ったことをするように感じました。

    問題は、各チャネルの半分を完全な変数として使用するための数学関数がわかりません。

    フラグメントシェーダコードは次のとおりです。

    varying vec2 v_vTexcoord; 
    varying vec4 v_vColour; 
    
    uniform sampler2D texture; //Texture 
    
    uniform float surfWidth; 
    uniform float surfHeight; 
    
    uniform float xpos; 
    uniform float ypos; 
    
    void main() 
    { 
        //Setting the main texture position 
        vec2 texpos = (v_vTexcoord*vec2(surfWidth, surfHeight)) +  vec2(xpos, ypos); 
    
        //Modulo 1 for repeat, devide by 4 because its a 4x4 texture sheet 
        float tpx = mod(texpos.x,1.0)/4.0; 
        float tpy = mod(texpos.y,1.0)/4.0; 
    
        //Setup terrain "intensities" 
        float t1 = 0.0; 
        float t2 = 0.0; 
        float t3 = 0.0; 
        float t4 = 0.0; 
        float t5 = 0.0; 
        float t6 = 0.0; 
        float t7 = 0.0; 
        float t8 = 0.0; 
    
        //Load from the surface (splatmap) 
        float btr = (v_vColour * texture2D(gm_BaseTexture,  v_vTexcoord)).r; 
        float btg = (v_vColour * texture2D(gm_BaseTexture, v_vTexcoord)).g; 
        float btb = (v_vColour * texture2D(gm_BaseTexture, v_vTexcoord)).b; 
        float bta = (v_vColour * texture2D(gm_BaseTexture, v_vTexcoord)).a; 
    
        //Calculating what texture to use (also deviding each channel into  2) 
        if (btr <= 0.5) { 
         t1 = btr*2.0; 
        } else { 
         t5 = (btr-0.5)*2.0; 
        } 
    
        if (btg <= 0.5) { 
         t2 = btg*2.0; 
        } else { 
         t6 = (btg-0.5)*2.0; 
        } 
    
        if (btb <= 0.5) { 
         t3 = btb*2.0; 
        } else { 
         t7 = (btb-0.5)*2.0; 
        } 
    
        if (bta <= 0.5) { 
         t4 = bta*2.0; 
        } else { 
         t8 = (bta-0.5)*2.0; 
        } 
    
        //Get terrain pixels at proper positions 
        vec4 ter1 = texture2D(texture, vec2(tpx, tpy)); 
        ter1.a = t1; 
        vec4 ter2 = texture2D(texture, vec2(tpx+0.25, tpy)); 
        ter2.a = t2; 
        vec4 ter3 = texture2D(texture, vec2(tpx+0.50, tpy)); 
        ter3.a = t3; 
        vec4 ter4 = texture2D(texture, vec2(tpx+0.75, tpy)); 
        ter4.a = t4; 
    
        vec4 ter5 = texture2D(texture, vec2(tpx, tpy+0.25)); 
        ter5.a = t5; 
        vec4 ter6 = texture2D(texture, vec2(tpx+0.25, tpy+0.25)); 
        ter6.a = t6; 
        vec4 ter7 = texture2D(texture, vec2(tpx+0.50, tpy+0.25)); 
        ter7.a = t7; 
        vec4 ter8 = texture2D(texture, vec2(tpx+0.75, tpy+0.25)); 
        ter8.a = t8; 
    
        //Output to screen 
        gl_FragColor = 
        ter1*vec4(t1) + 
        ter2*vec4(t2) + 
        ter3*vec4(t3) + 
        ter4*vec4(t4) + 
        ter5*vec4(t5) + 
        ter6*vec4(t6) + 
        ter7*vec4(t7) + 
        ter8*vec4(t8); 
    } 
    

    テクスチャが重複している場合、彼らは明るく」を取得、また、私は私がclamp()またはlerp()のようなものを必要とするつもりだということはかなり確信しているが、私はそれのまわりで私の頭をラップすることはできません。..

    "(両方のテクスチャが最後のステートメントに単純に追加されているので...どのように起こるのを防ぐことができず、テクスチャ自体の「最大」を常に出力するかはわかりません(「点灯」しないように)。私がばかげて聞こえたら、私の最初の本当のシェーダです。:)

  • 答えて

    1

    現代的なハードウェアでは、ブランチはそれほど大きくないとは限りません潜在的にかなりの労力を節約することができます。あなたのアプローチを使用すると、同じ色チャネル(すなわちブレンドT1およびT5)にパックされている2つの「スプラッティングチャンネル」をブレンドすることができないこと

    btr *= 2.; 
    t1 = fract(min(btr,1.)); 
    t5 = max(btr-1.,0.); 
    

    注:枝wihoutあなたのロジックを書くことは、このようになります。別のスプラットマップをサンプリングするほうが簡単です(おそらくより効率的です)。

    最終出力をブレンドすることについては、線形にブレンドしたいと仮定して、個々の重みをすべての重みの合計で除算します。

    float sum = t1+t2+t3+t4+t5+t6+t7+t8; 
    gl_FragColor = ter1*(t1/sum) + ter2*(t2/sum) + ter3*(t3/sum) + ... 
    
    +1

    驚くばかり!ありがとう:)私はちょうど正しくsplatmapを生成することができる必要があります..しかし、これは私のシェーダーの問題を修正!再度ありがとう:)あなたはすぐにwww.shootmup.comで結果を見るでしょう –

    関連する問題