In three.js, it appears that shadows are not being cast by imported 3D objects

Hey there, I've been diving into three.js recently and managed to successfully import a 3D model from Cinema 4D using the three.OBJMTLLoader. However, I'm having trouble getting the imported object to cast a shadow. I've tried setting object.castShadow = true, but it doesn't seem to be working. Interestingly, I can get geometries created in three.js to cast shadows, so I know the scene setup is correct.

You can check out the test scene here: . I've also updated it with the suggested fix below.

Below is the code. If anyone could kindly point out where I might be going wrong or confirm if imported objects can cast shadows, I would truly appreciate it.

Cheers.


        <script>
            var container;
            var controls;
            var camera, scene, renderer;
            var windowHalfX = window.innerWidth / 2;
            var windowHalfY = window.innerHeight / 2;

            init();
            animate();

            function init() {
                container = document.createElement('div');
                document.body.appendChild(container);

                camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000);
                camera.position.z = 500;
                camera.position.y = 500;

                scene = new THREE.Scene();

                controls = new THREE.OrbitControls(camera);
                controls.addEventListener('change', render);

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

                var spotLight = new THREE.SpotLight(0xffffff);
                spotLight.position.set(500, 1000, 500);
                spotLight.castShadow = true;
                spotLight.shadowMapWidth = 1024;
                spotLight.shadowMapHeight = 1024;
                scene.add(spotLight);

                var companion = new THREE.OBJMTLLoader();
                companion.load('companion2.obj', 'companion.mtl', function (object) {
                    object.position.set(0, -20, 0);
                    object.scale.set(0.8, 0.8, 0.8);
                    object.castShadow = true;
                    scene.add(object);
                });

                var floorGeometry = new THREE.CubeGeometry(1000, 4, 1000);
                var floorMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000 });
                var floor = new THREE.Mesh(floorGeometry, floorMaterial);
                floor.position.set(0, -130, 0);
                floor.receiveShadow = true;
                scene.add(floor);

                var geometry = new THREE.BoxGeometry(100, 100, 100);
                mesh = new THREE.Mesh(geometry);
                scene.add(mesh);
                mesh.position.set(-100, 200, 10);
                mesh.castShadow = true;

                renderer = new THREE.WebGLRenderer();
                renderer.setClearColor(0xEEEEEE, 1.0);
                renderer.setSize(window.innerWidth, window.innerHeight);
                container.appendChild(renderer.domElement);
                renderer.shadowMapEnabled = true;
                renderer.shadowMapSoft = true;
                spotLight.shadowCameraVisible = true;

                var step = 0;
                render();
            };

            function render() {
                camera.lookAt(scene.position);
                renderer.render(scene, camera);
            }

            function animate() {
                requestAnimationFrame(animate);
                render();
            }
        </script>
    

Answer №1

Your item contains multiple sub-meshes, each of which must have the castShadow property set to true.

To resolve this issue, include the following code snippet in your loader callback:

object.traverse( function( node ) { if ( node instanceof THREE.Mesh ) { node.castShadow = true; } } );

This solution is tailored for three.js version r.66

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

In the Node environment, why does null evaluate as less than 3 while also being greater than 3?

How come null is false when compared to 3 in node, and true when compared to 3? $ node > null > 3 false > null < 3 true ...

Using Regular expressions in JavaScript to eliminate content between two HTML comment tags

I am currently dealing with two HTML comments in this format: <!--Delete--> Blah blah blah blah <!--Delete--> I need to remove these comments, along with any characters and newlines. I am utilizing JavaScript and Grunt for this replacement ta ...

Eliminate JSON data that pertains to dates that are either in the past or future

I am working on integrating upcoming classes and past classes components into my application. I have successfully stored the schedule of classes and can retrieve them using backend services. However, I need to display only the upcoming classes in one compo ...

javascript href clears Internet Explorer webpage

I noticed a strange issue with my HTML page. In Internet Explorer, when I click on the link, it displays the return value on a blank page. However, in Chrome, it simply executes the function without affecting the page appearance. Is there a way to make I ...

Actively toggle the selection state within OpenSeadragon

Currently, I am in the process of integrating a viewer for scanned pages using OpenSeadragon along with the Selection plugin (https://github.com/picturae/openseadragonselection) to allow users to select a portion of the page. I have successfully incorpora ...

Executing numerous tests on a single response using Node.js along with Chai, Mocha, and Should

I have a setup similar to the one below that allows me to perform a series of API tests using Mocha. While this method works well, it involves making an individual API call for each test. My goal is to streamline the process by utilizing the same API cal ...

Angular application across multiple subdomains

Currently creating an angular application that allows users to generate and share digital books with a subdomain link like mycoolbook.theappsite.com. However, I've set up the routes so that editing books are at the URL "mycoolbook.theappsite.com/sett ...

Error: The jasmine framework is unable to locate the window object

Currently, I am testing a method that includes locking the orientation of the screen as one of its functionalities. However, when using Jasmine, I encountered an error at the following line: (<any>window).screen.orientation.lock('portrait&apos ...

The marriage of Vue 2.0 and Rails 5: Shifting from Reactive to Declarative Rendering

As I make my way through the Vue guide with a Rails 5 app, I've noticed that although I am able to update my Vue js object, the DOM doesn't behave as described in the Declarative Rendering section. The data and the DOM are supposed to be linke ...

The pre-set value in the search bar of the Google specialized search

Is it possible to pre-fill the search field with text when the Google Custom Search page is loaded using the standard copy and paste code (free with ads)? If yes, how can this be achieved? Below is the code snippet: <div id="cse" style="width: 100%;" ...

Incorporating Data from a Dictionary into a Highcharts Series

Utilizing flask allows me to organize all my data in a dictionary for use with highcharts. my_data = { 'dataset1': {'x_values': [1, 2, 3, 4, 5, 6], 'y_values': [7, 8, 9, 10, 11, 12]}, ...

Trigger a drop-down list in React when typing a specific character, like {{ or @, in an input field

Is there a way in React.js to display a list or dropdown when a user types a certain character like '@' or '{{ }}' in the input text area? The user should be able to select an option from this list and have it inserted into the text are ...

A dynamic context menu using jQuery within AJAX-loaded content

After spending hours searching for a solution without success, I am turning to this forum for help (I have come across similar questions but none of them have solved my issue). The problem I am facing is with implementing a custom context menu on a page t ...

How can nextJS leverage async getInitialProps() method in combination with AWS S3?

I'm currently facing a challenge with executing an s3.getObject() function within an async getInitialProps() method in a nextJS project. I'm struggling to properly format the results so that they can be returned as an object, which is essential f ...

Performing a validation on data fetched using a .load() function

I've been struggling with a persistent issue that I just can't seem to solve. So, here's the situation: I have a blog post on a CMS that I'm developing. The content is saved within a div with its own unique ID. When the user clicks an ...

Click the button on your mobile device to open the already installed Android app

After creating a small Android app using jQuery Mobile, I incorporated a button to open another native Android app. Is it feasible for the jQuery Mobile app button to load/open an already installed and functioning native Android app upon click? I would gr ...

JS-generated elements do not automatically wrap to the next line

For my first project, I've been working on a to-do list and encountered an issue. When I create a new div with user input, I expect it to start on a new line but it remains stuck on the same line. Can anyone point out where I might have gone wrong? I ...

Tips for rearranging table columns using drag and drop in react js

I have been experimenting with various libraries to create a drag-and-drop feature for changing table columns order. Here is my current implementation: import React, { useState } from 'react'; import './list_de_tournees.css' const Table ...

What is the best way to make text appear as if it is floating in Jade or HTML?

Currently, I am facing an issue with a Jade file that displays an error message when a user tries to log in with incorrect credentials. The main problem is that this error message disrupts the alignment of everything else on the page, as it is just a regul ...

Utilizing Node.js with Express and Swig to seamlessly pass a local JSON file to a template

I am new to working with nodes, and I have successfully managed to integrate Express/swig and display them on the screen. However, when I include my d3 code (which functions independently), I encounter an error in the console: Uncaught TypeError: Cannot re ...