Changing the color of each line within a BufferGeometry using Three.js

This example demonstrates drawing lines with the same color. I aimed to change the color of each line and here are the modifications I made:

Introducing attribute

  const colors = new Float32Array(MAX_POINTS * 3);
  geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));

Modifying material

const material = new THREE.LineBasicMaterial({ vertexColors: true });

In the update function, altering colors

   ...
for ( let i = 0, l = MAX_POINTS; i < l; i ++ ) {
    UpdateColor();
    colors[Cindex++] = rgb[0];
    colors[Cindex++] = rgb[1];
    colors[Cindex++] = rgb[2];
    
    positions[ index ++ ] = x;
    positions[ index ++ ] = y;
    positions[ index ++ ] = z;

    x += ( Math.random() - 0.5 ) * 30;
    y += ( Math.random() - 0.5 ) * 30;
    z += ( Math.random() - 0.5 ) * 30;
}

An additional line added in animate()

 line.geometry.attributes.color.needsUpdate = true;

The updated version can be found here.

Despite my efforts, only a few lines change color as intended. What steps should I take to achieve the desired result?

Answer №1

Implement the usage of LineSegments in conjunction with a buffer geometry that is not indexed, and ensure that vertexColors: true is specified in the material:

body{
  overflow: hidden;
  margin: 0;
}
<script type="module">
import * as THREE from 'https://cdn.skypack.dev/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="37435f4552527707190604001902">[email protected]</a>';

let renderer, scene, camera;

let line;
const MAX_POINTS = 500;
let drawCount;
let prevPoint = new THREE.Vector3();
let currPoint = new THREE.Vector3();
let color = new THREE.Color();

init();
animate();

function init() {

    // info
    const info = document.createElement( 'div' );
    info.style.position = 'absolute';
    info.style.top = '30px';
    info.style.width = '100%';
    info.style.textAlign = 'center';
    info.style.color = '#fff';
    info.style.fontWeight = 'bold';
    info.style.backgroundColor = 'transparent';
    info.style.zIndex = '1';
    info.style.fontFamily = 'Monospace';
    info.innerHTML = "Interactive animated LineSegments rendering without indexing in three.js";
    document.body.appendChild( info );

    // renderer
    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio( window.devicePixelRatio );
    renderer.setSize( window.innerWidth, window.innerHeight );
  //renderer.setClearColor( 0x7f7f7f);
    document.body.appendChild( renderer.domElement );

    // scene
    scene = new THREE.Scene();

    // camera
    camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.set( 0, 0, 1000 );

    // geometry
    const geometry = new THREE.BufferGeometry();

    // attributes
    const positions = new Float32Array( MAX_POINTS * 3 * 2); // 3 vertices per point
    geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
  const colors = new Float32Array( MAX_POINTS * 3 * 2);
  geometry.setAttribute( 'color', new THREE.BufferAttribute( colors, 3) );

    // drawcalls
    drawCount = 2; // draw the first 2 points, only
    geometry.setDrawRange( 0, drawCount );

    // material
    const material = new THREE.LineBasicMaterial( { vertexColors: true } );

    // line
    line = new THREE.LineSegments( geometry,  material );
    scene.add( line );

    // update positions
    updatePositions();

}

// update positions
function updatePositions() {

    const positions = line.geometry.attributes.position;
  const colors = line.geometry.attributes.color;

    let x, y, z;
    prevPoint.set(0, 0, 0);
  currPoint.set(0, 0, 0);

    for ( let i = 0, l = MAX_POINTS; i < l; i ++ ) {
        
    positions.setXYZ(i * 2, prevPoint.x, prevPoint.y, prevPoint.z);
        currPoint.random().subScalar(0.5).multiplyScalar(30).add(prevPoint);
    positions.setXYZ((i * 2) + 1, currPoint.x, currPoint.y, currPoint.z);
    prevPoint.copy(currPoint);
    
    color.set(Math.random() * 0xffffff);
    colors.setXYZ(i * 2, color.r, color.g, color.b);
    colors.setXYZ(i * 2 + 1, color.r, color.g, color.b);

    }
  
  positions.needsUpdate = true;
  colors.needsUpdate = true;

}

// render
function render() {

    renderer.render( scene, camera );

}

// animate
function animate() {

    requestAnimationFrame( animate );

    drawCount = ( drawCount + 2 ) % (MAX_POINTS * 2);

    line.geometry.setDrawRange( 0, drawCount );

    if ( drawCount === 0 ) {

        // periodically, generate new data

        updatePositions();


    }

    render();

}

</script>

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

A step-by-step guide on uploading a CSV file in Angular 13 and troubleshooting the error with the application name "my

I am currently learning angular. I've generated a csv file for uploading using the code above, but when I try to display it, the screen remains blank with no content shown. The page is empty and nothing is displaying Could it be that it's not ...

Can the front end acquire JSON data from a URL, save it as a JSON file with a unique name, and store it in a designated location?

I'm facing a straightforward problem with my React Native project. I am attempting to create a script that will be executed during the build process to fetch JSON data from a URL and then store it as a JSON file with a unique name in a specific direct ...

Use bracket notation to verify if a property is undefined

Having some difficulty determining if the property value of an object is undefined when accessed dynamically with bracket notation. Here's a snippet of my code: function toBritishDate(date: Date | string): string { console.log(date) return &qu ...

Javascript is responsible for causing a div to become stuck in a loop of alternating between

My current challenge involves a JavaScript function that manipulates boxes by toggling classnames. The strange issue I'm facing is that the correct classes are being set at the correct times, but the div keeps alternating between the original class an ...

React hook, when not properly called, may result in an error known as

While working on a project with React hooks, I encountered the error message below. Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might ha ...

What is the best way to configure the loading state of my spinner?

When a user clicks to navigate to the articles page, I want to display a spinner while waiting for the articles data to be fetched and displayed. There is a slight delay after the click, hence the need for the spinner. I have a custom spinner component ca ...

Error: Jest react testing encountered an issue when attempting to read the property 'type' from an undefined value

While conducting tests on my app components created with the material UI library using jest and enzyme, I encountered an error in one of my packages. Here is a screenshot of the error: Click here to view ...

What is the process for making a fetch request to Paypal's Oath API version 2?

After spending days working on setting up a functional payment portal on my website, I have hit a roadblock. My website does not directly sell products, but I do need to accept payments for invoices generated from my Paypal business account. To achieve thi ...

Troubles with Angular elements not aligning correctly when using the "display: block" property

When using an angular element for a directive with "display: block", it may not automatically take up 100% of the width of the parent container. In order to ensure that it does, the width must be explicitly set to "100%" in the CSS. Despite setting "width: ...

What is the correct way to reference this data element in Ajax?

I am attempting to retrieve the elevation data for 732 meters from the JSON API response below: {"results":1,"data":[{"wind":{"degrees":200,"speed_kts":6,"speed_mph":7,"speed_mps":3,&quo ...

How can I toggle button states within a v-for loop based on input changes in Vue.js?

Within the starting point of my code: https://plnkr.co/LdbVJCuy3oojfyOa2MS7 I am aiming to allow the 'Press' button to be active on each row when there is a change in the input field. To achieve this, I made an addition to the code with: :dis ...

Enhancing Image Upload with Ajax/JavaScript: Generating Multiple Previews

I've been experimenting with an Ajax image uploader that I found on this website. Currently, I have managed to create duplicate preview images: one displayed under the input field and the other elsewhere on the page labeled as "this what you chose". H ...

React error #425: Timezone formatting causing minification issue

Encountering a strange issue that seems to only occur on Vercel. The error message reads: Uncaught Error: Minified React error #425; visit https://reactjs.org/docs/error-decoder.html?invariant=425 for the full message or use the non-minified dev environme ...

Storing array data locally within an AngularJS application for seamless sharing between two separate applications

I need assistance with persisting and sharing array data var queries = []; between two separate AngularJS applications. One application is for the front end, while the other is for the admin side. Both applications cause the entire page to load when access ...

Using jQuery to append text after multiple element values

I currently have price span tags displayed on my website: <div> <span class="priceTitle">10.00</span> </div> <div> <span class="priceTitle">15.00</span> </div> <div> <span class="priceTitle">20.0 ...

What is the process for adding or modifying attributes in child elements?

I have been experimenting with a simple script that adds the target="_blank" attribute to all the <a> elements. $(function(){ $('a').attr('target', '_blank'); }); While it is functioning perfectly, I am now interested ...

What is the method to rotate an SVG icon contained within a button when clicked?

I'm attempting to incorporate a CSS animation into an SVG that is enclosed within a button. Example <button class="spin"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ari ...

Finishing up with regular expressions

I want to create an autocomplete feature for the input field on my website. For instance, when the tab key is pressed, I want the word htt to automatically become tp:// in the input value. This autocomplete should only work if the user inputs "htt" at the ...

Transmit responses from PHP script

I am in the process of creating a signup form where, upon clicking the submit button, all form data is sent to a PHP file for validation. My goal is to display an error message next to each input field if there are multiple errors. How can I achieve this ...

Utilizing jQuery to Retrieve Column and Row Headers of a Selected Cell

I am currently working on a JavaFX project that includes a WebView. The HTML code is being generated using a StringBuilder. My goal is to retrieve the column and row headers of the selected cell. This information is necessary for my Java code. You can ...