What is the best way to incorporate color into a ShaderMaterial using three.js?

I'm a beginner when it comes to three.js, so I appreciate your patience. I've been given a project that requires me to create a car body using WebGL and dent it when the mouse is clicked. My goal is to change the color of these dents from the color of the car body to yellow. Do you have any suggestions on how I can achieve this? Please note: I only want to alter the color of the dents, not the entire car.

Below is the code for the material used for the dents. Initially, I tried adding color to the shader material but that didn't yield the desired results, so I decided to comment it out.

var dentMaterial = new THREE.ShaderMaterial({
    uniforms : {
        size : { type: 'f', value : 20.0 },
        near : { type: 'f', value : camera.near },
        far  : { type: 'f', value : camera.far }
        //color:  { type: 'v3', value: { x: 1, y: 1, z: 1 } }
       // map  : { type: "t", value : THREE.ImageUtils.loadTexture( 'textures/heatmap.jpg' ) } //here
      },
      attributes : {},
      vertexColors: THREE.VertexColors,
      vertexShader: vertShader,
      fragmentShader: fragShader,
      side: THREE.DoubleSide,
      transparent: true
});

The following code snippet showcases where the dents are actually being generated.

 THREE.DentModifier = function () {};

THREE.DentModifier.prototype = {

constructor: THREE.DentModifier,

set: function ( origin, direction, radius, depth, material ) {

    this.origin = origin; // vec3
    this.direction = direction; // vec3
    this.radius = radius; // float
    this.depth = depth; // float
    //this.material = material // GLmaterial
    return this;

},  

magnitude: function(vector) {
    return vector.x * vector.x + vector.y * vector.y + vector.z * vector.z;
},

linearFalloff: function (distance, radius) {    
    return this.clamp01(1 - distance / radius);
},

gaussFalloff:function (distance, radius) {
    return this.clamp01(Math.pow(360, Math.pow(distance / radius, 2.5) - .01));
},

needleFalloff:function (distance, radius) {
    return -(distance * distance / (radius * radius) + 1);
},

clamp01: function(val) {
    if (val < 0) return 0;
    if(val > 1) return 1;
    return val;
},

modify: function ( mesh , material ) {

    this.mesh = mesh;
    var matrix = new THREE.Matrix4().getInverse( this.mesh.matrixWorld );
    var origin = this.origin.applyMatrix4( matrix );

    var normal = new THREE.Vector3(); 
    normal.copy( this.direction );
    normal.multiplyScalar( -this.radius * ( 1 - this.depth ) );

    var centerSphere = new THREE.Vector3();
    centerSphere.addVectors( origin, normal );
    var sphere = new THREE.Sphere( centerSphere, this.radius );

    this.mesh.geometry.elementsNeedUpdate = false;
    var sqrRadius = 100; //this.radius*this.radius;
    var sqrMagnitude; //float
    for ( var i = 0, il = this.mesh.geometry.vertices.length; i < il; i++ ) {

        if ( centerSphere.distanceTo( this.mesh.geometry.vertices[ i ] ) < this.radius ) {

            // new - Limit depth of dent
            sqrMagnitude = this.magnitude(this.mesh.geometry.vertices[i]) - this.magnitude(centerSphere);
            if (sqrMagnitude > sqrRadius) {
                console.log("We are too deep Scotty !!");
                break;
            } // end new

            var ray = new THREE.Ray( this.mesh.geometry.vertices[ i ], this.direction );
            var dent = ray.intersectSphere( sphere );
            this.mesh.geometry.vertices[ i ] = dent;                

        }

    };

Answer №1

dentMaterial.uniforms.diffuse = { type: "c", value: { r:1, g:0, b:0 } };

If you are using the default phongShader uniforms, this method will also work:

dentMaterial.uniforms.diffuse.value.setHex(0xFF0000);

This code snippet is applicable for Three.js version r.71.

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

The Autocomplete component from MUI is alerting me to provide a unique key for every child element being passed

I am currently using the Autocomplete component from MUI and encountering an issue with a warning that says: Warning: Each child in a list should have a unique "key" prop. Although I've added keys to both renderOption and renderTags, the wa ...

Combining two items from separate arrays

How can I efficiently merge objects that share the same index in two different arrays of objects? Below is the first array const countries = [ { "name": "Sweden", "nativeName": "Sverige" }, ...

Generate dynamic Bootstrap Carousel slides with unique hashtag URLs

I've been attempting to connect to various slides within a bootstrap carousel from a different page but have had no success. Here is an example of what I'm trying to achieve: <a href="services#slide2">Link to Slide 2</a> For refere ...

Concurrent requests hitting multiple ExpressJS routes simultaneously

While configuring my routes for an expressjs app, I encountered the issue of two routes being executed when accessing a single endpoint. This is an excerpt from my code: app.get("/forgot-password", (req, res) => { .... }); app.get("/:modelName/:id ...

Unable to interact with buttons located in the title bar of the Electron application

I am currently working on developing a basic Text Editor using Electron. I am facing an issue with adding a custom title bar where the buttons are not clickable. To try and fix this issue, I have included an onclick tag to the buttons in my code. main.js ...

React is unable to access and retrieve data from a web API

Currently, I have a controller set up in web-api for my project. I am using React v18.2.0 and NextJS v13.3.0 to work with this setup: public List<ReturnDat> Get() { List<ReturnDat> lst = new List<ReturnDat>(); lst.Add(new ReturnD ...

Utilizing jQuery BBQ for Seamless Transitions – From Fading to Sliding and More

This is my first time posting a question here, even though I am an active user of stackoverflow. I have developed a website using jQuery BBQ to load pages through AJAX while still maintaining the ability to track history with the back button and other fun ...

Adding a new item to a list using Ajax after a post request - focusing on layout design

I currently have an activity stream available for users to use, as well as a site-wide view. When a user posts an update, it displays a default bootstrap success alert. However, I have noticed that other websites slide down existing items and append the ne ...

Moving information from Ajax to PHP

I'm experiencing an issue with sending data from AJAX to PHP on the same site, "testpage.php". The PHP script doesn't seem to be displaying the data being sent. Using jQuery/Ajax: <script src="http://code.jquery.com/jquery-latest.js" type="t ...

There is an issue with the syntax in your for-loop control where a closing parenthesis is missing

When I try to navigate through the arrays from 1 to 4 in the given JSON data, Firebug shows me an error message: SyntaxError: missing ) after for-loop control [Break On This Error] for( x in LGIntake.corpCodeOptions.marketSegment.1){ StartI...aseId=0 ...

Using Vue: How to utilize v-slot variables in JavaScript

Can the values of the v-slot of a component be accessed in the script? For instance, consider the following template: <cron-core v-model="value" :periods="periods" :format="format" v-slot="{fields, period, error}"> {{period}} <div v-for="fiel ...

Can you explain the use of the "left" and "right" fields in the jstree jQuery plugin?

Currently, I am working on creating a tree using the jquery plugin jstree. While going through this plugin's database file, I came across two fields called "left" and "right". However, I am unclear about how these fields are utilized. Interestingly, ...

Passing a $scope.property as a reference to a factory object

I am in need of a Factory object that can be linked with a $scope.property to produce a certain result. Additionally, I require the ability to detect changes in either the modifier within the factory instance or the $scope.property in order to update the r ...

Processing Microsoft Office files with Node.js

I have a project underway for a web application that allows users to upload Microsoft Office Document files. Our current setup involves Node.JS with Express.js running on Heroku, which means I am unable to install programs like abiword or catdoc. Although ...

"The jQuery colorpicker function is not functioning properly when applied to newly added elements

I've got these amazing gadgets with a cool sliding box feature inside. Initially, there are two widgets visible on the page, but you have the option to add or delete a widget as needed. Within the sliding box, there is a color picker tool. Interestin ...

Error: Type error - unable to call function on string during Ajax request

An error message saying "Uncaught TypeError: string is not a function" keeps popping up when I attempt to make an Ajax call. Here's the code snippet: $('input.js-nome-produto-servico').live("keyup", function(ed, h){ var $campo = ed.cur ...

Leveraging ts-loader alongside strip-loader in Webpack

I am currently facing an issue with strip-loader in my Typescript project that is built with Webpack. The ts-loader statement in my project is as follows: { test: /\.ts$/, loader: 'babel-loader?presets[]=es2015!ts-loader' } Everything see ...

Instructions for manipulating and displaying a source array from a child component using Vue

I have a parent component with an array that I display in the template. My goal is to click on a link that uses vue-router with a dynamic id attribute, and then open a new component displaying only the element of the array that corresponds to that id. Howe ...

I encountered a challenge with a cross-site scripting filter that is preventing me from storing a JavaScript variable in a MySQL database using a

I am currently working on a project where I need to save a JavaScript variable into a MySQL database using a Python CGI script. In this case, the JavaScript variable contains the following information: <li style = "width: 300px; background-color: white ...

Tips on how to modify a select option in vue based on the value selected in another select

My Web Api has methods that load the first select and then dynamically load the options for the second select, with a parameter passed from the first selection. The URL structure for the second select is as follows: http://localhost:58209/api/Tecnico/Tanq ...