4
votes

I have a three.js scene which renders a 3D model. I am using a DirectionalLight to cast a shadow on that model.

What I am seeing happen is a gradient stepping effect against the model, as if the model is made up of lots of submodels each with its own slight shadow being cast.

Below is a screenshot of the effect:

gradient stepping

Why is this happening and how can I prevent it?

Some various code snippets - there's a lot going on on this scene so I've tried to just highlight the important parts:

Camera & Directional Light source:

// Camera
camera = new THREE.PerspectiveCamera( 30, (window.innerWidth / window.innerHeight), 1, 10000 );
camera.position.x = 1000;
camera.position.y = 50;
camera.position.z = 1500;
scene.add( camera );

// LIGHTS
var lightFront = new THREE.DirectionalLight( 0xffffff, 0.7 );
lightFront.position.x = 120;
lightFront.position.y = 120;
lightFront.position.z = 150;
lightFront.castShadow = true;

lightFront.shadow.camera.left = -6;
lightFront.shadow.camera.right = 6;
scene.add( lightFront );

Material is a THREE.Mesh, with:

material.normalScale = new THREE.Vector2( 1, 1 );
material.castShadow = true;
material.receiveShadow = false;
material.shininess = 100;

Renderer has the following:

renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.shadowMap.soft = true;
renderer.shadowMap.bias = 0.0039;
renderer.shadowMap.darkness = 0.5;
renderer.shadowMap.width = 1024;
renderer.shadowMap.height = 1024;

I've played about with various renderer settings without much luck.

I am running revision 82 of three.js.

1
That is usually an indication of self-shadowing. See this answer. If you need help, upgrade to the current three.js revision, first.WestLangley

1 Answers

0
votes

It's probably caused by the low resolution of the shadow map, which by default is 512 * 512.

You could increase that with the following syntax:

lightFront.shadow.mapSize.width = lightFront.shadow.mapSize.height = 1024;

However, it would greatly increases the computation time, and as a result, drop in framerate.

There is a upper limit according to your target device, which can be found here.