2017-01-08 6 views
2

Ich habe ein Netz, das ich rotiere und mich bewege. Ich möchte nur einen Teil davon zeichnen.Zeichnen Sie nur einen Teil eines Netzes in WebGL

ZB:

GameImage

In meinem WebGL Spiel, ich habe eine Spur Karte mesh, und ich möchte nur den Teil zeigen, die in dem roten Kreis ist (oben links), der Rest Ich will nicht gezeichnet werden.

Sollte ich mit einem Fragment-Shader arbeiten? Oder kann ich dem Track-Map-Mesh irgendwie sagen, dass es nur den Teil des Kreises zeichnen soll?

Danke!

PS: Es wäre großartig, wenn ich die Trackkarte um den Kreis herum ausbleichen könnte, anstatt sie einfach abzuschneiden. :-)

Antwort

6

Es gibt mehrere Möglichkeiten, dies zu erreichen, für einen einfachen rechteckigen Ausschnitt Sie scissor testing wie diese verwenden:

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

Für einen kreisförmigen Ausschnitt Sie einen Schablonenpuffer verwenden könnte, um eine Platte die zeichnen Stencil Buffer, schablonieren und zeichnen Sie Ihre Spur, dies erfordert jedoch, dass Sie Ihre Rendering-Pipeline mit einem Framebuffer mit einem angehängten Stencil-Puffer, der ein wenig überwältigend sein kann und nur einen scharfen Ausschnitt gibt.

ein eigenes Fragment-Shader verwenden und in Kombination mit dem oben genannten Scheren rect Vermischung scheint, wie die vernünftigste Lösung hier, Setup Ihre Scheren, wie zuvor beschrieben, dann in den Fragment-Shader:

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.)); 
} 

Was wir sind Hier wird der Abstand unseres aktuellen Pixels zum Mittelpunkt der Scherenregion berechnet (in der linken oberen Ecke des Bildschirms wird 256x256 angenommen), dann wird ein lineares Ausblenden zwischen 100 und 128 durchgeführt. Das Ergebnis ist eine Maske, die so aussieht :

result

Beachten Sie, dass wir den Scheren-Test technisch nicht mehr benötigen, da die Maske im Fragment-Shader alles außerhalb des kreisförmigen Bereichs maskiert. Der Scissor-Test stellt jedoch sicher, dass wir den Fragment-Shader nur dort ausführen, wo wir ihn brauchen.

+0

Vielen Dank! Das hat perfekt funktioniert und auch eine ausgezeichnete Erklärung. – Craigo

3

Da Sie auch die Trackmap im Kreisbereich ausblenden möchten, wäre eine schnelle und schmutzige Lösung die Verwendung eines Fragment - Shaders, bei dem Fragmente außerhalb des Kreisbereichs verworfen werden und bei denen der Alpha - Wert linear entlang der Linie interpoliert wird Entfernung vom Zentrum.

Das Fragment-Shader mehr oder weniger würde so aussehen

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); 
} 

Denken Sie daran, dies ist nur eine der vielen Lösung ist, dass Sie für dieses spezielle Problem nutzen könnten. Sie können dies direkt innerhalb des Vertex-Shaders tun, indem Sie Vertices außerhalb des Kreisbereichs verwerfen oder einen Stencil-Puffer einrichten, um genau das gleiche zu erreichen.

Verwandte Themen