Issues with the functionality of materials in three.js causing lighting problems

After much experimentation, I am still struggling to achieve a normal shadow using Spot and Directional lights with Lambert and Phong materials:

Take a look at some examples

When using Spot Light with Lambert Material, the material does not react to light properly (pic. 1, 2). With Spot Light and Phong Material, the shadow appears as an imperfect pattern rather than smooth (pic. 3, 4). Directional Light with Lambert or Phong material gives a smooth shadow but not quite the desired result (pic. 5 - 8).

I have configured my preferences for shadows as follows:

renderer.shadowMap.enabled = true;
renderer.shadowMapSoft = true;

renderer.shadowCameraNear = 3;
renderer.shadowCameraFar = camera.far;
renderer.shadowCameraFov = 50;

renderer.shadowMapBias = 0.0039;
renderer.shadowMapDarkness = 0.5;
renderer.shadowMapWidth = 1024;
renderer.shadowMapHeight = 1024;

As for lighting, I have set up:

var ambientLight =new THREE.AmbientLight( 0x555555 );
scene.add(ambientLight);

along with:

var spotLight = new THREE.SpotLight( 0xffffff);
spotLight.position.set( 12, 22, -25 );
spotLight.castShadow = true;
scene.add(spotLight );

and also:

var directionalLight=new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set( 12, 22, -25 );
directionalLight.castShadow = true;
scene.add(directionalLight);

The castShadow and receiveShadow properties are consistent across all examples.

If needed, you can view the source code of this page here.

This code structure remains the same for all my examples, except for variations in light-material combinations.

Answer №1

Realtime shadows can be a challenge to implement in Three.js. Here are some key tips to enhance your shadow rendering:

To optimize the shadow camera frustum, set these values:

spotLight.shadow.camera.near = 25;
spotLight.shadow.camera.far = 50;
spotLight.shadow.camera.fov = 30;

Increase the resolution of the shadow map with:

spotLight.shadow.mapSize.width = 2048;
spotLight.shadow.mapSize.height = 2048;

Utilize shadowBias to reduce visual artifacts:

spotLight.shadowBias = -0.003;

The final result may not be flawless as light creeps into the room, but with further adjustments and compromises, it could meet your requirements: https://jsfiddle.net/wbrj8uak/8/


I'm adding this comment here regarding 2pha's updated example and explaining why I reverted it:

Changing the camera position caused shadows to disappear inside the room, which might confuse users aiming for internal shadow effects. Therefore, I retained the original code provided by the poster.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Converting large numbers (exceeding 53 bits) into a string using JavaScript

I have a REST service that returns JSON. One of the properties in the JSON contains a very large integer, and I need to retrieve it as a string before Javascript messes it up. Is there a way to do this? I attempted to intercept every response using Angular ...

Guide to creating a nested table with JavaScript

Currently, I am utilizing JavaScript to dynamically generate a table. To better explain my inquiry, here is an example of the HTML: <table id='mainTable'> <tr> <td> Row 1 Cell 1 </td> ...

Loading an HTML page using jQuery's .load() method that contains embedded JavaScript

I'm facing an issue with loading .html pages (including JavaScript) into a div element. Below is my div setup: <div class="content"></div> This is my php code: <?php if(!$_POST['page']) die("0"); $page = (int)$_POST[&a ...

Executing NodeJS Functions in a Particular Order

Just starting to learn Node and working on building an app. Currently, in my route file, I am attempting to connect to MySQL and retrieve the major of the user, then use it for other operations. However, when I run the webpage, the console displays that t ...

Tips for selecting an <select> option value based on an URL parameter automatically

I have a 2-step form where I am successfully passing the first name in the URL from step 1 to step 2, but I am struggling to do the same for a select field. Here's an example of what I have: In the URL: ?firstname=Bob Form Field: <input type= ...

Run the jQuery script once it has been successfully loaded using jQuery's .load method

On the Index.html page, there is a select box labeled #choose_content_to_load and a div named #get_loaded_content <select id="choose_content_to_load"> <option>Some content from the page content.html and div #content</option> </select ...

When using fs.readFileSync, the error message "no such file or directory" may appear even though the file is successfully returned when using require()

Looking to dynamically read a JSON file poses a challenge with the traditional require() method. The issue lies in the fact that the file is not updated until the NodeJS server is restarted, prompting the need to utilize fs.readFile or fs.readFileSync. Wh ...

When a model.find is passed as an argument to be invoked, it results in an error

After working with ExpressJS for a while, I decided to explore using Mongoose alongside it. In the callback of my queries where I handle errors like this: function( error, data ) {...} , I found myself repeating code. To streamline this process, I created ...

A guide on incorporating AJAX with jQuery to fetch a JSON file

I am struggling to incorporate a json file into my code using ajax. Despite my efforts, I can't seem to get it to work as I'm not well-versed in ajax and JQuery. The json file contains an array that I need to utilize in various sections of the j ...

Strategies for detecting when the focus has moved away from a Div

I'm currently developing a dynamic form that generates multiple Divs. My goal is to detect when the focus is lost from an entire div, not just from one input field. https://i.sstatic.net/YopGs.png As shown in the image, I have several identical form ...

What is the best way to leverage local storage/memory to save information for my text-based RPG game?

Currently, I am in the process of creating a text-based RPG on Codecademy. However, I am facing a challenge when it comes to implementing a save/load system using JavaScript/HTML. My idea is to create a system where players can type "save" into a prompt, ...

implementing nested key property specifications in React

Is it recommended to explicitly set the keys for the children of components when using arrays of Components? I understand that when using arrays of Components the key property is assumed to be the index of the array and should be explicitly set. {arr.ma ...

Implementing automatic 3D model scaling in THREE JS

Incorporated a basic 3D model viewer using three.js. The collection houses a database of 3D models categorized by size - tall, small, and large varieties. The canvas dimensions are fixed on the viewer; this causes some models to load at a small scale initi ...

I am attempting to arrange variables based on the key of the json nested within another json

It's a bit challenging to condense my goal into one question, but I'll try my best to clarify. I currently have a JSON array that represents various HTML slider elements categorized within 3 control panes: Basic, Interface, and Advanced. Each pa ...

Error: Module 'mongoose' not found

I have successfully created a basic CRUD API using nodeJS, express, and mongoDB. Everything was working smoothly until I decided to enhance the security by storing password hashes instead of plain text passwords. To achieve this, I integrated the bcrypt np ...

Unable to convert data to a JSON string

I've created a tool for building dynamic tables: <div class="container"> <div class="row"> <div class="col"> <hr> <h3>Add your data</h3> <button id="addTd" type="button" class="btn btn-pr ...

Is there a way to create a discord.js bot that can search for past messages without the need for a json file or storing them in a database?

Similar to the search feature in Discord. Imagine being able to enter !search [user] [query] and getting a response like "50 messages match your query." This would be like a word counting bot that doesn't need a database or local storage.The bot ...

Whenever I initiate an AJAX call, my form submits automatically

I have designed a form that sends a list of products to the spring backend. This form consists of two separate buttons: A "Submit" button for submitting the form. A "Fetch available Stock" button for checking stock availability. When the "Fetch available ...

The popup is unable to remain in the center of the screen because the background page keeps scrolling back to the top

Whenever I click a button to open a popup window, the page unexpectedly scrolls to the top. It's frustrating because if I'm at the bottom of the page and press the 'submit' button, the popup doesn't display in the center as intende ...

Did I incorrectly associate the function with the button causing it to always be executed?

I am working on a PHP page, where I have some initial content followed by session initialization code: <?php session_start(); ?> The requirement is to display a disconnect button only if the user is logged in, indicated by the presence of $_SESS ...