Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sharing depth buffer between targets #15440

Closed
pailhead opened this issue Dec 16, 2018 · 8 comments
Closed

Sharing depth buffer between targets #15440

pailhead opened this issue Dec 16, 2018 · 8 comments

Comments

@pailhead
Copy link
Contributor

I'm experimenting with an effect that uses the stencil buffer. I'd like to be able to share the depth/stencil render buffer between different targets.

It seems like i've been able to do what i want by changing this:

setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );

to:

setupRenderBufferStorage( renderTarget.ownDepthBuffer || renderTargetProperties.__webglDepthbuffer, renderTarget )

and creating the buffer myself on the render target.

I am unable to find a way to do this without modifying the library. The super private caching internals seem to be in the way, since createRenderbuffer() is both called and stored inside the renderer.

I don't understand what exactly depthTexture is, but it seems like it is something similar to this, and can be provided from outside. Is there a way to achieve what i'm doing here without the hack?

@mrdoob
Copy link
Owner

mrdoob commented Dec 18, 2018

I don't understand what exactly depthTexture is, but it seems like it is something similar to this, and can be provided from outside. Is there a way to achieve what i'm doing here without the hack?

I don't think so...

How do you think the API for this should be?

@pailhead
Copy link
Contributor Author

pailhead commented Dec 18, 2018

I'm not entirely sure. Not to open the old can of worms :) but it seems worth while mentioning that this problem seems similar to the chunk one I've been boring everyone with.

As I see it, there are many things private to the renderer that maps to low level Webgl api/state and some times you need access to it. When you want to modify the shader code, it doesn't exist until the renderer does the init. If you then want to modify it, you're given a hook.

So in line with that approach, each one of these private methods could have a hook. onBeforeCreateBuffer, onBeforeUploadTexture etc. onBeforeCompile could be that and onBeforeParse etc. I'm not sure how big of a fan I would be of this API, but it would work, and would allow you to modify this kind of stuff.

They might not have to be as granular, but more abstract onThisStage onThatStage.

The API I might favor, is similar to the chunks I proposed, and the hack in the snippet. For every property __foo that the renderer manages internally, add an external ownFoo that can be used.

This could be left kinda open, hacky and raw where you would call:

myTarget.depthBuffer = renderer.getContext().createRenderBuffer()

Or

myTarget.depthBuffer = new THREE.RenderBuffer()

And then the internals would still call the createRenderBuffer() but just not cache it the same way (per target).

The third way would maybe be to just expose all of the state of the renderer. It would allow for more hacking. If you could access this cache, and understand what happens when, between two targets that Three set's up, you could nuke one buffer, and link the second one.

All of these have some overlaps. Exposing all of the internals may be the most flexible. If there isn't a hook, you can monkey patch your own method or class with a hook if you need it. For example, instead of waiting for the next frame or something to check hasBufferBeenCreated() you replace the code without the hook, with a hook, and you just hook in. If you want ownProp you modify the line as i did in the first snippet.

The onBeforeSomething actually kinda does this too, but you have to wait for each Something to be vetted, and there just may be too many edge cases.

The ownProp || __renderCache is the most straight forward perhaps, but also super specific, only applicable to some cases.

@pailhead
Copy link
Contributor Author

Here's an example of how I'm using this:

https://raw.githack.com/pailhead/three.js/depth-peel-stencil/examples/webgl_materials_depthpeel.html

The little quads kinda show what's going on, but I want to try to visualize it better. There are two targets being flip flopped, so the same scene is being drawn to both of them. But with each pass, I do some stencil logic, and I keep it around for the next one. Because each pass needs to write something to it, I need to keep the same buffer between both targets.

@pailhead
Copy link
Contributor Author

pailhead commented Dec 20, 2018

Wow, sharing between the final composition target as well made it run at 60fps at half rez on an iphone. I think this would be a useful feature. Unfortunately i'm running into some depth precision issues there.

@gkjohnson
Copy link
Collaborator

@pailhead Can you explain a bit more about why using DepthTexture wouldn't work? At least on the surface it seems to be what you're interested in, granted it requires an extension to work.

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 24, 2020

Closing in favor of #15490.

@Mugen87 Mugen87 closed this as completed Mar 24, 2020
@gkjohnson
Copy link
Collaborator

@Mugen87 #15490 is a PR, though -- does it make sense to close the issue in favor a PR?

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 25, 2020

Well, if both more or less contain the same discussion I think it's okay. Especially since the initial post (#15490 (comment)) is very detailed and contains all relevant information. Besides, we don't need for each PR a corresponding issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants