Webgl update region using viewport+scissor

2019-05-24 13:24发布

I've been trying to create a multiviewport webgl application.

I got everything rendering quite nice using viewport+scissor for each view. But now I would like to improve rendering and just render the view which is updated, so skip overdrawing. I've made a little demo showing the idea: http://kile.stravaganza.org/lab/js/scissor/

As I understand scissor it's suposse that it will just render the current scissor box and keep the rest of the canvas untouched. But it seems that it just keeps clearing the whole canvas on each frame, no matter what I tried :(

This is the rendering code (The last view it's supossed to be rendered just once and keep it on each frame):

function drawScene()
{
    gl.clearColor(1.0, 0.0, 0.0, 0.0);
    gl.scissor(0,0,200,200);
    gl.viewport(0,0,200,200);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    drawFigures();

    gl.clearColor(0.0, 1.0, 0.0, 0.0);
    gl.scissor(200,0,200,200);
    gl.viewport(200,0,200,200);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    drawFigures();

    gl.clearColor(0.0, 0.0, 1.0, 0.0);
    gl.scissor(200,200,200,200);
    gl.viewport(200,200,200,200);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    drawFigures();

    // Render just once   
    if (first)
    {
        gl.clearColor(1.0, 1.0, 0.0, 0.0);
        gl.scissor(0,200,200,200);
        gl.viewport(0,200,200,200);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        drawFigures();
        first=false;
    }
}

Any idea how could I achieve this effect?

Thank you very much in advance

1条回答
不美不萌又怎样
2楼-- · 2019-05-24 13:48

You can use the preserveDrawingBuffer attribute:

gl = canvas.getContext("experimental-webgl", { preserveDrawingBuffer: true });

It isn't recommended to use this in production. The WebGL specifications states:

While it is sometimes desirable to preserve the drawing buffer, it can cause significant performance loss on some platforms. Whenever possible this flag should remain false and other techniques used. Techniques like synchronous drawing buffer access (e.g., calling readPixels or toDataURL in the same function that renders to the drawing buffer) can be used to get the contents of the drawing buffer. If the author needs to render to the same drawing buffer over a series of calls, a Framebuffer Object can be used.

This SO question contains also relevant information regarding preserveDrawingBuffer: When WebGL decide to update the display?

查看更多
登录 后发表回答