Customizing particle textures in Three.js Particle System for unique visual effects

I have a scene in Three.js with 1000 particles and I've loaded 2 different textures.

var particleCount = 1000;
var texture1 = THREE.ImageUtils.loadTexture( 'texture1.png' );
var texture2 = THREE.ImageUtils.loadTexture( 'texture2.png' );

var customUniforms = {
    texture:   {type: "t", value: texture1} // How can I assign unique textures to each particle?
};

var customAttributes = {
    customColor:   {type: "c", value: []},
    customSize: {type: "f", value: []}
};

for(var p = 0; p < particleCount; p++ )
{
    customAttributes.customColor.value[p] = new THREE.Color(0xFFFFFF * Math.random());
    customAttributes.customSize.value[p] = size;

    //  .. place particle and push to particles code
}

var shaderMaterial = new THREE.ShaderMaterial({
        uniforms:       customUniforms,
        attributes:     customAttributes,
        vertexShader:   document.getElementById( 'vertexshader' ).textContent,
        fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
        transparent: true,
        alphaTest: 0.5
});

This is the fragment shader:

uniform sampler2D texture;
varying vec3 vColor;
void main()
{
    // calculates a color for the particle
    gl_FragColor = vec4( vColor, 1.0 );
    // sets particle texture to desired color
    gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
}

How can I assign a different texture to each particle's fragment shader?

Answer №1

Interesting idea to send the index of the texture via an attribute.

Each particle represents a single point (point sprite).
Every point has a position (via attributes) and other properties (via attributes or uniforms).
The position is typically represented as vec3 (x, y, z) transformed into vec4(position, 1.0).
I'm not sure if three.js utilizes the fourth element ('w' from vec4), but it might be worth trying to send the texture index through that.

Vertex:

attribute vec4 vertPos; //x, y, z, w = texture index (you can use your own custom attribute)
varying float texIndex;
...
texIndex = vertPos.w;
...

Fragment:

...
if(texIndex == 0) tex = texture2D(texture0, gl_PointCoord);
else tex = texture2D(texture1, gl_PointCoord);
...

I haven't personally tested this out.
I have no previous experience with this specific library.

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

Code snippet in webpage body

Hey there, I could really use some assistance: I currently have the following: A) Login.html B) Documentation.html C) Base.html Within the login page, there is a form with fields for User and Password. In Documentation, there are links to various folder ...

Error occurs when attempting to instantiate a class with parameters that do not match any available constructor signatures

I am attempting to encapsulate each instance of router.navigateByUrl within a class function, with the intention of calling that function in the appropriate context. However, I am encountering an error that states 'Supplied parameters do not match any ...

Is there a way to efficiently line up and run several promises simultaneously while using just one callback function?

I am currently utilizing the http request library called got. This package makes handling asynchronous http connections fast and easy. However, I have encountered a challenge with got being a promisified package, which presents certain difficulties for me ...

Ways to select the initial 10 rows, final 3 rows, and middle 2 rows using Javascript

As a newcomer to Javascript, I have a couple of questions: 1) How can I retrieve the first 10 rows, the last 3 rows, and the 2 rows in the center using the code var firstTable = $('#aaa table').eq(0); 2) Is there a way to create and assign new ...

Weird Javascript behavior when classes are manipulated during mouse scrolling

Searching for a Javascript expert to assist in solving a particular issue. I have a simple function that I need help with. The goal is to add a bounceDown class when scrolling down by 1px, have it run for 5 seconds, and then remove the class for future use ...

Utilizing a mutual RxJS subject for seamless two-way data binding in Angular 2

I have a unique service dedicated to managing app configurations class Configuration { get setting() { return dataStore.fetchSetting(); } set setting(value) { dataStore.saveSetting(value); } } This configuration is linked to components t ...

How to use jQuery to maintain an image at the top of a div

Within my HTML, there is a primary root div element containing an image. <div id="root"> <img id="msg"/> </div> Using jQuery, I am able to prepend multiple div elements inside the main root div. However, the problem arises when these ...

Dealing with the validation of two forms on a single webpage: Strategies and Solutions

In a popup, there are two forms that alternate display - one for editing (loaded via ajax) and one for creation. Using jQuery validation, I aim to show hints for both editing and field submission. The validation includes ensuring time spans do not overla ...

Dealing with browser timeouts for HTTP requests using JavaScript

Managing time out situations in a web application when calling a REST API is crucial. Below is the code snippet I am using to make the API call with jQuery ajax. $.ajax({ type: "POST", url: endpoint, data: payload, ...

Typescript array iteration using dual parameters

I seem to be struggling with the logic behind this seemingly straightforward iteration question. My task involves iterating through an array of data based on id and code, removing data only when the code is not associated with the given id's. Let&ap ...

JavaScript-Based Header Features Similar to Excel

Currently, I am in the process of developing a function that generates a sequence of strings similar to Excel headers. For those who may not be familiar with Excel, the sequence goes like this: A,B,...,Z,AA,...,AZ,BA,...,ZZ,AAA,...,etc. Here is the code ...

Tips for using an array as a jQuery selector in JavaScript

Managing an element with an array id id="x[]" can be tricky when it comes to dynamically changing content based on database entries. This specific element is essentially a delete button for removing table rows from the database. <div align="center" id= ...

Guide to Dynamically Including an Element in an Array using Typescript

Encountering a type error within the <RenderFormFields formFields={formFieldsData} /> component:- Types of property 'type' are not compatible. Type 'string' cannot be assigned to type '"select"'.ts(2322) Rende ...

Guide on how to use Vue's watch feature to monitor a particular property within an array

I am interested in observing the "clientFilter" within an array TableProduit: [ { nr_commande: 0, date_creation: "", id_delegue: "1", clientFilter: "" } ], ...

Code Not Executing

I have come across an issue with two select tags that are supposed to show or hide divs based on the dropdown selection. Strangely, I am able to get them to work independently, but when trying to make them work together, they fail. Any ideas as to why this ...

What is the solution to the error "Maximum update depth exceeded. Calls to setState inside componentWillUpdate or componentDidUpdate" in React?

Everything was running smoothly until this unexpected issue appeared. I attempted to change the condition to componentDidMount, but unfortunately, that didn't resolve the problem. The error is occurring in this particular function. componentDidUpd ...

How to dismiss a jQueryMobile dialog without triggering a page refresh

I've encountered a question similar to this before, but there wasn't any solution provided. The issue I'm facing is that I have a form and when a user clicks on a checkbox, I want to open a popup/dialog for them to enter some data. However, ...

Switching the color scheme between mobile and desktop devices to make the background look

As a newcomer to threejs, I have just begun learning and developing with this technology. I am aware that certain features may be different on mobile browsers compared to desktop ones due to limitations. However, I have encountered an issue that I cannot s ...

Connect to the MongoDB database running on localhost using the mongoose library

I am currently learning about the MEAN stack through this helpful tutorial. However, the tutorial assumes a connection to a remote mongodb installation. I have MongoDB already set up and running on my CentOS7 localhost. To modify the mongoose connect line ...

Identify whether the application is built with nextJS, react, or react-native

I'm currently developing a library for React applications and I anticipate that certain features will function differently depending on the environment. I am seeking a method to identify whether the current environment is a ReactJS application (creat ...