ElevationRamp inside the polygon

My issue:
Create a polygon on the terrain - color the area inside the polygon like ElevationRamp for a globe or like a height-depending-heatmaps.

What I know for now:

  1. There is no ready solution out-of-the-box: Question: elevationramp-to-polyline
  2. It is possible: Looks like appropriate example
  3. I’ve already read about fabric and custom appearances
  4. I’m studying a basic of shaders.
  5. I’ve investigated this shaders example.

What I don’t know for now:
How to use my new knowledges on the practice (I’m new in the Cesium and some things are not very clear for me yet, but I’m working on it :slight_smile: ).

So, my questions are:

  1. Is my direction (to use fabric / appearance / shaders) is right?
    If no:
  2. Could you advice me something other that can help?
    If yes:
  3. Should I write everything (shaders, material, etc.) from scratch?
    or
  4. Can I combine something ready (ex., something from GlobeFS.glsl or something) with new fabric or appearance?
  5. Does all kinds of primitives and entities can be used in this case?
  6. Could you share any appropriate examples?

Thanks in advance. I will be very appreciate for any help, explanations, conversation.

1 Like

Hi!

Great to hear that you are taking steps to learn the Cesium platform.

You are right, you would need to create a custom shader to use for the MaterialProperty of the polygon.

The easiest one to use is probably a rectangle entity with a default clamped to ground property, as in this example (please select “Draw Rectangle” from the dropdown menu). The code starts on line 166.

We currently don’t have an example for this specific use case.

What kind of project are you working on? What is the motivation behind drawing a customized polygon on the terrain (instead of using globe material like in the elevation ramp example)?

Hi!

Thanks a lot for your answer!

I.

Unfortunately, there is no link in your answer. But if I found correctly, you means this one, right?
So,

  1. if I need a polygon, but it do not clamped to the ground by default, is it possible to make it clamped?
  2. Is it possible to use custom shaders at the entity? (it seemed to me, when I read about this things, that it possible to use custom appearance and, hence, custom shaders, at primitives only, but I can be wrong or confuse something).

II.

  1. Do you have any examples not for this specific case, but maybe for the case of custom shaders for the entity?

III.

The project is the construction data analytics platform (based on drone data and images).
One of the feature - a user create the polygon to estimate an area, volume, etc. of some specific object. And for some of cases we need to colorize a space inside the polygon depends on the height of a terrain.
We already use globe elevation ramp for other case, but here we need such visualization exactly inside the users’ polygon.

Yes it is possible. You can use PolygonGraphics with heightReference set to CLAMP_TO_GROUND. You can also use GroundPrimitive, which automatically drape over terrain.

My apologies, that is the correct link.

It is possible as noted in this discussion.

I have previously made an example for primitives here. I don’t recall seeing an example for entities.

Thank you for sharing your use case. We look forward to seeing the results and assisting you further with the project.

Hi! I came back to this task and have a new questions:

I’m trying to set custom material source for GroundPrimitive (please, see my Ground primitive example)
To solve my task I need to use height (like Globe ElevationRampMaterial), but as I see, materialInput.height is available for Globe only and I cannot use it for ground primitive.

Is it possible to add values of terrain height inside the polygon to the shader? Via uniforms, for example, or some other way?

Hi Olga, I have the exact same requirement, were you able to figure out any solution?

Edit: I’ve created another ticket with my findings, leaving it here to link both tickets - Color polygon based on ElevationRamp

Hi, Atul!
Thanks for your link.
I’m digging in this direction - if we cannot get height inside shader, let’s set it outside and use via uniforms.
a). As mentioned here, it is possible to generate texture using undocumented API and set it to the material uniforms.
b). Texture data should be rectangle, so we need to get bounding box for our polygon.
c). To get height data we can use sampleTerrainMostDetailed.
d). But, as we need to know height values not in the vertexes only, but inside the polygon too, we need to generate a set of points with small step between each other. We may do it using pointGrid for the polygon bbox via Turf library.

I still didn’t get final results, but this direction seems promising to me.

1 Like

Hi Olga, thanks for the reply. The link in point (c) is not working, can you please add it?

Sure. Updated.

I’ve been trying to understand the heatmap example, I couldn’t figure out how to texture map is associated with the texture coordinate (st). If you look at the fragment shader code in the example, it uses the materialInput.st value to pick the colour from the texture. But in our case, we need to pick colors based on elevation, right?

The main point I took there - how to set custom texture to the shader.
As we need to pick colors based on elevation and we cannot get elevation inside the shader, we have to get elevations outside. So, for our case we can create a texture based on elevation data and after that picked the colors from it.

Consider this image as a texture -
image

Here I can easily visualize how it’ll overlap/map on the polygon and we can simply pick the colour using st. But in our case, it’s a 1D array of colours, I can’t visualize how texture maps with the polygon. How st value is going to map with the correct texel in the texture since colour is supposed to be picked based on the elevation. So what is the relation between st and elevation data?

I’m referring this for understanding how texture mapping works - http://web.cse.ohio-state.edu/~parent.1/classes/581/Lectures/13.Texture.pdf

1D array of colors is a texture data. And we use it for creation a 2D texture as arrayBufferView.

texture = new Cesium.Texture({
      context: context,
      pixelFormat: Cesium.PixelFormat.RGBA,
      pixelDatatype: Cesium.PixelDatatype.UNSIGNED_BYTE,
      source: {
        width: gridWidth,
        height: gridHeight,
        arrayBufferView: textureData,
      },
      sampler: new Cesium.Sampler({
        wrapS: Cesium.TextureWrap.CLAMP_TO_EDGE,
        wrapT: Cesium.TextureWrap.CLAMP_TO_EDGE,
        minificationFilter: Cesium.TextureMinificationFilter.LINEAR,
        magnificationFilter: Cesium.TextureMagnificationFilter.LINEAR,
      }),
      flipY: false,
    });

Note the source - here we set width and height as a count of points.

For example, for width = 3 and height = 2:

1 Like

Here is described, how to collect points inside the polygon via turf library.

1 Like

Test example, how to visualize elevation ramp inside the polygon via shader and some undocumented behavior with private renderer API like texture and sampler.

2 Likes

This is super helpful Olga, thanks a ton!. You should definitely get this sandcastle example merged, much needed.

@Olga_Aptekar

Thank you for chiming in here! We really appreciate your input and your ideas :grin: :rocket:

-Sam

1 Like