Mesh with custom lighting effects in Three.js using specific light sources

In my current scene, I have various objects, including spheres that I want to be illuminated by pink and blue lights. However, there is also a tube geometry that should only be affected by a white light, without picking up the pink and blue colors.

To illustrate the issue, here is a comparison: What is happening: https://i.sstatic.net/oWOPO.png Desired outcome for the tube: https://i.sstatic.net/YCkcC.png

Currently, I am achieving this by using a meshBasicMaterial, but this approach compromises the 3D appearance of the tube.

How can I create a gray tube with a MeshLambertMaterial that doesn't react to the pink and blue lights?

Below is the code snippet that outlines how I am setting up my scene:

# Generating spheres:
for (var i = 0; i < 5; i++) {
        var SphereGeometry = new THREE.SphereGeometry(2, 20, 20);
        var SphereMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });
        var Sphere = new THREE.Mesh(SphereGeometry, SphereMaterial);
        Sphere.position.set(i * 7 -14, 0 + Math.random() * 5 - 2.5, 2);
        spheresArray.push(Sphere);
        scene.add(Sphere);
    }

#Generating tubes:
for (var i = 0; i < CurvesArray.length; i++) {
        var geometry = new THREE.TubeGeometry( CurvesArray[i], 20, 0.5, 8, false );
        var material = new THREE.MeshBasicMaterial( { color: 0xe3e3e3 } );
        var mesh = new THREE.Mesh( geometry, material );
        scene.add( mesh );
    }

#Lights setup:
var spotLight = new THREE.SpotLight( 0xff00cc );
    spotLight.position.set( -10, 3, 30, 100 );
    lightsArray.push(spotLight);
    scene.add(spotLight);

    var spotLight2 = new THREE.SpotLight( 0xaa99cc );
    spotLight2.position.set( 5, 15, 10, 100 );
    lightsArray.push(spotLight2);
    scene.add(spotLight2);

    var spotLight3 = new THREE.SpotLight( 0x0022bb );
    spotLight3.position.set( 2, -15, 10, 100 );
    lightsArray.push(spotLight3);
    scene.add(spotLight3);

    var light = new THREE.AmbientLight( 0x5f5f5f );
    scene.add( light );

If you need more information or find any part confusing, feel free to ask for clarification!

Answer №1

Utilize the concept of layers in your 3D modeling:

Here is an example demonstrating the use of layers: https://jsfiddle.net/mmalex/1xr356zf/

  1. Objects on the same layer are affected by the same lights.
  2. Objects belonging to the same layer as the camera will be visible to that camera.

Assign layers to your objects and lights:

for (var i = 0; i < 5; i++) {
    var SphereGeometry = new THREE.SphereGeometry(2, 20, 20);
    var SphereMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });
    var Sphere = new THREE.Mesh(SphereGeometry, SphereMaterial);
    Sphere.position.set(i * 7 -14, 0 + Math.random() * 5 - 2.5, 2);

    // set layers to Spheres
    Sphere.layers.set(i%3); // <<=== check here!
    spheresArray.push(Sphere);
    scene.add(Sphere);
}

Assign layers to lights:

var spotLight = new THREE.SpotLight( 0xff00cc );
spotLight.position.set( -10, 3, 30, 100 );
spotLight.layers.set(0); // << === layer 0 is by default
lightsArray.push(spotLight);
scene.add(spotLight);

var spotLight2 = new THREE.SpotLight( 0xaa99cc );
spotLight2.position.set( 5, 15, 10, 100 );
spotLight2.layers.set(1);  // << === layer 1 set to spotLight2
lightsArray.push(spotLight2);
scene.add(spotLight2);

var spotLight3 = new THREE.SpotLight( 0x0022bb );
spotLight3.position.set( 2, -15, 10, 100 );
spotLight3.layers.set(2);  // << === layer 2 set to spotLight3
lightsArray.push(spotLight3);
scene.add(spotLight3);

Render the layers one by one:

let animate = function() {
  requestAnimationFrame(animate);

  controls.update();

  renderer.autoClear = true;
  camera.layers.set(0); // << == switch camera between layers
  renderer.render(scene, camera);

  renderer.autoClear = false; // don't remove previous layer results

  camera.layers.set(1); // << == switch camera between layers
  renderer.render(scene, camera);

  camera.layers.set(2); // << == switch camera between layers
  renderer.render(scene, camera);
};

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

Unable to insert HTML code into a div upon clicking an image button

I am in the process of developing a website dedicated to radio streams, and I was advised to utilize Jquery and AJAX for loading HTML files into a div upon button click. This way, users wouldn't have to load an entirely new page for each radio stream. ...

What is the best way to fill a dropdown menu with names and corresponding numeric IDs?

How can I effectively link my dropdown to a variable in the controller, using the id property of the dropdown array instead of the value for assignment? Meanwhile, still displaying the content of the drop down using the name property of the array for user ...

VueJS Unit Testing: Exploring the Content of Attributes- What to Test?

I'm currently facing some challenges with my initial VueJS unit tests using Jest. Although I grasp the concept and have already executed my first set of successful tests, I find myself pondering over the question of "What aspects should I test?" For ...

Is there a way to change a weather api into local time using ReactJS/JavaScript?

In order to display time in a specific format like 12:00 or 20:00 and change the background with images, I need to convert it to local time. This is essential for achieving my desired output. The JSON data structure that I am working with looks as follow ...

The module '../xcode' could not be located. This issue is occurring within React Native and Expo CLI, where the required stack cannot

Trying my hand at creating my first project using React Native in iOS with expo.io, I encountered an error when running the command "expo start": https://ibb.co/f2xsmpN https://i.sstatic.net/Uyxkk.png Despite attempts to reinstall and update Xcode, usin ...

What is the best way to send AJAX post data to a Node.js server?

I am currently facing an issue with passing a unique ID object back to the server side using Ajax after making an API call. I need help figuring out what might be going wrong in my code. This is the client side code snippet where I loop through a JavaScri ...

Guide to making a Grid element interactive using the Link component

PostsList component is responsible for rendering a list of posts. The goal is to enable users to click on a post item and be redirected to the specific post's link. const PostsListView = ({ posts, setError, isloggedin }) => { const [redirectCre ...

create new Exception( "Invalid syntax, expression not recognized: " msg );

Can someone assist me in identifying the issue at hand? Error: There seems to be a syntax error, and the expression #save_property_#{result.id} is unrecognized. throw new Error( "Syntax error, unrecognized expression: " msg ); Here is the c ...

Guide to incorporating ThreeJS Collada loader with TypeScript / Angular CLI

I currently have three plugins installed: node_modules/three My Collada loader was also successfully installed in: node_modules/three-collada-loader It seems that the typings already include definitions for the Collada loader as well: node_modules/@ty ...

React - z-index issue persists

My React App with Autocomplete feature is almost complete, but I need some assistance to double-check my code. https://i.stack.imgur.com/dhmck.png In the code snippet below, I have added a search box with the className "autocomplete" style. The issue I a ...

Filtering deeply nested arrays

Hey, I'm working with this interesting array: [ { "Navn": "Long Island Iced Tea", "Nummer": "2", "Glas i ml": "250", "Instruktioner": "", "a": "Hæld is i glasset", "b": "pynt med en skive lime", ...

Interactive selection menu with jquery technology

I am in the process of developing a dynamic dropdown feature using jQuery var rooms = $("<select />"); $(res.data).each(function () { var option = $("<option />"); option.html(this.name); op ...

A tutorial on preventing backbone.js from automatically adding /# when a dialog is closed

Whenever I navigate back on my backbone page, it automatically adds /# to the URL. This results in loading an empty index page from the Rails home view when pressing back again. Disabling turbolinks fixed this issue for me. However, another problem arises ...

Creating dynamic web pages with jQuery is a simple and effective

I am currently using jQuery to create HTML elements with specific classes and then append them together. However, the code I have written is not adding the generated HTML to the container as expected. There are no errors being produced but the HTML is not ...

What is the best way to split key and value into separate array objects using JavaScript?

Here's a snippet of code I am working with: let obj = {EdadBeneficiario1: '32', EdadBeneficiario2: '5'} var years = []; let i; for (i= obj;i<=obj;i++) { years.push({ edad_beneficiario : i }) } When I run this code, the output i ...

I encounter difficulties when retrieving data in Next.js

Within a Next.js project, there is code provided that retrieves data from an external API endpoint and then passes it as props to a component called Services. This Services component utilizes the received data to dynamically render different sections of th ...

"Using HTML to assign a unique identifier to an image within

Apologies in advance for any errors as I am relatively new to html. I am attempting to construct a table with images that have onclick events, so that each clicked seat is tracked and its id is added to a list to change the class. Each image has been give ...

What is the best approach to execute the jquery script exclusively on mobile devices?

I want to modify this code so that it only functions on mobile devices and is disabled on computers. How can I achieve this? <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> <ul id="pri ...

Utilizing JQuery's $(document).ready() function following a window.location change

I'm having trouble getting a JavaScript function to run after being redirected to a specific page like "example.com" when the DOM is ready for it to work with. Unfortunately, it seems that $(document).ready() is running before "example.com" finishes l ...

Strip the pound symbol from the end of a URL during an AJAX request

When I click on the News tab in my Rails application (version 2.3.4 and Ruby 1.8.7), an Ajax call is triggered to load data. <a href="News" onclick="load_feed();"><u>Show More...</u></a> <script> function load_feed() { $.a ...