Threejs soft shadows for point light - three.js

Is there a way to have soft shadows with PointLight in Threejs?
Like in the picture below:

Yes. To have soft shadows in your scene you have to set the renderer like this:
var renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // the default is THREE.PCFShadowMap
Source: documentation

Related

Transparency texture display incorrectly

I create a mesh with transparency texture over the ground. but when I move the mesh, the transparent part of the texture changed to the background color of the scene somewhere. how to solve this problem? am I missing some configuration here?
mainCode:
this.renderer = new THREE.WebGLRenderer({antialias: true,alpha: true,logarithmicDepthBuffer:true});
let material = new THREE.MeshBasicMaterial({side: THREE.DoubleSide,color: 0xFFFFFF,map: new THREE.TextureLoader().load(_background),transparent: true,opacity: 1,});
set depthTest:false in material
means :
this.renderer = new THREE.WebGLRenderer({antialias: true,alpha: true,logarithmicDepthBuffer:true});
let material = new THREE.MeshBasicMaterial({side: THREE.DoubleSide,color: 0xFFFFFF,map: new THREE.TextureLoader().load(_background),transparent: true,opacity: 1,depthTest:false});

Manually specifying camera matrices in ThreeJS

I'm working on a project where I will draw 3D graphics on a video that is filmed with a real camera. I get provided a static projection and view matrix and my task is to draw the actual graphics on top. I've got it working in pure WebGL and know I'm trying to do it in ThreeJS. The problem is that I can't find a way to manually set the projection and view matrix for the camera in ThreeJS.
I've tried to set camera.matrixAutoUpdate = false and calling camera.projectionMatrix.set(matrix) and camera.matrixWorldInverse.set(matrix), but it doesn't seam to work. It is like the actual variable isn't passed to the shader.
Does anyone know how this can be done?
This is what I've got so far:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.matrixAutoUpdate = false;
camera.projectionMatrix.set(...)
camera.matrixWorldInverse.set(...)
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
var animate = function() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
animate();

Trouble using toonshader in three js on objects that cast a shadow

I'm creating a sphere that casts and receives shadows with MeshToonMaterial but this is giving me an irregular shadow at the darkest section.
Sphere with irregular shadow:
Closer look at the sphere:
The light is:
light = new THREE.PointLight(0xffffff, 0.8, 18);
light.position.set(-3,6,-3);
light.castShadow = true;
light.shadow.camera.near = 0.1;
light.shadow.camera.far = 25;
light.shadowBias = 0.0015;
scene.add(light);
The sphere is:
mesh = new THREE.Mesh
(
new THREE.SphereBufferGeometry( 1, 32, 16 ),
new THREE.MeshToonMaterial({color:0xff4444})
);
mesh.position.y += 1;
mesh.receiveShadow = true;
mesh.castShadow = true;
mesh.position.set(-2.5, 3/2, 2.5);
scene.add(mesh);
The renderer:
renderer = new THREE.WebGLRenderer();
renderer.setSize(800,400);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
I've tried with other models and shadow map types with similar results.
If I set:
mesh.castShadow = false;
Then what I get is:
That's pretty much the style I'm looking for, but I'm also needing it to casts shadows.
I would like to avoid using an extra sphere for casting the shadow.
How can I achieve this?
Disabling receiving shadows on the sphere mesh will prevent it from being rendered with the cast shadows, but it will still cast a shadow on the plane.
mesh.receiveShadow = false
However, that means that the sphere won't have any shadows cast on it from other objects, either.
Other than that, it seems like an issue with the way the toon shader handles cast shadows.

Adding three.js compound object into A-Frame causing unexpected flickering of child objects

I am adding augmented reality experience to my web app which originally created using threejs
I have a compound object(which is an Object3D instance with multiple meshes). but placing it into A-Frame giving unexpected flickering s shown in below
Pic of the original web app with threejs is given below
I have the three.js code like below
scene = new THREE.Scene();
mainObj = new THREE.Object3D();
scene.add(mainObj);
renderer = new THREE.WebGLRenderer({alpha: true, antialias: true});
renderer.sortObjects = false
container = document.getElementById("canvas-container");
width = $(container).innerWidth();
height = $(container).innerHeight();
renderer.setSize(width, height);
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(75, width / height, 10, 2000);
camera.position.set(0, 67, 100);
controls = new THREE.OrbitControls( camera , container);
controls.dampingFactor = 0.2;
controls.enableDamping = true;
controls.target.set( 0, 10, -20 );
controls.maxPolarAngle = (Math.PI/2) - 0.05;
controls.maxDistance = 800;
controls.minDistance = 2;
controls.target.set(0, buildingConfig.h/2, buildingConfig.l/-2)
controls.enableKeys = false;
controls.update();
scene.add(camera);
light = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.7);
light.position.set(1, 10000, 1);
light.castShadow = true
scene.add( light );
renderer.render(scene, camera);
// logic to add child meshes to mainObj
Which I changed to include in A-Frame.
<script type="text/javascript">
initmodels();
AFRAME.registerComponent('e1', {
init:function(){
this.el.setObject3D('building', mainObj);
}
});
</script>
<a-scene e1>
</a-scene>
I guess this issue is related to the scene or renderer. Can anyone help me with a proper scene or renderer setup in A-Frame
This looks like z-fighting. Is the three.js version running on a different system than your aframe version?
Different platforms have different z-buffer precision. It may require you to make changes to the geometry to compensate for the limited resolution.
Also, I don't know about AR.s, but the THREE renderer has a "logarithmicDepthBuffer" option that can increase the resolution of your z-buffer at near scales, but may have some side effects.
I had exactly the same issue. After a few trial and errors, I was able to fix it
Added recent version of aframe
Add <a-scene embedded artoolkit='sourceType: webcam;' renderer='logarithmicDepthBuffer: true;'>
Add <a-marker-camera camera="far:100000; near:0.01" >
Main reason was the light, Remove all lights and add only the hemisphere light into the scene and improvise upon other lights later on.
Hope this would resolve your issue too.

Three.VRControls initial rotation

I've been doing through this Unable to change camera position when using VRControls and Three.js - VRControls integration - How to move in the scene? but it's not quite doing what I need.
I have a VR video app and I've just switched to VRControls with the WebVR polyfill from something old and custom. This is working well, however I'm really struggling to set the initial camera angle.
I.e. I want the camera to start pointing at a particular angle, and then rotate with the controls - however the controls always override this angle.
I've tried adding the camera to a Dolly Group or Persepective Camera, and it seems like I can move the camera but not set the initial viewing angle.
Here is how the camera is set up
container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1024);
scene = new THREE.Scene();
target = new THREE.Vector3();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
var vrEffect = new THREE.VREffect(renderer);
vrEffect.setSize(window.innerWidth, window.innerHeight);
var params = {
hideButton: false, // Default: false.
isUndistorted: false // Default: false.
};
manager = new WebVRManager(renderer, vrEffect, params);
dolly = new THREE.PerspectiveCamera();
dolly.add( camera );
//scene.add( dolly );
controls = new THREE.VRControls(camera);// (I've tried using Dolly here)
controls.standing = true;
And I've tried various ways to rotate the camera, dolly or scene
camera.position.y = currentScene.pan * Math.PI/180;
//controls.resetPose();
//dolly.position.x = currentScene.tilt * Math.PI/180;
//camera.updateProjectionMatrix();
I can rotate the mesh, but then all the objects inside the mesh are in the wrong place.. I could try moving them but this seems like the wrong approach to point the camera to the place I want it..
The camera was getting re-added to the scene at a later time, overriding the dolly. It's working now.

Resources