Enhancing the ShaderMaterial attribute in three.js

Exploring the three.js tutorial on shaders, we discover a technique for updating uniform values of a ShaderMaterial:

var attributes = {
  displacement: {
    type: 'f', // a float
    value: [] // an empty array
  }
};
var uniforms = {
  amplitude: {
    type: 'f', // a float
    value: 1
  }
};

var vShader = $('#vertexshader');
var fShader = $('#fragmentshader');

// create the final material
var shaderMaterial =
    new THREE.MeshShaderMaterial({
      uniforms:       uniforms,
      attributes:     attributes,
      vertexShader:   vShader.text(),
      fragmentShader: fShader.text()
    });
...

var frame = 0;
function update() {

  // update the amplitude based on
  // the frame value.
  uniforms.amplitude.value =
    Math.cos(frame);

  // update the frame counter
  frame += 0.1;

  renderer.render(scene, camera);

  // set up the next call
  requestAnimFrame(update);
}

The tutorial does not address whether the same principle applies to attributes. In my own experimentation, I attempted to introduce jitter in the vertices of a sphere demo by assigning random displacements each frame:

  function update() {

    // update the amplitude based on
    // the frame value.
    values = attributes.displacement.value

    for(var v = 0; v < vertCount; v++) {
        values[v] = (Math.random() * 30);
    }

    renderer.render(scene, camera);

    // set up the next call
    requestAnimFrame(update);
  }

Unfortunately, this resulted in a static misshapen sphere. It seems that attributes retain only their initial assigned value and cannot be updated subsequently. Is this behavior typical of glsl attributes, or should there be an additional step required for updating attributes? If so, are there any workarounds available aside from manipulating vertex positions directly in javascript?

Answer №1

After some experimentation, I discovered that it is indeed feasible to modify attributes such as uniforms. Surprisingly, the key piece of code that resolved my issue was:

attributes.displacement.needsUpdate = true;

This crucial line had been left out of the instructional material, but once included, it produced the desired outcome flawlessly.

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

Suggestions for improving the smoothness of the Bootstrap toggle hide/show feature

Recently completed my bootstrap toggle hide/show feature and everything seems to be functioning correctly, except for the transition between the different contents. The borders appear jagged and not smooth when activating the toggle. I suspect there may b ...

What is the best way to connect a line from the edge of the circle's outermost arc?

I am attempting to create a label line that extends from the outermost point of the circle, similar to what is shown in this image. https://i.sstatic.net/OqC0p.png var svg = d3.select("body") .append("svg") .append("g") svg.append("g") .attr("cl ...

Adding pixels to the top position with jQuery in Angular 2

I am trying to adjust the position of my markers when the zoom level is at 18 or higher by adding 10px upwards. However, my current approach doesn't seem to be working as expected. Can someone please assist me with this issue? You can view the code sn ...

Redux export does not complete correctly unless brackets are used

I'm trying to understand why the main JS file is having trouble importing todo from './actions' without brackets, while there are no issues with importing todos from './reducers'. Main js-file: import { createStore } from 'r ...

Tips for positioning a div relative to another div while controlling its z-index

Hey there, take a look at the image below https://i.sstatic.net/zYiaY.png The issue I'm facing is quite common - I have div 1 and div 2 visible in a loop, but divs 3 are hidden. When div 2 is clicked on, everything is great so far. However, what I wa ...

Implementing JavaScript Code in TypeScript

Every JavaScript code should also be valid in TypeScript, but when attempting to run the following code snippet below, an error is triggered. Could someone convert this JavaScript code into TypeScript? Error: 20:9 - TS2531 Error: Object is possibly 'z ...

Node.js and MySQL: Troubles with closing connections - Dealing with asynchronous complexities

I am currently working on a Node program to populate my MySQL database with data from files stored on disk. While the method I'm using seems to be effective, I am facing challenges in ensuring that asynchronous functions complete before ending the con ...

What is the best method for retrieving a child control from a TR element?

I am facing an issue with a hidden field inside each Tr in my template: <ItemTemplate> <tr style="" class="ui-selectee trClass ui-widget-content"> <td style="width: 100px"> <asp:HiddenField ID="idField" runat=" ...

Obtain the dynamic $scope variable within the HTML structure

When creating numerous directives with dynamic scope variables initialized in the link functions, accessing these values within the directive templates can get tricky. For example: // link: function(scope, ele, attr){ scope.key = scope.somevar + 's ...

Issue with jquery .click function not triggering after CSS adjustment

In the process of creating a fun game where two players take turns drawing on a grid by clicking <td> elements. Currently, I have implemented the functionality to toggle the background color of a <td> element from black to white and vice versa ...

How to effectively utilize wrapAsync in MeteorJS when working with callbacks in the vzaar API?

Issue to Resolve: My current challenge involves retrieving an uploaded video ID asynchronously from an API in order to incorporate it into my code once the video upload process is completed. Unfortunately, I am encountering issues where the returned value ...

Passing all selected items from a list to the controller

I am currently facing an issue with my two multi-select lists. One list contains a full list of names while the second one holds the names that have been selected from the first list. The names are stored in a Vue array which populates the names into the s ...

Steps to display a text box once the dropdown list is updated

I have a dropdown menu with two options <div class="form-group"> <span class="col-sm-4 control-span">Member Type</span> <div class="col-sm-8"> <select class="form-control" id="membertype" name="me ...

Show various attachment file names using jQuery

Utilizing jQuery, I've implemented a script to extract the filename from a hidden field and then append it to the filename class in my HTML. filenameCache = $('#example-marketing-material-file-cache').val().replace(/^.*[\\\/ ...

Can someone explain the significance of receiving a TypeError when trying to access properties of null (specifically 'useRef') in a React application?

I encountered an issue while working on a React project...the browser console displays the following error. What does this mean? And how can I resolve it? react.development.js:1545 Uncaught TypeError: Cannot read properties of null (reading 'useRef ...

The Image component in a test within Next.js was not wrapped in an act(...) during an update

After setting up a basic NextJS app with create-next-app and integrating Jest for testing, I encountered an error message stating "An update to Image inside a test was not wrapped in act(...)". The issue seems to be related to the Image component in NextJS ...

There was an issue when trying to process the Javascript data structure with JSON.parse

Currently, I have the following data stored in a JavaScript variable: "{'Headings': [{'name': 'Behavior', 'majorTopic': 'N', 'vote': {'down': 1, 'up': 1}}, {'na ...

What is the best way to create a reusable component for a Material-UI Snackbar?

Having trouble getting my Alert component to display a message that says "Successfully submitted" in the parent component. The message doesn't seem to be showing up. AlertComponent import React, { useState } from "react"; import { Snackbar, Alert } f ...

Ways to initiate state transition from child component to parent component using React Hooks?

In the parent component, I have the following: const [updateQuantity, quantity] = useState(1); const handleChangeQuantity = e => { console.log(e.target.value); console.log("TEST"); updateQuantity(e.target.value); }; I the ...

Is checking for an email address in a form necessary?

I am currently in the process of creating a coming soon page. I have included a form on the page where users can sign up using their email addresses, which are then sent to me via email. However, I need assistance in determining how to verify that the in ...