Using Three.js: applying a gradient color to points

In my project using threejs, I am working on creating and rendering a point cloud. One of my goals is to assign each point a specific color based on its Z coordinate. Ideally, I want the color to follow a gradient approach starting from green for the smallest Z values, going through blue, yellow, and finally red for the largest Z values. Can anyone suggest an efficient method to achieve this color mapping for each point?

While my actual script is lengthy, I have condensed it down to these key lines:

function drawCloud(){
    for(i = 0; i < totalPoints * 3; i = i + 3){
        //Adjusting the Z value for each point
        //Z coordinate is every third value, hence i+2
        points.geometry.attributes.position.array[i+2] = theNewZValueForThisPoint;

        //Assigning colors to points
        // R,G, B values are represented by i, i+1, i+2 respectively
        //Here, each point is given a green color
        points.geometry.attributes.color.array[i] = 0;
        points.geometry.attributes.color.array[i+1] = 1;
        points.geometry.attributes.color.array[i+2] = 0;
    }    
}

function animate() {
    requestAnimationFrame(animate);
    drawCloud();
    render();
  }
  
  function render() {
    renderer.render(scene, camera);
  }


Previously, I attempted a segmentation approach where each point was assigned a fixed color within specified ranges. However, this approach resulted in abrupt color transitions between segments. My goal now is to achieve a more gradual gradient change in color as Z values increase.

It's important to note that the code presented here has been simplified for clarity. Any suggestions for enhancements or optimizations would be greatly appreciated.

Answer №1

If you have the minimum and maximum z-values for your point cloud, you can utilize this function to determine the color of each point based on a customized gradient defined in the gradient-array:

function getColor(z, zMin, zMax) {
  
  // method to normalize value within specified range
  function normalize(v, vMin, vMax) {
    return ((v - vMin) / (vMax - vMin));
  }

  // method to clamp a value between specified min and max values
  function clamp(value, min, max) {
    if (value >= max) return max;
    if (value <= min) return min;
    return value;
  }

  // method for linear interpolation of two numbers
  function lerp(a, b, alpha) {
    return a + (b - a) * clamp(alpha, 0, 1);
  }
  
  const zNorm = normalize(z, zMin, zMax);

  // define gradient with breakpoints and colors
  const gradient = [
    {bp: 0,   r: 0, g: 1, b: 0},
    {bp: 1/3, r: 0, g: 0, b: 1},
    {bp: 2/3, r: 1, g: 1, b: 0},
    {bp: 1,   r: 1, g: 0, b: 0}
  ];

  let red, green, blue;

  // find color segment and interpolate color between breakpoints
  for(let i = 0, g = gradient.length; i < g; i++) {
    if(zNorm < gradient[i].bp || gradient[i].bp === 1) {
      red = lerp(gradient[i-1].r, gradient[i].r, normalize(zNorm, gradient[i-1].bp, gradient[i].bp));
      green = lerp(gradient[i-1].g, gradient[i].g, normalize(zNorm, gradient[i-1].bp, gradient[i].bp));
      blue = lerp(gradient[i-1].b, gradient[i].b, normalize(zNorm, gradient[i-1].bp, gradient[i].bp));
      break;
    }
  }
  
  return {r: red, g: green, b: blue};
}

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 coloring feature in Excel Add-in's React component fails to populate cells after the "await" statement

Currently, I am developing a Microsoft Excel Add-in using React. My goal is to assign colors to specific cells based on the value in each cell, indicated by a color code (refer to the Board Color column in the image below). To achieve this, I retrieve the ...

I am unable to comprehend the function definition

I have familiarity with different types of JavaScript function declarations such as expression functions and anonymous functions. However, I am unsure about the syntax used in these two specific functions: "manipulateData: function (input)" and "getDataByI ...

Creating a visually appealing chart similar to Excel can be achieved using JavaScript with a whopping 64382 lines of JSON data. No need for Chart.js or any additional tools - simply rely on JavaScript, HTML, and CSS to

I have a project that is due in just a few hours and I need to create a detailed chart using a large set of 64382 lines of JSON data. My knowledge of javascript is limited, so I am struggling to come up with ideas on how to approach this task. While I have ...

JQuery Mobile pop-up error: Property 'is' is not defined

I am attempting to utilize jQuery to open a dialog box. I have followed the instructions provided in this link: Here is the code snippet for the dialog: <div data-role="popup" id="popupDialog" data-overlay-theme="a" data-theme="c" style="max-width ...

Cross-Origin Resource Sharing (CORS) and the Access-Control-Allow-Origin problem

I am currently developing an AngularJS web application that communicates with a RESTful Jersey Api as its Backend. I have implemented a function to make API calls, and here is an example: function Create(user) { return $http.post('http://loca ...

The input type '{}' does not match the expected type 'Readonly<IIdeasContainerProps>'. The property '...' is not found in the type '{}'

Having recently started using TypeScript, I'm encountering some issues when attempting to execute this code snippet. Error The error message reads as follows: Failed to compile 13,8): Type '{}' is not assignable to type 'Readonly &l ...

The jQuery included does not function properly in production mode and results in an error stating that it is not a function

After placing the jquery.placeholder.js file in the assets/javascripts folder, I successfully applied the function in my coffeescript file and it worked perfectly. $(document).ready -> $('input, textarea').placeholder(); However, when swit ...

``Change the color of the sections in a 3D pie chart on a Highcharts

I am looking to create a custom pie chart with two different colors: one for the main surface and another for the sides. Currently, I can only configure the lighter blue color for the main surface, but I would like to also change the darker blue color for ...

Adjust the color of the active link on the page using Angular and CSS

I have a project that I need to modify by adding a sub menu that appears on every page but is only coded once. My goal is to highlight the link for the current page, all within one HTML snippet. Although the list renders correctly, I'm struggling to g ...

Concealing choices that have already been chosen in a ReactJS select dropdown menu

My challenge involves having 3 select boxes with the same option values, where users set security questions. Each question is selected and answered by the user. I fetched security questions via an API call and stored them in an array named "securityQuestio ...

Remove all instances of an empty array within a larger array

Is there a way to eliminate an empty array from within a parent array prior to adding a new element? In the structure provided, it appears as follows: var parentArray = [ ['123', '345'], [], ['12'] ] The goal is to remove t ...

Using VueJS to access dynamic component data within a method executed through v-bind

I am currently facing a unique challenge and finding it difficult to come up with a solution. My project involves creating a file manager-like feature in Vue, where I want specific folders or files to display custom thumbnails. For example, showing the Cr ...

The target element is out of reach for the Puppeteer selector

When trying to extract the source of multiple images, I encountered an issue with the selectors not working properly. It seems like the elements are fake or not actually present on the page. Every page contains one of the desired elements (the main image) ...

Is it necessary to compile the React JavaScript project before uploading it to npm?

Hey there, I'm currently in the process of publishing a React JavaScript component on npm. I have a question regarding whether or not I need to build the project and deploy the build folder. Your input would be greatly appreciated. Thanks! ...

Simpler and more sustainable methods for embedding HTML elements using a configuration file

Currently, I am devoting my time to a toy project that heavily relies on JavaScript. A key component of this project is a JSON file that contains configurations and input descriptions, along with range values and options. This JSON file enables me to easil ...

Utilizing jQuery to target a select element's two specific children

I am trying to target the parent element by matching two specific children elements. Here is my code: $('span:contains("11:00am"), span.name:contains("Tom")').parents("a").css("background-color","rgb(255, 255, 255)"); <script src="https://c ...

Using a dynamic HTML interface, select from a vast array of over 50,000 values by leveraging the power

I am working on a project that includes a multiselect option with over 50,000 records. We are using AJAX to fetch data from the server based on user searches, which works fine. However, when a user tries to select all records by clicking the "check all" ...

Tips for sending the setState function to a different function and utilizing it to identify values in a material-ui select and manage the "value is undefined" issue

I am currently utilizing a Material UI select component that is populated with data from an array containing values and options. Within this array, there exists a nested object property named "setFilter". The setFilter property holds the value of setState ...

Remove items from an array using other items from another array as the index

Let's consider the following scenario: let arr1 = [0,2] // This array is always sorted Just to clarify, these elements in the "arr1" array represent indexes that need to be removed from another array. We also have another array: let arrOvj = [1,4,6, ...

JavaScript String Splitting with Regular Expressions

It's like the solution is right in front of me, but I just can't seem to see it. var expr = "-5+6.3x24"; console.log(expr.split(/([+\-x\/])/)); The expected output should be: ["-5", "+", "6.3", "x", "24"] I want to split the string ...