Custom shader not properly updating position of Three.js vertices

I have developed a custom shader using three.js that allows me to modify individual vertices' color, size, and position.

While the color and size modifications work as expected, updating the vertex x, y, or z values does not reflect on the screen.

JSFiddle

What could I be overlooking?

Vertex Shaders:

<script type="x-shader/x-vertex" id="vertexshader">

  attribute float size;
  attribute vec3 color;

  varying vec3 vColor;
  varying vec2 vUv;

  void main() 
  {
    vColor = color;
    gl_PointSize = size;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }

</script>

Fragment Shader

<script type="x-shader/x-fragment" id="fragmentshader">

  uniform sampler2D texture;

  varying vec2 vUv;
  varying vec3 vColor;

  void main() 
  {
    vec4 color = vec4(vColor, 1);
    gl_FragColor = color;
  }

</script>

JavaScript:

var container = document.getElementById('container');
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 100;

var scene = new THREE.Scene();

var vShader = document.getElementById('vertexshader').textContent;
var fShader = document.getElementById('fragmentshader').textContent;

var uniforms = {};

var attributes = {
  color: { type: 'c', value: [] },
  size:  { type: 'f', value: [] }
};

var geometry = new THREE.Geometry();

for ( var i = 0; i < 100; i ++ ) 
{
  var angle = Math.random() * Math.PI * 2;
  var radius = 40 + (Math.random() * 5);

  var vertex = new THREE.Vector3();
  vertex.x = Math.cos(angle) * radius;
  vertex.y = Math.sin(angle) * radius;
  vertex.z = 0; 

  attributes.size.value[i] = Math.random() * 10;
  attributes.color.value[i] = new THREE.Color( 0xff0000 );

  geometry.vertices.push( vertex );
}

var material = new THREE.ShaderMaterial(
{ 
  uniforms: uniforms,
  attributes: attributes,
  vertexShader: vShader,
  fragmentShader: fShader,
  transparent: true
});

var particleSystem = new THREE.PointCloud(geometry, material);
scene.add( particleSystem );

renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x292B30, 1 );
container.appendChild( renderer.domElement );

animate();

function animate() 
{
  requestAnimationFrame( animate );
  render();
}

function render() 
{
  for (var i = geometry.vertices.length - 1; i >= 0; i--) 
  {
    geometry.vertices[i].z = geometry.vertices[i].z - 0.5 ;
  }

  camera.lookAt( scene.position );
  //particleSystem.geometry.__dirtyVertices = true;
  renderer.render( scene, camera );
}

Answer №1

When adjusting the position of the vertex, make sure to activate the verticesNeedUpdate flag:

geometry.verticesNeedUpdate = true;

Check out the updated code snippet here: https://jsfiddle.net/1cmg0z2f/2/

In Three.js version r71, there are modifications in the ShaderMaterial, causing the fiddle to be incompatible with the latest update.

Answer №2

After leaving a comment on the existing accepted answer, I want to provide an updated response.

Here is the code snippet:

geometry.attributes[attributeName].needsUpdate = true

For example:

geometry.attributes.position.needsUpdate = true


It's important to note that this solution applies to custom or shader attributes created using setAttribute, which was my initial search before discovering this question and answer pair.

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

Adapt vanilla JavaScript code to be compatible with Node.js, MongoDB, and Express framework

In the midst of working on a blog project for my class, I find myself faced with the challenge of integrating Nodejs, Mongo, and Express into our existing setup. Up until now, we have been gradually transitioning to using Express in our application develop ...

Example of jQuery UI tabs - each new tab opens with a unique script assigned

Here is a jQuery tabs script that you can check out: http://jqueryui.com/demos/tabs/#manipulation var $tabs = $( "#tabs").tabs({ tabTemplate: "<li><a href='#{href}'>#{label}</a> <span class='ui-icon ...

Modify the JSON object once it has been imported into Three.js

I am diving into the world of JavaScript and exploring Three.JS, a fascinating new frontier for me. Recently, I managed to convert an obj file into a JSON object and successfully loaded it onto my website using THREE.JSONLoader in three.js. The object disp ...

Balancing website speed with capturing product impression

I've been tasked with capturing impressions of all the products visible in the viewport on a website that features thousands of products. To achieve this, I implemented a directory and utilized the IntersectionObserver, which was referenced within the ...

Having trouble clicking on an element in Selenium Webdriver with Python? It seems like the property 'click' is returning null

Encountering an error when attempting to execute this command: driver.find_element_by_link_text("Confirm").click() selenium.common.exceptions.WebDriverException: Message: unknown error: Element <a href="javascript:void(0);" class="c-button u-fontSize1 ...

I'm wondering if affdex-sdk can be utilized in node.js to store emotion data in mongodb

Is it possible to utilize the affdex Javascript SDK with Node.js for saving emotion data to MongoDB? Can the emotion data collected on the frontend be passed to the backend (Node.js) for storage in MongoDB? The CameraDetector constructor requires four pa ...

Creating a stunning star using three.js, just like the mesmerizing 100,000 stars in Chrome Experiments

I'm hoping I've found the right place this time. I'm currently trying to understand how to create a star using three.js similar to the way it was done in the chrome experiments 100,000 stars project. Although I looked into the source code, i ...

What is the best approach: Referencing schema within properties or including it as an array in Mongoose?

Consider the scenario where we have two schemas, User and Post. Should we include a reference to User in Post's properties or should we add an array of Post schema inside User schema? Which approach is more efficient in terms of performance and other ...

React and Material UI: Ensuring Proper Whitespace Handling in Strings

Exploring the use of Typography component from Material UI (https://material-ui.com/api/typography/) The main objective is to maintain the new lines and spaces in a saved string. For instance, if the string contains leading spaces and new lines, it shoul ...

Accessing PHP variables within a React componentTo access external

How can I pass the id selected in a menu from a react component to a PHP file, after already knowing how to send data from PHP to the react component? $.ajax({url: '/file.php', type: 'POST', dataType: 'json', ...

Swapping out the title attribute within imgbox

After updating to the latest version of imgbox, I encountered a similar issue as I did with LightBox2 involving the 'title' attribute. It creates a caption, but the HTML tends to show a hovertext over the image link. Here is an example: <a ...

Limit DerbyJS to re-rendering specific DOM elements

Currently, DerbyJS (visit http://derbyjs.com) functions by replacing everything in the body tag of the document each time a link is clicked. Is there a way to utilize the template, but replace only the content inside #main-content instead of refreshing th ...

Troubleshooting issue with jquery.i18n.properties functionality

I am encountering an issue with implementing jQuery internationalization. I have included the files jquery.i18n.properties.js, jquery.i18n.properties-min.js, and jquery-min.js in my resources folder. In my jsp, I have added the following code: <script ...

What methods can we employ to prevent the GraphQL query from being triggered with every keystroke when using React?

Recently, I received a new task that requires me to implement input value debouncing to prevent backend requests on every keystroke. Additionally, I need to establish an internal useState for CollectionsAutocomplete, which is connected to the generalQuery ...

What is the method for retrieving the name of a canceled file?

When a user clicks on the "Cancel" button during an upload, I am attempting to retrieve the filename of the file that was canceled. However, it seems like the current method I am using (var image_file_name) is not successfully retrieving the name of the ca ...

What is the best method for incorporating headers and custom server-side .js in an express.js / node.js application?

Recently, I've been working on developing a data-driven HTML site specifically tailored for developers at our company. The main concept involves setting up a server using node.js v0.12+ / express v4+ to handle various functions for accessing a large d ...

Is there a way to create a menu using only CSS?

Is there a way to achieve this using only CSS without any JavaScript? For reference, here's the fiddle: http://jsfiddle.net/q646Ljg6/4/ This is the HTML: <div id="navigation" class="navigation"> <div id="dropmenu" class="dropmenu"> ...

Incorporating a digital currency ticker onto your webpage

Hey there, I've been diving into the world of integrating third-party API's into my website and currently exploring the documentation provided by . I'm finding it challenging to grasp how to implement a specific ticker (such as BTC/USD) usin ...

Implementing USB trigger for cash drawer in web development

I am wondering about how to use a USB trigger to open a cash drawer (BT-100U). Can someone provide guidance on integrating this into a website? Here is a brief description of the BT-100U Cash Drawer Driver Trigger with USB Interface: This device allows fo ...

Jose authentication is encountering issues with verifying JWT

My Next.js/Clerk.js middleware setup looks like this: import { authMiddleware } from "@clerk/nextjs"; import { jwtVerify } from "jose"; export default authMiddleware({ publicRoutes: ["/", "/contact", "/pricin ...