How do I simulate "overflow: hidden" in three.js or WebGL?

Viewed 550

I'm currently working on a WebGL GUI for my games and I really want to dig deep into GPU graphics, since it's a lot smoother than WebKit CSS rendering.

Is it possible to make a scrollview where the inside meshes are following overflow rule to hide when going outside the boundaries of the parent mesh?

Perhaps a shader could work, any suggestions?

Thanks!

2 Answers

If you only want to clip by rectangles you can use the scissor test.

gl.enable(gl.SCISSOR_TEST);
gl.scissor(x, y, width, height);

Now WebGL will only render between x, y, width, and height.

THREE.js also has scissor settings WebGLRenderer.setScissor and WebGLRenderer.setScissorTest

You could use a "stencil test" to achieve this. The stencil test allows you to mask subsequent rendering of geometry against pixels that you have denoted as the "stencil".

In terms of what you are doing, you might use the stencil technique to:

  1. specify the interior (rectangle?) of your scroll area as the "stencil". At this point, you would "draw" a rectangle that represents the boundary of your scroll-able area into your "stencil buffer".
  2. Now, with the stencilled area defined and rendered to your stencil buffer, you'd then render the actual contents of the scroll-able area. Because the stencil buffer is active, the contents of the scrollbar area are clipped by the rectangle you drew into the "stencil buffer". Any contents rendered outside of the "stencilled pixels" would not be rendered.

To give you an idea of how to achieve this, you could define your rendering sequence as follows:

    // Clearing the stencil buffer
    gl.clearStencil(0);
    gl.clear(gl.STENCIL_BUFFER_BIT);


    // Tell webgl how to render into the stencil buffer
    gl.stencilFunc(gl.ALWAYS, 1, 1);
    gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE);
    gl.colorMask(false, false, false, false);

    gl.enable(gl.STENCIL_TEST);

    // Renders the inner rectangle of scroll area
    drawInnerRectangleOfScrollArea();

    // Tell webgl how to clip rendering of the scroll area content
    gl.stencilFunc(gl.EQUAL, 1, 1);
    gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
    gl.colorMask(true, true, true, true);

    // Renders the inner contents of scroll area (ie the list of items, etc)
    drawInnerContentsOfScrollArea();

    // Reset the stenicl test state so to not affect any other rendering
    gl.disable(gl.STENCIL_TEST);
Related