Style property POSITION_ABSOLUTE of point cloud tileset causes ERROR

Hello Team,
When calling a function asynchronously that changes the style of the point cloud tileset, but not calling just after the tileset was initialized, it causes an error which is described in the image attached when ${POSITION_ABSOLUTE} property is called.

Why can I not access to ${POSITION_ABSOLUTE} anymore?

This is an animated GIF of two versions of the code:

Cesium Style String

Yes, it’s subtle: You used " (double quotes) inside the string. This means that the value of pos there is
vec3(" + XYZ[0] + "," + XYZ[1] + "," + XYZ[2] + ")

You have to use ' (single quotes) in the string, as in
pos: 'vec3(' + XYZ[0] + ',' + XYZ[1] + ',' + XYZ[2] + ')',
so that the resulting string actually is
vec3(4401688.591363471,225003.70009621087,4595441.614419247)

But…

… the section about Defining Variables in the specifications says

A define expression may not reference other defines

But you could just define the “position” outside of the style (because it only depends on the click position anyhow) - for example, like this:

function applyStyle(ts, cartesian) {
  const XYZ = [cartesian.x, cartesian.y, cartesian.z];
  const posString = 'vec3(' + XYZ[0] + ',' + XYZ[1] + ',' + XYZ[2] + ')';
  // DEBUG OUTPUT:
  console.log(XYZ);
  console.log("The posString is "+posString);
  ts.style = new Cesium.Cesium3DTileStyle({
    defines : {
      distance : 'clamp(distance(${POSITION_ABSOLUTE}, ' + posString + ') / 25.0, 0.0, 1.0)'
    },
    show: "clamp(${distance}, 0.0, 0.3) < 0.3",
    color : 'mix(color("yellow"), color("red"), ${distance})'
  });
}

The sandcastle:

(The interaction is still a bit glitchy, but … the shader error should be resolved now…)

1 Like

This is great @Marco13
You have helped me in other threads as well. I appreciate the support from you as always.

@Marco13
Also, I’m not fully understanding the defined expression yet.
As far as I understand, ${POSITION_ABSOLUTE} is a per-point property that I can use from any style expression and anytime.
Therefore, I thought it shouldn’t give me an error by referring to it.
Please correct me if I am wrong.

The error was not caused by the ${POSITION_ABSOLUTE}.

The error was caused by two other things:

  • The "pos" that you added to the defines had a wrong format. It contained the string
    vec3(" + XYZ[0] + "," + XYZ[1] + "," + XYZ[2] + ")
    and not the (intended) string
    vec3(4401688.591363471,225003.70009621087,4595441.614419247)
  • Even with the right string: One element of the defines can not refer to another element of the defines. So your "distance" cannot refer to the "pos".

A hint is given in the error message: It says

ERROR: 0:107: ‘distance’ : no matching overloaded function found

and prints a loooong output of the shaders. This output contains…

vec4 getColorFromStyle(ProcessedAttributes attributes, Metadata metadata, float tiles3d_tileset_time)
{
    return mix(vec4(vec3(1.0, 1.0, 0.0), 1.0), vec4(vec3(1.0, 0.0, 0.0), 1.0), clamp((distance(v_positionWC, czm_infinity) / 25.0), 0.0, 1.0));
}
//===========================================================================================================^^^^^^^^^^^^ this....

This czm_infinity is inserted there because it could not figure out what the second parameter of the distance function should be.

Of course, it would be nicer if it could have an explicit error message like

ERROR: The ‘distance’ refers to the ‘pos’, but definitions may not refer to each other

or

ERROR: The value for the pos definition could not be parsed

but creating such detailed messages can be difficult…

1 Like

Understood. I need to be careful and get used to more on concatenating the strings to pass to the style expression.
I was also almost kind of ignoring the long error message since it was a long and different language but I should have read and tried to get some hint at least.

Thank you very much for your detailed answer again @Marco13