What I'm trying to do is create multiple PointCloud's, and assign each of them a different color. With the PointCloudMaterial, it had a color property that seemed to do the trick, but since I'm using a ShaderMaterial I can't seem to figure out how to achieve similar results.
[Edit: added images to clarify]
I'm using a ShaderMaterial because there were some custom attributes I wanted to scale and change the opacity for each vertex.
Function for creating a particle cloud:
function addParticleCloud(width, height, colorIn, particleCount) {
var geometry = new THREE.Geometry();
// add randomized vertex positions for geometry
for (var i = 0; i < particleCount; i++) {
var vertex = new THREE.Vector3();
vertex.x = Math.random() * width;
vertex.y = Math.random() * height;
vertex.z = z;
geometry.vertices.push(vertex);
}
var attributeCount = attributes.alpha.value.length;
var totalCount = attributeCount + geometry.vertices.length;
// change attributes per particle/vertex
for (var i = attributeCount; i < totalCount; i++) {
// random alpha
attributes.alpha.value[i] = Math.random();
// random scale
attributes.scale.value[i] = Math.random() * (250.0 - 100) + 100;
// TRIED TO CHANGE COLORS HERE, but every cloud created afterwards has the
// same color as the first one.
attributes.colorVal.value[i] = new THREE.Color(colorIn);
attributes.colorVal.needsUpdate = true;
// update attributeCount
attributeCount = attributes.alpha.value.length;
}
var material = new THREE.ShaderMaterial({
uniforms: uniforms,
attributes: attributes,
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
transparent: true,
});
// This is the kind of thing I'd like to be able to do
//material.color = new THREE.Color(colorIn);
var particles = new THREE.PointCloud(geometry, material);
scene.add(particles);
}
Code calling that function:
// [width, height, color]
var rectangles = [
[400, 200, 0xA3422C],
[40, 500, 0x0040f0],
[200, 200, 0x2CA35E],
[40, 500, 0x2C8DA3],
];
for (var i = 0; i < rectangles.length; i++) {
var sqWidth = rectangles[i][0];
var sqHeight = rectangles[i][3];
var rectColor = rectangles[i][2];
var particleCount = 100;
// Note: I've removed some parameters for clarity (xyz positions, etc.)
addParticleCloud(sqWidth, sqHeight, rectColor, particleCount);
}
Code for vertex and fragment shader:
<script type="x-shader/x-vertex" id="vertexshader">
attribute float alpha;
attribute float scale;
attribute vec3 colorVal;
uniform float size;
varying float vAlpha;
varying vec3 vColor;
void main() {
vColor = colorVal;
vAlpha = alpha;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( scale / length( mvPosition.xyz ) );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
varying float vAlpha;
varying vec3 vColor;
void main() {
gl_FragColor = vec4( vColor.rgb, vAlpha );
}
</script>
Attributes and Uniforms:
// attributes
attributes = {
alpha: {type: 'f', value: []},
shouldFade: {type: 'b', value: []},
scale: {type: 'f', value: []},
colorVal: {type: "c", value: []},
};
// uniforms
uniforms = {
size: {type: "f", value: 100.0},
};