Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only draw part of a mesh in WebGL

I have a mesh that I rotate and move around. I would like to only draw part of it.

Eg:

GameImage

In my WebGL game, I have a track map mesh, and I only want to show the part that is in the red circle (on the top left), the rest I don't want drawn.

Should I be looking into using a fragment shader? Or can I somehow tell the track map mesh to only draw the part that is in the circle?

Thanks!

PS: It would be great if I could fade the track map out around the circle, instead of just cutting it off. :-)

like image 364
Craigo Avatar asked Jan 28 '26 04:01

Craigo


1 Answers

There are several ways to achieve this, for a simple rectangular cutout you could use scissor testing like this:

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

For a circular cutout you could use a stencil buffer, draw a disk to the stencil buffer, enable stenciling and draw your track, this however requires you to setup your rendering pipeline using a framebuffer with an attached stencil buffer which may be a bit overwhelming and only gives a sharp cutout.

Using a custom fragment shader and blending in combination with the aforementioned scissor rect seems like the most sensible solution here, setup your scissor as described before, then in the 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.));
}

What we're doing here is calculating the distance of our current pixel to the center of the scissor region(assumed to be 256x256 in the top left corner of the screen) then doing a linear fade out between 100 and 128 The result is a mask looking like this:

result

Note that technically we don't need the scissor test anymore, as the mask in the fragment shader masks everything outside the circular region. However keeping the scissor test makes sure we only do the fragment shader work where we need it.

like image 78
LJᛃ Avatar answered Jan 29 '26 18:01

LJᛃ