Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Labels/billboards on terrain and depthTestAgainstTerrain #2694

Closed
pjcozzi opened this issue May 7, 2015 · 32 comments · Fixed by #6621
Closed

Labels/billboards on terrain and depthTestAgainstTerrain #2694

pjcozzi opened this issue May 7, 2015 · 32 comments · Fixed by #6621

Comments

@pjcozzi
Copy link
Contributor

pjcozzi commented May 7, 2015

When labels/billboards are clamped to terrain, they require depthTestAgainstTerrain to be false so they do not sink into terrain. However, this allows 3D models and extruded geometries, for example, to come through terrain.

@bagnell and I have brainstormed a few ideas like using an extra depth buffer or stenciling. We're hoping for something simpler though.

@mramato
Copy link
Contributor

mramato commented Oct 14, 2015

Was this addressed by the heightReference stuff? Or is this still an issue?

@hpinkos
Copy link
Contributor

hpinkos commented Sep 9, 2016

@pjcozzi @bagnell is this still a problem?

@bagnell
Copy link
Contributor

bagnell commented Sep 9, 2016

Yes, it's still a problem. For example, if you have a label on the side of a mountain. Its possible to rotate so the part of the label fails the depth test with the mountain.

@mramato
Copy link
Contributor

mramato commented Sep 9, 2016

Here's exactly what @bagnell is talking about. Hopefully something we can address sooner rather than later. (along with other label/depth improvements).

labels

@hpinkos
Copy link
Contributor

hpinkos commented Oct 5, 2016

@pjcozzi
Copy link
Contributor Author

pjcozzi commented Jan 2, 2017

CC #2160

@hpinkos
Copy link
Contributor

hpinkos commented Feb 15, 2017

Also came up in this forum post: https://groups.google.com/d/msg/cesium-dev/Z68H4SHnAAY/MzQTuxkQDAAJ

@juburr
Copy link
Contributor

juburr commented Jun 27, 2017

@pjcozzi @bagnell We would love to see this one get addressed. Do you have a time estimate on it? As we begin to integrate 3D models into our application, this issue is causing some unintended side effects.

@pjcozzi
Copy link
Contributor Author

pjcozzi commented Jun 27, 2017

@jburr-nc no time frame for this exact fix, but check out Label.disableDepthTestDistance, which can be used to fix this.

@juburr
Copy link
Contributor

juburr commented Jun 27, 2017

@pjcozzi Thanks for the tip! That worked!

@pjcozzi
Copy link
Contributor Author

pjcozzi commented Aug 21, 2017

Discussed a bit offline with @bagnell today. @bagnell said he already tried this, but I still think we should re-investigate something like checking the center and corner points of a billboard/label against the depth buffer in the vertex shader, and then "passing depth" (e.g., not pushing in front of the near plane to clip it) if all (or maybe n) points pass. Probably enable depth writes but not reads in the render state.

@juburr
Copy link
Contributor

juburr commented Sep 1, 2017

Unsure if this is related or not, but is anyone else experiencing 3D dome shapes distorting KML data sources?

@thw0rted
Copy link
Contributor

I'm currently combining disableDepthTestDistance with translucencyByDistance to make labels visible through terrain, but hidden at a certain distance from the viewer. This mitigates the issue where entities show through the earth (!) in 3D mode when disableDepthTestDistance is set to Infinity. I'm still hoping for a solution where billboards don't get clipped by terrain, but "whole entities" are hidden when they're behind something (like, say, the planet).

@emackey
Copy link
Contributor

emackey commented Oct 24, 2017

I like the "whole entity" idea. I've encountered more than one project where they want an all-or-nothing test for visibility of the entity (point, billboard, and label, together). If the entity's single location is exposed to the camera, then the point+billboard+label graphics should be visible in their entirety, unfettered by depth-buffering. But if the entity is obscured, even just hidden behind a small hill, then the point+billboard+label graphics are turned off completely. At no time is a partial label or partial marker symbol (billboard) ever shown to the user, nor a marker without a label or vice-versa. Essentially, the 2D elements don't need to participate in the 3D scene at all, beyond yes-or-no knowledge of whether the object they represent is visible within the scene, and its screen-space location.

Points, billboards, and labels in such a system could even be moved to a separate render pass where FXAA was not applied to them, which would be an added win.

@thw0rted
Copy link
Contributor

I had two thoughts about this. Being able to designate entities as all-or-nothing, at the top level, would be a helpful feature, for the reasons you've laid out. But I also think that certain 2D graphical elements should be excluded from individual depth testing, as you've described, either behind an option or as a global rendering engine change. I can't think of a reason anybody would ever want a billboard or label to be partially obscured by terrain (though of course I wouldn't say it's impossible), so at the very least the default behavior should be to avoid doing this.

@emackey
Copy link
Contributor

emackey commented Oct 26, 2017

Yes, every time I think about this, I can't imagine a valid reason why a user would want per-fragment visibility testing of 2D elements (points/billboards/labels). They either want all fragments of all the available 2D elements for a given entity, or none.

@pjcozzi
Copy link
Contributor Author

pjcozzi commented Oct 26, 2017

@emackey @thw0rted I agree - feel free to hack up a prototype. This could even become a bit easier with the upcoming post-processing framework, #5808, providing access to the terrain/environment depth texture.

CC @bagnell

@ggetz
Copy link
Contributor

ggetz commented Dec 4, 2017

Came up again on the forum: https://groups.google.com/forum/#!topic/cesium-dev/73iP8rzzGuU

@ggetz
Copy link
Contributor

ggetz commented Jan 12, 2018

Came up again on the forum: https://groups.google.com/forum/#!topic/cesium-dev/kQiuFbnTpSQ

@cesium-concierge
Copy link

Congratulations on closing the issue! I found these Cesium forum links in the comments above:

https://groups.google.com/d/msg/cesium-dev/mm2Xipqbp-g/AoSvaHcUAQAJ
https://groups.google.com/d/msg/cesium-dev/Z68H4SHnAAY/MzQTuxkQDAAJ
https://groups.google.com/forum/#!topic/cesium-dev/73iP8rzzGuU
https://groups.google.com/forum/#!topic/cesium-dev/kQiuFbnTpSQ

If this issue affects any of these threads, please post a comment like the following:

The issue at #2694 has just been closed and may resolve your issue. Look for the change in the next stable release of Cesium or get it now in the master branch on GitHub https://github.com/AnalyticalGraphicsInc/cesium.


I am a bot who helps you make Cesium awesome! Contributions to my configuration are welcome.

🌍 🌎 🌏

@gooin
Copy link

gooin commented Aug 9, 2018

Hello there:
Any news with this issue?
I'm trying to add billboards on terrain, when I set camera at a certain angle, it's completely invisible.
billboards on terrain
my code:

var info={
 country:"foo",
 region:"bar",
 longitude:123,
 latitude:12
}
 billboard = viewer.entities.add(new Cesium.Entity({
                            name: info.country + " " + info.region,
                            position: Cesium.Cartesian3.fromDegrees(info.longitude, info.latitude),
                            billboard: {
                                image: info.url,
                                width: 40,
                                height: 40,
                                verticalOrigin: Cesium.VerticalOrigin.BOTTOM
                            }
                        }));

@thw0rted
Copy link
Contributor

thw0rted commented Aug 9, 2018

Your billboard is not clamped to the ground. Add heightReference: Cesium.HeightReference.CLAMP_TO_GROUND and see if it behaves the way you want.

@gooin
Copy link

gooin commented Aug 9, 2018

@thw0rted Awesome!Thank you.

@munna
Copy link

munna commented Sep 28, 2018

I am getting error normalized result is not a number while set heightReference: Cesium.HeightReference.CLAMP_TO_GROUND in my code and globe map become black.

Here are my complete code

entity.polygon.material = Cesium.Color.CYAN.withAlpha(0.5); entity.polygon.outlineColor=Cesium.Color.BLACK; entity.polygon.extrudedHeight =entity.properties.Hght; entity.polygon.extrudedHeightReference=Cesium.HeightReference.CLAMP_TO_GROUND;

@thw0rted
Copy link
Contributor

Can you dump your entity definition and post it here? Like, console.log(entity) then copy/paste or make a screenshot. Alternately, you could log the values being used in the entity definition separately. For example, is entity.properties.Hght really the value you want for extrudedHeight?

@munna
Copy link

munna commented Sep 28, 2018

Thanks for reply @thw0rted .
consloe.log is not visible properly as it is big object. Please check this screenshot
error

@thw0rted
Copy link
Contributor

I haven't tried setting this up after the fact, have you tried making an entity with constructor options for the polygon definition, rather than making the entity then altering its polygon on the fly?

@hpinkos
Copy link
Contributor

hpinkos commented Sep 28, 2018

@munna can you please put together a Sandcastle example to reproduce the issue? https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/

@munna
Copy link

munna commented Sep 29, 2018

@hpinkos I have created here Sandcastle URL to reproduce but i am not getting same issue. but got another two issue.

  1. When I apply entity.polygon.extrudedHeightReference=Cesium.HeightReference.CLAMP_TO_GROUND;, 3D building become 2D.
  2. when i enable 2-8 line code. geometry goes underground and become invisible.
    var scene =viewer.scene; scene.terrainProvider = Cesium.createWorldTerrain({requestWaterMask : true, requestVertexNormals : true }); scene.imageryLayers.addImageryProvider( new Cesium.IonImageryProvider({ assetId: 2 }) ); scene.globe.depthTestAgainstTerrain = true;

@18616594872
Copy link

hello, I want to ask if the problem of pickPositionSupported is not supported under IE.

@GatorScott
Copy link

I think you want to set the polygon's height reference to be CLAMP_TO_GROUND and perPositionHeight to false, and set the extrusion's height reference to RELATIVE_TO_GROUND. Here's your example with those changes.

//var scene =viewer.scene;
//scene.terrainProvider = Cesium.createWorldTerrain({requestWaterMask : true,
//          requestVertexNormals : true });
//scene.imageryLayers.addImageryProvider(
//          new Cesium.IonImageryProvider({ assetId: 2 })
//        );
//scene.globe.depthTestAgainstTerrain = true;
var promise = Cesium.GeoJsonDataSource.load( "https://raw.githubusercontent.com/munna/react-gis/master/building.geojson",
              {clampToGround: true});
      promise.then(function(dataSource) {
          console.log("Munna");
          console.log(viewer);
        viewer.dataSources.add(dataSource);
  
          //Get the array of entities
          var entities = dataSource.entities.values;
  
          var colorHash = {};
          for (var i = 0; i < entities.length; i++) {
              //For each entity, create a random color based on the state name.
              //Some states have multiple entities, so we store the color in a
              //hash so that we use the same color for the entire state.
              var entity = entities[i];
              var name = "Munna";//entity.name;
              var color = colorHash[name];
              if (!color) {
                  color = Cesium.Color.fromRandom({
                      alpha : 0.4
                  });
                  colorHash[name] = color;
              }
  
              //Set the polygon material to our random color.
              entity.polygon.material = Cesium.Color.RED.withAlpha(1);
              //Remove the outlines.
              entity.polygon.outline = true;
              entity.polygon.outlineColor=Cesium.Color.BLACK;
              //Extrude the polygon based on the state's population.  Each entity
              //stores the properties for the GeoJSON feature it was created from
              entity.polygon.extrudedHeight =entity.properties.Hght;// / 50.0;
              entity.polygon.extrudedHeightReference=Cesium.HeightReference.RELATIVE_TO_GROUND;
              entity.polygon.perPositionHeight =false;
              //entity.polygon.height=67;
              entity.polygon.heightReference=Cesium.HeightReference.CLAMP_TO_GROUND;
          }
          viewer.flyTo(promise);
      }).otherwise(function(error){
          //Display any errrors encountered while loading.
          console.log(error);
      });```

And what it looks like.

![image](https://user-images.githubusercontent.com/4126790/46259158-a7e02c80-c4a3-11e8-9964-314667542ac3.png)

@munna
Copy link

munna commented Oct 1, 2018

@GatorScott , Thank you very much . its working as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.