Three.js object self shadow itself depending on geometry - three.js

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

Related

Three.js: Trouble combining stencil clipping with EffectComposer

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?

Using threeGLTFLoader load gltf get transparency problem

I try to use threeGLTFLoader to load gltf ,problem with the material,the model is a man’s head but now i could see the back
here is the code:
var threeGLTFLoader = new THREE.GLTFLoader();
var objPositions;
threeGLTFLoader.load("../resources/untitled.gltf", function (gltf) {
model = gltf.scene;
model.name = "man";
model.scale.set(300, 300, 300);
root.matrixAutoUpdate = false;
root.updateMatrix();
root.add(model);
});
The link of 3D model
Without the model it's hard to guess what's going on here, but I'll wager a guess based on seeing this kind of back-is-in-front rendering before.
I think your glTF model probably has materials that are marked "alphaMode": "BLEND".
In most realtime 3D rendering systems, including ThreeJS, blended or translucent materials will disable the depth buffer, and can be rendered out of order. There are ways for some engines to fix or work around this, but they can cost performance and increase complexity.
For opaque materials in a glTF file, the best thing to do is leave alphaMode set to its default value OPAQUE. Only materials that really need to be translucent should be set to BLEND.
Ed Mackey’s answer on GitHub is a good explanation of why this is happening. If you’re the author of the model, it’s an issue you could fix by disabling transparency on parts of the model that aren’t meant to be transparent. If you’re not the author of the model, you can override the incorrect transparency settings after loading the model in three.js:
model.traverse((object) => {
if (object.isMesh) object.material.transparent = false;
});
This code will disable transparency everywhere on the model. In more complex cases you may need to select specific parts of the mesh to override, and that is easier to do in Blender, using Alpha Clip or Opaque modes.

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 :)

TextGeometry to always face user?

I've added some text to my scene with THREE.TextGeometry, and the text seems to be stuck in whichever xy plane I place it. Any way to have it adjust to always be in plane with the screen- readable for the user?
Try
mesh.lookAt( camera.position );
The local z-axis of the mesh should then point toward the camera.
To make the text always face the screen (rather than the camera):
mesh.quaternion.copy(camera.quaternion);
Note that this differs from object.lookAt(camera); since this will result in different orientation depending on where on the screen the object is located.
Object3D.onBeforeRender can be used to update the orientation on each frame. It might be useful to disable frustum culling using Object3D.frustumCulled = false; to ensure that the callback always is triggered.

Update function on Three.js

How make an Update function in Three.js, like in Unity3d?
I mean, that i create an object:
var torus = new THREE.Mesh(
new THREE.TorusKnotGeometry(60,20,100),
reflectionMaterial
);
and when i click on the body, i change a reflectionMaterial. But the image don't change, i see a not changed reflectionMaterial (last figure). Always redrawing a render image???
Thank's for attention. Sorry for my English (I'm from Ukrainian).
P.S.: I work with Three.js onn my netbook and on (not my) notebook. On netbook i don't see a shaders. Why?? Did the Three.js support Shader Model number 3 and 0?
If I understand your question, you are having issues changing a material after you click on something? You may need to change a flag depending on if you already have a material or not, there are some dependencies - check the link below:
material.needsUpdate = true;
There is an article on How to update things in Three.js

Resources