2017-01-08 10 views
2

私は回転して移動するメッシュを持っています。私はその一部を描くだけです。WebGLのメッシュの部分だけを描画します

例:私のWebGLのゲームでは

GameImage

、私はトラックマップメッシュを持っている、と私は唯一の(左上の)赤い円の中にある部分、残りの部分を表示したいです私は描かれたくありません。

フラグメントシェーダーの使用を検討する必要がありますか?あるいは、私は何とかトラックマップメッシュに円の中にある部分だけを描画するように指示することはできますか?

ありがとうございます!

PS:トラックマップを円の周りに消してしまえば、それをカットするのではなく、素晴らしいことになるでしょう。 :-)

答えて

6

これを達成するために、いくつかの方法は、あなたがこのようなscissor testing使用することができ、単純な長方形の穴のため、ありますにディスクを描き、あなたはステンシルバッファを使用することができ、円形の切​​り欠き部について

gl.enable(gl.SCISSOR_TEST); 
gl.scissor(0,gl.canvas.clientHeight-256,256,256); 
// draw track here 
gl.disable(gl.SCISSOR_TEST); 

をステンシルバッファを有効にし、ステンシルを有効にしてトラックを描画する必要がありますが、ステンシルバッファが付いたフレームバッファを使用してレンダリングパイプラインをセットアップする必要があります。その後、フラグメントシェーダでは、前述のように

カスタムフラグメントシェーダを使用し、前述のはさみRECTと組み合わせて配合するには、ここで最も賢明な解決策、セットアップあなたのはさみのように思える:私たちがしているもの

void main(void) { 
    // do what you need to do to get the final color 
    gl_FragColor.rgb = finalColor; 
    gl_FragColor.a = smoothstep(128.,100.,length(min(vec2(gl_FragCoord.x,resolution.y-gl_FragCoord.y),256.)-128.)); 
} 

ここでは、現在のピクセルとシザー領域の中心との距離を計算します(スクリーンの左上隅の256x256と仮定します)。次に100と128の間の線形フェードアウトを実行します。 結果は次のようなマスクです:

result

技術的には、フラグメントシェイダーのマスクが円形領域外のすべてをマスクするため、技術的にはシザーテストは必要ありません。しかし、はさみテストを維持することで、必要なところでフラグメントシェーダの作業を行うだけです。

+0

ありがとうございました!それは完璧に機能し、優れた説明もありました。 – Craigo

3

円領域内のトラックマップをフェードさせたいので、素早く汚れた解決策は、フラグメントシェーダを使用することです。円領域外のフラグメントは破棄され、内側のフラグメントはアルファ値が線形に補間されます中心からの距離。

フラグメントシェーダは、多かれ少なかれ、これはちょうどあなたがこの特定の問題のために使用することができ、多くの解決策の一つである点に注意してください。この

precision mediump float; 

varying vec3 Color; 

uniform vec2 MapPos;  //map's center position in screen pixels 

//constant value to decide how big the red area is 
const float circle_radius = 90.0; 
const float falloff  = 1.0; 

void main() 
{ 
    float distance = length(FragCoord.xy - MapPos.xy); 
    if(distance > circle_radius) discard; //discarding fragments outside circle area 

    //alpha fades from 1 to 0, falloff decides how strong the fade is on the edge of the circle 
    float alpha = pow(1.0 - distance/90.0, falloff); 
    gl_FragColor = vec4(Color, alpha); 
} 

ようになります。サークル領域外の頂点を破棄するか、同じ正確なものを得るためにステンシルバッファを設定することで、頂点シェーダの内部で直接行うことができます

関連する問題