Shadow casting on text geometry

I’m trying to cast shadow on text geometry, like in this three.js example , i dont understand what i’m doing wrong… can somebody help?
CodeSandbox demo

Your scene has a bit extreme size - try keeping values of position and size around 0.1 (small items), 1.0 (1x1 metre), 10.0 (absolutely huge things.) Having objects of size 1000x1000 will force you to start unnecessarily updating camera and shadow camera near / far planes and sizing.

Your code itself is working, you can verify that by replacing your addLights with, for example:

addLights() {
  this.ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
  this.lightHolder = new THREE.Group();
  const topLight = new THREE.SpotLight(0xffffff, 0.4);
  topLight.position.set(0, 15, 200); // <--- Light was between text and the plane, casting light only on the plane
  topLight.castShadow = true;
  topLight.shadow.camera.near = 1; // <--- Shadow camera with near / far values of 10 / 30 could not cover much in a scene where objects are of size 100x100
  topLight.shadow.camera.far = 3000;
  topLight.shadow.mapSize = new THREE.Vector2(2048, 2048);
  this.lightHolder.add(topLight);
  const sideLight = new THREE.SpotLight(0xffffff, 0.4);
  sideLight.position.set(0, -4, 5);
  this.lightHolder.add(sideLight);
  this.scene.add(this.lightHolder);
  this.planeGeometry = new THREE.PlaneGeometry(2000, 2000);
  this.shadowPlaneMaterial = new THREE.ShadowMaterial();
  const shadowPlaneMesh = new THREE.Mesh(
    this.planeGeometry,
    this.shadowPlaneMaterial
  );
  shadowPlaneMesh.position.z = -200.0; // <--- Plane with the shadow material was facing up, perpendicularly to the camera, removing .rotation.y fixes that (although in properly set up scene the plane should indeed be rotated by -90degrees
  shadowPlaneMesh.receiveShadow = true;
  this.lightHolder.add(shadowPlaneMesh);
  this.scene.add(shadowPlaneMesh);
}

While it may sound a bit laborious, I’d consider pausing for a moment and rewriting the scene to fit into a smaller size (as in the note above) - since there isn’t that much in the scene, yet. In the current form, where basically everything has to be multiplied by 100, it’s a bit unmanageable in a long run :smiling_face_with_tear:

2 Likes

thank you so much for respone! but now shadows are on the back of the text not below. i want shadows to cast like so: codepen example

that’s no shadow, it’s a shader. it’s called contact shadows. you use them to get soft ground shadows, they are using a blur shader internally. you could also just light the text from above though it won’t be as soft and cute.

i struggled a lot with that one example because it’s pretty much hardcoded for its use case. i’ve made a more reusable variant for drei

the code is here: drei/src/core/ContactShadows.tsx at aa2dd0f99fcb33562eff69b57fcb51dbe1d65ff3 · pmndrs/drei · GitHub it would probably be easier to port to your own app than the vanilla example.

2 Likes

yes i wanted to light from above, like in this Codepen example, i dont think shaders are used in this example , i cant achieve same effect still.

Your code was mostly fine. I wouldn’t worry too much about the scaling etc. With a spot light you can control shadow coverage by the placement of the light, and for a simple example like this, having a large scale probably isn’t a huge deal, since as long as it works… it works.

I scaled your text mesh down by .5

I rotated your ground plane by -90 degrees (Math.PI*-.5) (It was vertical before!)

I moved your SpotLight a bit…

I added a geometry.dispose() before you set the new geometry, so you don’t run out of memory
:slight_smile:

https://wm4m2j.csb.app/

https://codesandbox.io/p/sandbox/three-clock-forked-wm4m2j?file=%2Fsrc%2Findex.js%3A149%2C7

3 Likes

Thank you so much! i was banging my head around this for 2 days , couldn’t figure it out…

1 Like