1

In Three.js I have 1000 particles and 2 different textures loaded in.

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 do you set this value per a 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
});

Here 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 do I send a different texture to each particle's fragment shader?

1

1 Answer 1

0

Hmm... send index of texture via attribute.

Each particle is single point. (point sprite)
Each point have position (via attribute) and other properties. (via attributes or uniforms)
Position is normally type of vec3 (x, y, z) transformed into vec4(position, 1.0).
I don't know is three.js using fourth element ('w' from vec4) but you can try to send texture index via that.

Vertex:

attribute vec4 vertPos; //x, y, z, w = texture index (you can use 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 didn't test that.
I have never used this library.

Sign up to request clarification or add additional context in comments.

2 Comments

Something like this will work. You'd need to pass in each texture to the fragment shader, which is not ideal if you add more textures to choose from.
@wwwuser so finally how do you did that? any sudo code or jsfiddle ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.