cesium icon indicating copy to clipboard operation
cesium copied to clipboard

Z-Ordering of entity collection

Open tfili opened this issue 8 years ago • 47 comments

It would be nice to be able to change the render order of entities. Right now we have to tweak the eyeOffset which needs to change based on camera distance.

tfili avatar Jul 12 '16 15:07 tfili

This is probably one of the most frequently requested things on the forum. Also requested in #53

hpinkos avatar Dec 07 '16 15:12 hpinkos

CC #3647

pjcozzi avatar Jan 02 '17 21:01 pjcozzi

cc AnalyticalGraphicsInc/czml-writer#20

shunter avatar Jan 02 '17 21:01 shunter

Related: #4878 #4695

hpinkos avatar Jan 18 '17 17:01 hpinkos

Also reported here: https://groups.google.com/forum/?hl=en#!topic/cesium-dev/iyNHsibp2eI

hpinkos avatar Feb 08 '17 22:02 hpinkos

+1. I'd love to see this!

smills2929 avatar Feb 09 '17 01:02 smills2929

Also requested here: https://groups.google.com/forum/?hl=en#!topic/cesium-dev/p_TufXEFwTA

hpinkos avatar Mar 16 '17 14:03 hpinkos

Thinking about a possible implementation for billboards: https://groups.google.com/d/msg/cesium-dev/7CHDGRyJvwc/S55fUJ8XCAAJ

emackey avatar May 04 '17 21:05 emackey

push

Seems like this is still an issue. We have the same problem with labels drawn underneath polylines.

schitzN avatar Jan 09 '18 07:01 schitzN

Hi @schitzN, this hasn't been addressed yet. But stay tuned! We're starting work on this in the next month

hpinkos avatar Jan 09 '18 14:01 hpinkos

@hpinkos Will these changes also apply to billboard/lablel/polyline collections?

See on the forum: https://groups.google.com/forum/#!topic/cesium-dev/ywyFR5GSi_c

ggetz avatar May 02 '18 15:05 ggetz

@ggetz the changes I'm working on this round are specifically to address z-ordering in 3D, so I won't be making changes to billboards/labels because they are ordered spatially by their 3D position. We will have support for ordering polylines on the earth surface.

hpinkos avatar May 04 '18 14:05 hpinkos

@ggetz Thanks! @hpinkos changing the order of the primitives collections in 2D worked in the past (V 1.21) I don't know why it stopped working. Do you know when the issue will be resolved?

erezy avatar May 06 '18 07:05 erezy

Thanks @erezy, I didn't realize this was a regression. I've opened a separate issue so we can look into fixing it: #6569

hpinkos avatar May 07 '18 17:05 hpinkos

Will these changes also apply to rendering GeoJsonDataSource ?

eatjhuapl avatar Jun 14 '18 17:06 eatjhuapl

@eatapl we haven't hooked this up to GeoJson because I couldn't find anything in the GeoJSON spec that can be used to specify polygon ordering. Does GeoJSON have a property used for ordering that I missed? Thanks!

hpinkos avatar Jun 18 '18 14:06 hpinkos

Is there a workaround currently for at least drawing polylines below billboards? I'm implementing my own z-ordering where I can, but I don't know how to interact with the render pipeline for the parts of a single entity.

killroy42 avatar Sep 13 '18 18:09 killroy42

@killroy42 can you provide a short code example to reproduce the problem you're seeing?

hpinkos avatar Sep 14 '18 18:09 hpinkos

Well, just create an entity with a billboard image and a path. The project I'm working on: http://rolexmiddlesearace.com/trackerpt/

If you tilt the camera back and forth you see that the path switches places with the billboard icons.

killroy42 avatar Sep 14 '18 19:09 killroy42

@killroy42 I see what you're talking about. It's tricky to order billboards in 3D because you generally want them to order spatially (ie a billboard that is closer to the camera will draw on top of a polyline that is drawn in the distance). This is part of the reason why we have not added a z-index property to billboards.

You can try setting a negative z value to eyeOffset: billboard.eyeOffset = new Cesium.Cartesian3( 0, 0, -100) This makes the billboard draw as if it is closer to the camera, so it should push it above the polylines.

hpinkos avatar Sep 14 '18 19:09 hpinkos

Thanks, I'll try that. Is there an easy method to have an icon align horizontally with the ground, rather then vertically with the plane of the camera? As you can see, I really would like flat icons on the ground, than standing upright in the air.

killroy42 avatar Sep 14 '18 22:09 killroy42

@killroy42 no sorry, billboards aren't really designed to work that way. You could try replacing the billboards with a rectangle using an image for the material. This might have slightly poorer performance though depending on how many you have in the scene at a time.

hpinkos avatar Sep 18 '18 14:09 hpinkos

I've got entities that I needed to disable depth testing (set disableDepthTestDistance to Number.POSITIVE_INFINITY), but I also have labels that are going on top of these entities, and the shape entities are getting rendered on top of the labels always. Is there any way to make labels always render last? Or is this still a WIP? Attached an example image. z_index_isue

Zpeugh avatar Feb 15 '19 15:02 Zpeugh

@Zpeugh It's hard to tell exactly what's going on in the picture you posted, so I'm not quite sure why the label is rendering behind the geometry you have there. I would recommend applying an eyeOffset: new Cesium.Cartesian3(0, 0, <some negative value>) to your labels. This makes the label draw as if it's closer to the camera. All billboards and labels layer spatially, so things closer to the camera layer in front of things further away.

hpinkos avatar Feb 15 '19 15:02 hpinkos

I can explain the picture a bit more. The background is a B3DM texture mesh. The teal lines are all polyline entities with depth testing disabled. The labels are created with these parameters: { position: cartesianPoint, showBackground: false, font: (ANNOTATION_FONT_SIZE * scaleFactor) + "px 'Source Sans Pro', sans-serif", scale: 1.0 / scaleFactor, style: Cesium.LabelStyle.FILL_AND_OUTLINE, fillColor: Cesium.Color.WHITE, outlineColor: new Cesium.Color(0, 0, 0, 1), outlineWidth: 3.0 * scaleFactor, horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: verticalOrigin, disableDepthTestDistance: Number.POSITIVE_INFINITY, fontSize: ANNOTATION_FONT_SIZE }

I have already tried adding eyeOffset: new Cesium.Cartesian3(0, 0, -100000) and it only makes the labels invisible until you scroll well away from the surface of the globe. And even then, the polyline entities are still rendered on top of the label.

Zpeugh avatar Feb 15 '19 16:02 Zpeugh

The teal lines are all polyline entities with depth testing disabled

This is what's causing the problem. If depth testing is disabled, it's completely ambiguous what is "closer" to the camera and should be rendered on top.

hpinkos avatar Feb 15 '19 16:02 hpinkos

Okay that makes sense, but I need to have my shape entities always show through the B3DM's underneath or else I get something like this. (The label does show on top when the polyline entity depth testing is turned back on, as expected). Any ideas on how to get the proper rendering z-indexing in this scenario? Or am I SOL? depth_test_enabled

Zpeugh avatar Feb 15 '19 16:02 Zpeugh

@Zpeugh you might be able to do something with the classification options. See https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=Polylines%20on%203D%20Tiles.html&label=3D%20Tiles

hpinkos avatar Feb 15 '19 16:02 hpinkos

Alright thanks for your time. I will poke around with classification options. I'll post my answer here if I figure out a solution for my problem.

Zpeugh avatar Feb 15 '19 16:02 Zpeugh

+1 for me. Same issue with polylines rendering over labels, polylines left untouched, labels having disableDepthTestDistance: Number.POSITIVE_INFINITY.

When setting polyline material and depthFailMaterial to be different, I discovered that parts of polyline covering the labels are rendered using depthFailMaterial event through the surrounding polyline is rendered with material. This would suggest that disableDepthTestDistance works for depth test itself but the result is not honored in this case.

ladislavhorky avatar Mar 29 '19 19:03 ladislavhorky

@ladislavhorky Could you put together a Sandcastle example to reproduce that?

hpinkos avatar Mar 29 '19 19:03 hpinkos

@hpinkos here it is. You only need to turn it a bit to get some label in the town square to cross transparent polyline.

ladislavhorky avatar Mar 29 '19 19:03 ladislavhorky

@ladislavhorky The lines are drawing on top of the labels because you set a depthFailMaterial. That is working as designed. The depthFailMaterial colors the line when it fails the depth test, so it will always draw on top of the label when the label is in front of the line spatially. The lines look like they are rendering below the labels if I remove depthFailMaterial

hpinkos avatar Mar 29 '19 19:03 hpinkos

@hpinkos I see, that makes sense. But then, is there some way to make the polylines visible through the terrain/3D tiles without setting depthFailMaterial and thus interfering with labels? Like maybe splitting labels and lines into separate datasources? The intended behavior is to make both labels and lines visible through the mesh with correct z-ordering much like in Zpeugh's example.

My best workaround so far is to use distanceDisplayCondition for labels to minimize the crosses and some transparency for polylines to make the crosses less visible.

ladislavhorky avatar Mar 29 '19 22:03 ladislavhorky

I'm sorry @ladislavhorky, I don't have any workaround at this time

hpinkos avatar Apr 01 '19 15:04 hpinkos

@hpinkos Thanks for your time anyway. I'll do with the transparency for now.

ladislavhorky avatar Apr 01 '19 15:04 ladislavhorky

Was there ever a resolution found for this issue? I am getting different behavior depending on the alpha channel of polygon material as well. If the material has any transparency, the labels appear behind. If alpha is 1.0, label appears in front, but always behind polylines (GeoJsonDataSource stroke). See image on the left, green color has 1.0 alpha while other colors have less.

Also, in an unrelated issue, the individual letters of label text appear wonky/not-aligned if the text is smaller than about 17px (right image)

image

Maarondesigns avatar Oct 22 '19 14:10 Maarondesigns

@hpinkos , what is the roadmap regard this feature?

it is extremely needed, and it seems there is no workaround at the moment?

jony89 avatar Dec 05 '19 09:12 jony89

@Maarondesigns thanks for pointing these out. These are potentially separate issues. The small font issue seems to have been working as of CesiumJS 1.62. I opened an issue for this here: https://github.com/AnalyticalGraphicsInc/cesium/issues/8474

For the outline ordering issue, I'm unable to reproduce this. Here's the Sandcastle I tried. You can toggle the material alpha = 1 vs alpha = 0.8 with the buttons. It seems that the stroke is always on top regardless. Are you able to share a Sandcastle example that reproduces it?

@jony89 there may be a workaround depending on what exactly you're trying to achieve. Feel free to open a Cesium forum discussion thread describing your use case.

OmarShehata avatar Dec 18 '19 15:12 OmarShehata

I've circled back to this issue on a separate project. It seems like polylines render randomly above or below polygons and corridors with alpha less than 1.0. I am creating everything using the Primitive API. The project is my own version of the game RISK if you're interested: github

//country fill
let polygonPrimitive = new Cesium.Primitive({
        show: dontShow ? false : true,
        releaseGeometryInstances: false,
        geometryInstances: new Cesium.GeometryInstance({
          id: id + "_polygon",
          geometry: Cesium.PolygonGeometry.createGeometry(
            new Cesium.PolygonGeometry({
              polygonHierarchy: cartesian,
              height
            })
          )
        }),
        appearance: new Cesium.MaterialAppearance({
          material: new Cesium.Material.fromType("Color", {
            color: new Cesium.Color(
              fillColor[0],
              fillColor[1],
              fillColor[2],
              fillOpacity
            )
          })
        }),
        asynchronous: false
      });
//country border
let corridorPrimitive = new Cesium.Primitive({
          show: dontShow ? false : true,
          releaseGeometryInstances: false,
          geometryInstances: new Cesium.GeometryInstance({
            id: cid,
            geometry: Cesium.CorridorGeometry.createGeometry(
              new Cesium.CorridorGeometry({
                positions: p,
                width: 8000,
                extrudedHeight: height + 10000
              })
            )
          }),
          appearance: new Cesium.MaterialAppearance({
            material: new Cesium.Material.fromType("Color", {
              color: new Cesium.Color(
                strokeColor[0],
                strokeColor[1],
                strokeColor[2],
                strokeOpacity
              )
            })
          }),
          asynchronous: false
        });
//path
let path = new Cesium.Primitive({
      releaseGeometryInstances: false,
      geometryInstances: new Cesium.GeometryInstance({
        id: id?id:"path",
        geometry: Cesium.PolylineGeometry.createGeometry(
          new Cesium.PolylineGeometry({
            positions,
            width
          })
        )
      }),
      appearance: new Cesium.PolylineMaterialAppearance({
        material: new Cesium.Material.fromType("PolylineDash", {
          color
        })
      }),
      asynchronous: false
    });

Changing the camera angle makes the dashed polyline pop in front of or behind the countries. Same behavior when corridor alpha<1.0. In image below corridor alpha is 1.0. image

Maarondesigns avatar Jan 11 '20 16:01 Maarondesigns

@Maarondesigns thanks for pointing these out. These are potentially separate issues. The small font issue seems to have been working as of CesiumJS 1.62. I opened an issue for this here: #8474

For the outline ordering issue, I'm unable to reproduce this. Here's the Sandcastle I tried. You can toggle the material alpha = 1 vs alpha = 0.8 with the buttons. It seems that the stroke is always on top regardless. Are you able to share a Sandcastle example that reproduces it?

@jony89 there may be a workaround depending on what exactly you're trying to achieve. Feel free to open a Cesium forum discussion thread describing your use case.

I was able to reproduce in your sandcastle...This issue occurs when the polygon has extrudedHeight and then eyeOffset is used on the label to appear in front of it. SandCastle

It also occurs when you use a billboard with image: [ html canvas ], which I started doing to fix the alignment issue of the letters.

Maarondesigns avatar Mar 04 '20 20:03 Maarondesigns

Another mention of this: https://community.cesium.com/t/on-2d-mode-polylines-are-always-on-top-of-labels/11451

dzungpng avatar Nov 04 '20 19:11 dzungpng

Is there still no good fix for this? Even setting an eyeOffset z value is a subpar solution. I am having such trouble getting my label entities to appear over my arcs. The arcs vary in height, and some of them get very high.

I should say - the labels are for other entities on the map and not related to the arcs at all.

Can there not be a flag to treat these label entities as such so that they are just rendered above everything else, regardless of height?

aldenpoole avatar Jul 29 '22 16:07 aldenpoole