Three.js: Trouble combining stencil clipping with EffectComposer - three.js

NOTE: It appears I oversimplified my initial question. See below for the edit.
I'm trying to combine the technique shown in the clipping/stencil example of Three.js, which uses the stencil buffer to render 'caps' when clipping geometry, with an EffectComposer-based rendering pipeline, but I am running into some difficulties. A fiddle demonstrating the problem can be found at https://jsfiddle.net/2vc76ajd/1/.
The EffectComposer has two passes: a RenderPass and a ShaderPass using CopyShader (see code below).
composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
var shaderPass = new ShaderPass(CopyShader);
shaderPass.enabled = false;
composer.addPass(shaderPass);
The first renders the scene as usual, the latter merely copies the rendertarget onto a fullscreen quad. If I disable the ShaderPass everything works as intended: the geometry is clipped, and cutting planes are drawn in a different color:
When the ShaderPass is enabled by clicking the 'copy pass' checkbox in the upper right, however, the entire cutting plane gets rendered, rather than just the 'caps':
Presumably there is some interaction here between offscreen render targets and stencil buffers. However, I have so far been unable to find a way to have subsequent render passes look the same as the initial render. Can anyone tell me what I am missing?
EDIT: While WestLangley's answer solved my initial problem, it unfortunately doesn't work when you're using an SSAOPass, which is what I was doing before trying to simplify the problem for the question. I have posted an updated fiddle at https://jsfiddle.net/bavL98hf/1/, which includes the proposed fix and now toggles between a RenderPass or an SSAOPass. With SSAO turned on, the result is this:
I have tried setting stencilBuffer to true on all the render targets used in SSAOPass in addition to the ones in EffectComposer, but sadly that doesn't work this time. Can anyone tell me what else I am overlooking?

Related

THREE.JS Anti-Alias not working in multi-scene set-up

What's the trick for getting anti-aliasing to work properly on smaller scenes - which are overlaid on top of big scenes?
Check out this fiddle here:
https://jsfiddle.net/gilomer88/j974zmq0/6/
When you tap on any of the cubes you see there a new smaller "detailsScene" opens up on top of the main scene - and the cube in that "detailsScene" is not looking good. (It may not look all that bad here, but trust me, in my real project I'm loading a ".glb" model and it looks really terrible there. And it's not the model that's off. I know that because when I load it into my main scene it looks 100% perfect. Unless I have to re-load it for some reason into this smaller scene...?)
Otherwise I'm pretty sure I set the renderer for this smaller scene the right way, using:
detailsRenderer.setPixelRatio( window.devicePixelRatio );
(You'll find that bit on line 192 in the JS of the fiddle code.)
Any thoughts?
Anti-aliasing is working fine. The scene is just a bit blurred, because the canvas is scaled up while the renderer renders on a smaller size. You should always set the size of the renderer, such that it matches the canvas size. Just passing the canvas element to the renderer is obviously not enough in order to let the renderer know on which size it should render the scene.
detailsRenderer.setSize(detailsCanvas.offsetWidth, detailsCanvas.offsetHeight);
https://jsfiddle.net/sg3fn0tk/

Three.js object self shadow itself depending on geometry

I have playing a little with clara.io and i want to reproduce an image done with it.
I have searched the web for days looking up to reproduce what they call "Realistic" rendering.
As you can see on the image the six round part have they own shadows on the (one piece) brick from multiple lights sources.
I have no idea how they done that, if it is a simple setup, or a complex shader.
the best i can do is that and i have no idea how to proceed to make and object shadowing itself depending of it's geometry.
any trails ?
actually you need:
renderer.shadowMapEnabled = true;
light.castShadow = true;
object.castShadow = true;
object.receiveShadow = true;
i know its a little counter-intuitive that both the light and the mesh have the same attribute "castShadow", but that's how it works.
also remember to check the near, far, and size of the shadow camera of your light if the shadow doesn't appear or appears incorrectly.
here is an example i made:
http://shahar.thenachts.com/threejs/examples/selfShadow.html
it takes some time to load the model (the model is the floor and walls) and it's textures, so be patient.
to see the code, right click anywhere and choose "inspect element".
ie. Actually it is a very simple setup. The THREE.Object3D has two attributes castShadow and receiveShadow You can achieve the effect you are looking for (ie. self-shadowing) by setting both to true

Three.js FXAA background transparency

Created a simple scene with a cube in it. Able to see the color of the containing element, (body), in the background.
Added an FXAA shader and the antialiasing works well. However the background is now black, so can no longer see the color of the background container.
Added the following code:
var target = new THREE.WebGLRenderTarget(512, 512);
var composer = new THREE.EffectComposer( renderer, target );
in order to set the effect composer render target format to THREE.RGBAFormat, rather than the default THREE.RGBFormat.
This makes the background work properly, but then there are black and white edges around the cube and the antialiasing does not look very good.
Repeated the above but used the Sepia shader instead of the FXAA shader. This works correctly. The cube looks sepia and the background containing element color is correct.
Are there any workarounds to allow antialiasing and transparent background?
Thanks for any help
I read your issue and there seems to be a good source that can solve or at least lead you down the right path. Go check out: https://github.com/mrdoob/three.js/issues/2125
Hope this helps.
Check my answer in https://stackoverflow.com/a/21056080/2482976
The FXAA needed to be updated to handle the transparent background

Reset depth buffers destroyed by EffectComposer

I'm trying to render two different scenes and cameras on top of each other, like a HUD. Both render correctly when alone. Also this works as intended, so you can see mainscene under the helpscene:
renderer.render(mainscene, maincamera);
renderer.render(helpscene, helpcamera);
When I'm using EffectComposer to render the main scene, I can not see helpscene at all, I only see the results of composer rendering:
renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };
renderTarget = new THREE.WebGLRenderTarget( width, height, renderTargetParameters );
composer = new THREE.EffectComposer(renderer, renderTarget);
---- cut out for brevity ---
composer.render(delta);
renderer.render(helpscene, helpcamera); // has no effect whatsoever on the screen, why?
What is happening here? Again if I comment either render call out, they work correctly. But both enabled, I only see the composer scene/rendering. I would expect the helpscene to overlay (or at least overwrite) whatever is rendered before that.
I have quite complex code before renderer.render(helpscene, helpcamera);, it might take various different render paths and use effectcomposer or not based on different settings. But I want the helpscene to always take the simple route with no effects or anything, that's why I'm using a separate render call and not incorporating it as an effectcomposer pass.
EDIT: Turns out it is because some funny business with depth buffers (?). If I set material.depthTest = false to everything in the helper scene, it will show kind of correctly. It looks like the depth is set to zero or very low by some composer pass or by the composer itself, and rather unexpectedly, it will have the effect of hiding anything rendered with subsequent render calls.
Because I'm only using LineMaterial in the helper scene it will do for now, but I expect some problems further down the road with the depthTest = false workaround (might have some real shaded objects there later, which would need depth test against other objects inside the same helper scene).
So I guess the REAL QUESTION IS: how do I reset the depth buffers (or something) after EffectComposer, so that further render calls are not affected by it? I can also do the helper scene rendering as the last composer pass, does not make much difference.
I should maybe mention that one of my composer setups main RenderPass renders as a texture to a distorted plane geometry near a perspective camera created for that purpose (like the ortographic camera & quad setup found in many postprocessing examples, but with distortion). Other setup has a "normal" RenderPass with the actual scene camera, where I would expect the depth information to be such that I should see the helper scene anyway (that's probably some seriously f****ed up english, sorry, non-native speaker here and I could not come up with better words). I am having the same problem with both alternatives.
...and answering my self. After finding the real cause, it's quite simple.
renderer.clear(false, true, false); will clear the depth buffers so the overlay render works as expected :)

Three.js shadow map stripes in each light (now simplified, and with jsfiddle!)

I'm trying to create, modify and update (directional only for now) lights and shadowmaps dynamically. The light, shadow and shadow camera helper gets updated correctly as I move the light around or change shadow properties, except from the light's point of view, everything behind the origin (0,0,0) is shadowed for no apparent reason.
Screenshots:
http://i.imgur.com/n4AHvle.png
http://i.imgur.com/l0uaZHD.jpg
http://i.imgur.com/brKwCof.jpg
http://i.imgur.com/a6dqMGo.jpg (new, with spotlight)
You can see a scene with car and a piece of ground, they belong to a geometry imported with ColladaLoader. The problem is with shadowmapping, the car throws shadow correctly, but there are stripy shadows on the ground even though there is nothing else than the car obscuring light.
If I add more similar lights, they also have the same 4 stripes. They also appear with spotlight. If I change shadow map resolution, the stripes' size changes relative to each other, but there seems to be always four of them, spaced from center to both directions.
EDIT: JSFiddle here: http://jsfiddle.net/cL3hX/1/ There shouldn't be any shadows in the scene, unless some new geometry is introduced inside the shadow camera frustum.
Couple of notes on the fiddle:
I have r55, but the demo is r54 because jsfiddle apparently does not yet have r55.
I could only reproduce this with a Collada file. So it probably has something to do with the model. I created a simple cube in Sketchup 8, and tried to export it with various collada options.
In the JSFiddle I could only reproduce the bug with a file exported with "doublesided faces" -setting enabled. In my own application code, I do have the same bug on models created with or without that setting enabled, but in the fiddle, the bug seems to be triggered only when "doublesided faces" are exported. Anyway I do need to somehow show backsides of faces, because the tool I'm developing must work with Sketchup exports, and it's very hard to make models in Sketchup without having a mess of frontsides/backsides visible.
The very simple Collada file is included in the JSFiddle as javascript variable. Here's a download link for the same file: https://dl.dropbox.com/u/14489569/shadowmapdemo.dae
The problem is your Collada model.
Your "plane" is actually multiple coplanar faces back-to-back in a single geometry.
It's no wonder there are artifacts.
Replace it with a THREE.CubeGeometry.

Resources