Point Cloud Opacity Issue

Hello, I’m facing the issue with point cloud 3DTileset opacity manipulation.
Somehow when changing the color of point cloud via style, the point cloud displays black.

Here is Sandcastle representing the issue.

Appreciate any help.

Hi there,

A couple of things here. First off is getting the properties named correctly, and in the right place, so it’s not {COLOR.RED}, but {COLOR.r}. There might be some internal abbreviations and conversions that only looks for the first letter in case-neutral ways, but the internal model uses r,g,b,a,x,y,z,w notation, so just using those directly for safe measure.

Next up is bit more complex, and I wanted to know this myself so I dug deep into the code for this one. All shading expressions are converted to GLSL (C-like language), and most of CesiumJS is about doing this conversion for you. The internal vector (vec4) that stores colors and the RBGA values is a 32-bit float, and there’s an automatic conversion of those values when they’re not numbers (probably for some nefarious CSS style conversions) when Cesium generates a shader for it. This is what causes this weirdness, as the {$COLOR} is a special property that’s not converted automatically. Because we’re dealing with already converted values, you get converted values (where, for example, the RED channel has been converted from some number to Byte [ie. 0-255]) we get a double conversion as the automatic conversion will divide the value again, so imagine all your channels (RBG) are all converted from some number to small number to even smaller number (and indistinguishable from 0, or black).

Right. So, here’s the solution; assume the automatic conversion will divide by 255, so you times it by 255 before you push it in, like so;

"color": "rgba ( ${COLOR.r}*255, ${COLOR.g}*255, ${COLOR.b}*255, "+ opacity +")"

There probably is a use-case / feature request for something like a rgba_static() function that doesn’t do the automatic [channel] / 255 conversion, for those times you know the values are right. For example, the hsla() function does not do this, so if you just want to try out the oddness of it all, you can do;

"color": "hsla ( ${COLOR.r}, ${COLOR.g}, ${COLOR.b}, "+ opacity +")"

Anyway, it’s that automatic conversion of RBG values that does it; the parser will do a [variable] / 255.0 if it’s not an actual number. I don’t understand why it does this, btw, and I’m tempted to call it a bug, although it probably makes perfect sense in other use cases.



Hello, Alex,

Thank you so much for this detailed description, now everything is quite clear for me. Hope this answer will also help other folks around the forum.



1 Like