-
-
Notifications
You must be signed in to change notification settings - Fork 36.2k
Description
So I was trying my hand at stereo effects in ThreeJS and the first issue I ran into is that they are somewhat incompatible with EffectComposer. The issue is that the "effects" in the examples/js/effects directory are not actually possible to put into the EffectComposer. This was initially a little confusing to me. You can put examples/js/passes into the EffectComposer though (maybe it should have been called PassComposer?) but anyhow....
I think the solution is relatively straight forward. We could convert the examples/js/effects into Passes and push them through the effect composer pipeline. I've actually done this in my private branch of ThreeJS already last fall but I am unsure if is the best way, I did it in an expedient way... I'd like to get this back into ThreeJS proper now if you guys want it....
Here is how I did it:
- I modified EffectComposer to optionally accept a StereoCamera as the main camera.
- If the camera passed into EffectComposer is not a StereoCamera it behaves at it current does. Thus it is backwards compatible.
- If you pass in a StereoCamera, things change, but only for passes that are "stereoAware". This is a flag on each pass that defaults to false if not set. If it is set, if the pass is "stereoAware", then the EffectComposer will call the Pass twice, once for each camera if the stereo rig and with the appropriate viewport settings (only half of the render target is rendered.)
That is it. It is very straight forward but powerful change.
A pass like RenderPass is stereo aware (stereoAware=true), it needs to generate different images for each camera. Other passes like a non-adaptive ToneMap are not stereo aware as it operates on each pixel in a simple matter. The rule generally is any Pass that uses a search area, such as FXAA, SMAA, Botek, SSAO should be stereo aware because otherwise there would be blending across central barrier.
Right now I make the assumption that StereoCamera splits the viewport into two even side-by-side renders. This seems to make sense to me, but maybe it isn't a valid assumption.
I am sure there are ways to further extend this design, but it does achieve what is minimally necessary, to unify Effects and Passes to make it easier to do high quality VR with ThreeJS.
I think this is a generally decent design and it is really simple to implement. I'd also suggest implementing a few new passes for this workflow, such as Lenticular (interleave), and Anagraph, which just engage in pixel re-arrangement. These could take the side-by-side renderings and turn them into new forms for output, thus all stereo effects could use the same pipeline -- thus we'd have simplicity and efficient of code.
This change should mostly gut the existing examples/js/effects in terms of rendering, the main thing we would need to keep is the particular StereoCamera setup code that is particular to each device.