When working with THREE.js points, I often find the need for them to have different colors on a per-point basis. In some cases, I also adjust the alpha value, which leads me to write my own shader programs.
Here is the JavaScript code I am using:
let materials;
if (pointCloudData.colors !== undefined) {
geometry.colors = pointCloudData.colors.map(hexColor => new THREE.Color(hexColor));
// If each point in the cloud has its own color...
materials = new THREE.ShaderMaterial({
vertexColors: THREE.VertexColors,
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
transparent: true,
});
} else {
// Set a uniform color for the entire cloud
materials = new THREE.ShaderMaterial({
uniforms: {
unicolor: { value: pointCloudData.color },
},
vertexShader: document.getElementById('vertexshader').textContent,
fragmentShader: document.getElementById('fragmentshader').textContent,
transparent: true,
});
}
const pointCloud = new THREE.Points(geometry, materials);
In essence, I assign a uniform color to the mesh, unless individual point colors are defined, in which case I set the vertexColors for the geometry accordingly. When inspecting the values stored in geometry.colors, they appear to be correct RGB values within the range of [0,1].
Below is my Vertex Shader code:
attribute float size;
attribute float alpha;
varying float vAlpha;
varying vec3 vColor;
void main() {
vAlpha = alpha;
#ifdef USE_COLOR
vColor = color;
#endif
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_PointSize = size * ( 300.0 / -mvPosition.z );
gl_Position = projectionMatrix * mvPosition;
}
And here is my Fragment shader code:
uniform vec3 unicolor;
varying vec3 vColor;
varying float vAlpha;
void main() {
#ifdef USE_COLOR
gl_FragColor = vec4(vColor, vAlpha);
#else
gl_FragColor = vec4(unicolor, vAlpha);
#endif
}
Once again, I check if the vertexColor is defined and then pass it to the Fragment Shader for setting the individual point color.
For some unknown reason, all vertices appear white when trying to set the color per point. You can see a screenshot here, where the white pixels should actually be green or red. As someone who is not yet an advanced WebGL user, any help or guidance would be greatly appreciated. Could there be a mistake that I am overlooking?