Background- I’m working on an project that’s a bit like After Effects or Photoshop – you can manipulate various visual layers, which are ultimately composited together. I am not satisfied with the blend modes available directly in WebGL, so I have been implementing new blend modes using shaders and a multipass rendering scheme. Basically, I render each layer into a framebuffer, and then immediately use the framebuffer as a source texture when rendering the next layer.
My problem- since fragment shaders run in parallel, the layers aren’t rendered sequentially. The browser attempts to render all layers in parallel, and then composite them together, meaning that the source texture for a given layer’s parent layer is empty when the shader executes. As a result, there is no way to composite in data from the prior layer. I can tell that binding and rendering work in a broad sense given that I am able to preserve the composite texture after everything is rendered and use it on a subsequent frame, but that’s not what I am looking for.
My question – how can I force WebGL to rasterize a given framebuffer so that I can immediately use it as a texture?
2
Answers
I think the only two APIs that are available to you are flush and finish. From what I remember they don’t work exactly as expected in a browser. But you can give it a try.
WebGLRenderingContext.flush
WebGLRenderingContext.finish
Edit: If those doesn’t do what you expect, then you can probably do a minimal readPixels call which will hold for the pipeline to complete.
That’s not how WebGL works.
From the point of view of JavaScript and WebGL nothing runs in parallel. Whatever error you’re seeing is likely a result of a bug in your code, not anything to do with WebGL running in parallel.
From the spec:
There is no case of rendering to a framebuffer and having it not be ready for using the results in a draw call.
You claim in comments that calling
gl.finish
fixed your bug but that was more likely just coincidence to whatever your bug actually is.Post a repo if you believe you’ve seen otherwise as it would be a bug in your browser and should be reported. You mention textures being empty. That sounds more like you’re trying to render the contents of a canvas and they are being cleared which is part of the spec. Without seeing your code we can’t tell you what the real issue is but it’s not likely what you wrote in your question.