Is PLY vertexColor mapping broken? can't map PLY color data

Loading and tested multiple PLY files that display point vertex data when using PointsMaterial.

Mapping vertexColor to ShaderMaterial displays colors at incorrect positions.

    for (var i = 0; i < total; i++) {
      pos[i * 3] = activeGeometry.attributes.position.array[i * 3];
      pos[i * 3 + 1] = activeGeometry.attributes.position.array[i * 3 + 1];
      pos[i * 3 + 2] = activeGeometry.attributes.position.array[i * 3 + 2];

      // color data
      colors[i * 3] = activeGeometry.attributes.color.array[i * 3];
      colors[i * 3 + 1] = activeGeometry.attributes.color.array[i * 3 + 1];
      colors[i * 3 + 2] = activeGeometry.attributes.color.array[i * 3 + 2];
    
     
    }

That is the part that maps the vertex positions with no problem,

Color array has the same count and checks out, but something is off.

I sincerely appreciate your time reading my post, and hope to be graced with your Threejs wisdom :pray::pray::pray:

The post is a bit unclear… but lots of us here have worked with BufferGeometry + Particle systems, and doing color per particle isn’t very difficult. Is there a fiddle or codepen of something you need help with?

Thanks for the reply and the enthusiasm is very much appreciated.

The post is very specific to using ShaderMaterial with vertexColors. Waiting to hear from the the guys I’ve mentioned.

Thanks.

lol ok. good luck. :smiley:
https://vectorslave.com/gpuparticles/noise.html

the ply files I am using are not the problem as the colors are displayed when using Points and PointsMaterial. ( and tested in the Theejs online editor)

    var total = activeGeometry.attributes.position.count;
    var size = parseInt(Math.sqrt(total) + 0.5);
    var positions = new Float32Array(size * size * 3);
    var colors = new Float32Array(size * size * 3);

    for (var i = 0; i < total; i++) {
      positions[i * 3] = activeGeometry.attributes.position.array[i * 3];
      positions[i * 3 + 1] = activeGeometry.attributes.position.array[i * 3 + 1];
      positions[i * 3 + 2] = activeGeometry.attributes.position.array[i * 3 + 2];

      // color data
      colors[i * 3] = activeGeometry.attributes.color.array[i * 3];
      colors[i * 3 + 1] = activeGeometry.attributes.color.array[i * 3 + 1];
      colors[i * 3 + 2] = activeGeometry.attributes.color.array[i * 3 + 2];
    }
    fbo.particles.geometry.setAttribute(
      "color",
      new THREE.BufferAttribute(colors, 3)
    );

when adding color data in a colors array and setting the color attribute in the buffered Geometry I am seeing colors. But the colors don’t match correctly. I’ll upload some some shots of the disparity.

@Mugen87 Have you tried this? PointsMaterial won’t cut it as I need the GPGPU performance of ShaderMaterial

Your code there can be replaced with:

let positions = activeGeometry.attributes.position.array.slice(0);
let colors = activeGeometry.attributes.color.array.slice(0);

Not sure why you have such complex logic for copying those arrays?
Perhaps I am missing something…
Anyway… please post a reproduction of your issue in a codepen or jsfiddle.
You are not providing enough information to solve your problem.
When you say “the colors don’t match correctly.” that is not helpful. Please explain how they “don’t match”, and provide working code that reproduces the issue. Don’t just cut and paste a few lines here and there that you think may be related.

Those arrays are needed in that manner…

If you need more details on what I am doing and how

Maxime has a written a great article on it, but it seems nobody has successfully passed the vertexColor data along.

Generating you own colors for the shader is easier and that’s not the problem I am trying to solve.

in one line…

I am unable to map vertex color data from a PLY file into the ShaderMaterial + fragment shader.

Everything that google will return I have already tried, but nobody attempted matching color… Just vertex positions for morph transistions as per Maxime’s blog.

Thanks.

To color a particle…

you set up the attribute in the vertex shader…

attribute vec3 color;

a varying to send it to the fragment shader:

varying vec3 vColor;

in the vertex shader:

vColor = color;

then in the fragment shader:

varying vec3 vColor;

....

at the end of the fragment shader:

gl_FragColor.rgb *= vColor;

If you want to see how PointsMaterial handles color, you can read the source code here:

https://ycw.github.io/three-shaderlib-skim/dist/#/latest/points/vertex

https://ycw.github.io/three-shaderlib-skim/dist/#/latest/points/fragment

thats already done, and am familiar with them.
I am not using PointMatrial. PointMaterial has no problems.

I’ve pinpointed the issue to the size of the uv used which causes an issue in mapping the points correctly.
the uv used to store and calculate positions.

But, yes the correct color is loaded but just not mapped correctly.
remember this process uses a uv DataTexture to animate the particles in a “simulation” pass before the “render” pass.

@mrdoob when I change the size of the uv texture I notice the colors shifting to the right.

correct points

activeGeometry.attributes.position.count = 2970
uv texture size at 55*55 = 3025 ( enough to store all vertex data )
points incorrectly mapped.

increasing uv texture size to 64*64, same incorrect mapping but shifted to the right

@prisoner849 thoughts?

1 Like

Ahh great. Glad you figured it out. :slight_smile:

Not figured out the solution, just isolated the area.
its’s potentially a gl_fragcoord issue.

bruh just post some code in a code pen and we will fix you.
it doesn’t have to be like this.

1 Like