cesium icon indicating copy to clipboard operation
cesium copied to clipboard

Request Render Mode spotty with Entities

Open ggetz opened this issue 11 months ago โ€ข 14 comments

What happened?

Originally reported on the community forum

Hereโ€™s my use case: I have a geojson data source loaded (a polyline) , then I change the color or the thickness. When I set my renderMode=false, everything happens as expected. But for performance reasons, I need to be in renderMode=true.

Changing the color is still functional, but changing the thickness is not. Of course, Iโ€™ve added a call to scene.requestRender().

I can display my entity. Then if I change the thickness, the entity is no longer displayed. I have to manually move the camera to display the path with the correct thickness.

I found this PR #11934 and this Sandcastle

In the sandcastle, the requestRender does not work too with 1.127 (which is the version Iโ€™m using in my app)

We've also identified a similar reproduction in the Rendering Performance Sandcastle. When the "mouseover picking" option is selected, the entity does not appear until the camera moves, or a new frame is rendered for an unrelated reason.

Curiously enough, the second case is only reproducible at larger viewport sizes.

Likely, this is due to the entities becoming "ready" for rendering after the next immediate frame.

Reproduction steps

No response

Sandcastle example

No response

Environment

Browser: All CesiumJS Version: ID'd in 1.110 and 1.127 Operating System: All

ggetz avatar Mar 31 '25 15:03 ggetz

Thanks for reporting this. I've enhanced the react workaround I've published on the forum but It's not functional at 100%.

I've another case where render mode is a problem. Changing layer color parameters like h,s,l , brightness, contrast

**edit ** the last case works after a call to viewer.scene.requestRender() :)

chdenat avatar Apr 01 '25 15:04 chdenat

Any news on this? This is annoying.

I'm playing with entities and the UI I wrote toggles visibility. Hide an entity is immediately take n into account but the opposite, showing an entity, needs to move the camera to see effect.

chdenat avatar Apr 27 '25 09:04 chdenat

Hi @chdenat No new yet. If you are interesting in contributing, please let us know and we'd be happy to discuss implementation or review a PR. Thanks!

ggetz avatar May 08 '25 15:05 ggetz

@ggetz , thank you for the news ! Unfortunately, although I know the cesium API well, I do not have sufficient knowledge to help at the core level. Sometimes I look at the source code, but it's more to understand how a class or a feature works.

chdenat avatar May 08 '25 18:05 chdenat

Unfortunately this is a blocker for my organization updating, I looked through merge requests which affected the render loop of datasources and found the cause to be #12429, specifically: https://github.com/CesiumGS/cesium/blob/fb314464d211abf51649b17151137db7a403502a/packages/engine/Source/DataSources/DataSourceDisplay.js#L327-L333

Line 333 explicitly will prevent the update callback to run scene.requestRender() after anything other than the first frame, which is a clear regression from the behavior before this MR.

A fix requires either adding an additional flag, removing the condition !this._ready from line 327, or undoing the change. I am not sure the exact meaning of the ready flag, but it was clearly used as a "dirty" flag before this MR. I would like to get a fix in before 1.130

Beilinson avatar May 21 '25 13:05 Beilinson

@ggetz I've opened a PR solving the issue, it's ready for review:

#12630

For now, the following monkey patch solves the issue until that gets merged:

const originalUpdate = DataSourceDisplay.prototype.update;
let prevResult = false;

DataSourceDisplay.prototype.update = function(time) {
  const result = originalUpdate.call(this, time);
  if (!prevResult && result) {
    this._scene.requestRender();
  }
  prevResult = result;
}

Beilinson avatar May 26 '25 16:05 Beilinson

As I just had a similar experience let me add my two cents: While I think that @Beilinson's PR is fixing this for DataSources I suspect there is either a general underlying problem or the same thing is happening for different data classes with differente reasons.

I have a project that uses requestRenderMode and where I loaded ~50.000 entities. The entities are not loaded via a data source class but each one via viewer.entities.add(). This is still rendering relatively smoothly but any change to those entities (e.g. changing the color of one of them) is not becoming visible when calling scene.requestRender() immediately after the change. Instead I have to call scene.requestRender() again after about 2 seconds and only then the changed color is rendered.

As this is not happening, when only a few entites are rendered, this seems to be related to the amount of entities that are loaded in the scene. However, I would have guessed that a change to the entities properties would be available immediately for the next rendered frame.

Is this expected behavior or a similar/the same problem that @Beilinson fixed for data sources?

Edit: I just noticed that the problems disappear when I use CallbackProperties instead of updating the materials manually. So this is probably not really an issue. Just a bit counter-intuitive that a function that is evaluated for every geometry is more performant than manually changing the assigned material when something changes. ๐Ÿ˜„ However, I also noticed that using CallbackProperties for something like the hierarchy property when loading a big amount of polygons (~50k) is extremely reducing the loading speed (to a point where it just doesn't make sense to use them). So I guess I have to live with one of the problems when loading so many entities (I know that the general answer is to use something like 3DTiles ๐Ÿ™‚).

UniquePanda avatar Jun 02 '25 20:06 UniquePanda

A second note: A colleague of mine just experienced a similar problem with only a handful of entities (not DataSources, just entities added via viewer.entities.add()). So yes, we can confirm that this problem still exists (entities or updates to them not being rendered properly after a call to scene.requestRender() and only becoming visible after another call to requestRender() some time after the first one).

UniquePanda avatar Jun 10 '25 08:06 UniquePanda

Viewer.entities is a shortcut to a default DataSource, so my PR/monkeypatch should fix your problems.

@UniquePanda Could you try applying the monkeypatch and if it doesn't work send a sandbox showcasing the issue you're seeing?

Beilinson avatar Jun 10 '25 10:06 Beilinson

@Beilinson Very interesting to know. Thanks for the info!

While I wasn't able to fix the bug in my application with your monkey patch yet (I'm a bit in a hurry right now, probably applied the patch wrongly), I was able to quickly create a sandcastle that mimicks one of my use cases for a single line. If your monkey patch is commented out, the height update is only visible once the camera is moved. With your monkey patch the update happens correctly when requestRender() is called!

So I'd say it's working. I'll try it in my application again later today, but if it works in the sandcastle and not in my app, then that's probably just on my side. ^^

https://sandcastle.cesium.com/#c=lVVRUxMxEP4rax+YY6wpqPhQCiMUn5SBAcQH6zjhsr2L5pIz2cAcTP+7yV2utFIc7cNdkt39srvfd9vcaEdgrCyk5upzLTghHMAUnfQVO+HEL423OZ5IVyvesNoaMtTUyHzruz/TCglqi7cX6LyiEDznykXDTI9GcGr0T2yg5pSXYOZwjFJJ7YxmrXlqqgp1yMATkAGHCDe+CLZ/ziBe6HVO0uiMZIXb8DDTAHlbmO1zWq+Q5VypjErphtDG7McQOYfsxUolW1spPkECxAj23eWokVn85dHRBWqBNusQFvGx1osOIBgXbUO6rG4l3qENVo13fauv27NsNsjb/dRo4lKjnQ2G8LB216kROAayHhfbK6Chq7EXHTYLPZUk0TEuRJayr41qote4LyceORk758bwtT+DPqUptxRWXL9hc2uqEywsoste7e68YztDeLsXnzvbw/8I3NsY+G25upOCyjHsLQ+qwJaVXI1Xe3WeCjnzFF+nyefcmhotNdnDY0a5UcaOl4nFHbv4cLKSs+lAphscjz8dTT8+df3SJfl6aVn0pSzCO5GSeLg3proy2R+sdC6XXIucO1IYWboyRt1we+yJgpJngyMhoERZlBQl0EscsjV9L/kLzMfUWM8xW1pYgXTNlcek0S6Qix/eEYrzFYDHkIrXWdZvt+HgsFdMF5wHfk1heV3KvAd4HBrTFWvL/1IOj5D7CW4DEOuKhpcHsLsTfsnVInmrn1HYBRdh7bKekI24yuhCkhc4/Lsbp3/w6pJMPunj71gFCGPti6QyNMtazMNca2qpi2h5hqL1STCNPeaalnJ+wlV3X7rqyDlZ6HBBmE64Iggh4+WqgUaiEq61Ol5hGklh8JXGFyVLMM+n9uT6VGbS9HPTsG3HYDiYOGoUHvbdfC+r2lgCb1XG2IiwClM9cDm68flPJJY716tjMloNnQh5C1IcbJiQkCvuXLDMvVKX8h5ng8PJKPg/CVUmKEUXZ7dow39JdCt3Dz91h4yxyShsN0dS93n+gfwb

Edit: @Beilinson I can confirm this also fixes the problems in my app. Just had to add the monkey a little bit differently, but that's just my code. Good work. ๐Ÿ‘

UniquePanda avatar Jun 10 '25 11:06 UniquePanda

Glad to see my monkeypatch is helping, in my app I am still encountering issues with billboards. I've created a sandbox that shows off running requestRender after adding an entity with a billboard will not actually render the billboard... Will investigate and try to get a fix in to the main branch + a monkeypatch. Currently this seems to affect only billboards, points and labels dont have any issue.

https://sandcastle.cesium.com/#c=rZRbb9owFMe/ipWnIDEnXMoEA7SOrlKlrKDBupdIyEkOwapjZ7YDbSe++5wLaQdMg2kvkX38P/efEgquNNpQ2IJEI8RhiyagaJbgh8Jm+1ZY3CeCa0I5SN9qfPB56YFVCBxwBEEWz9dieytJAmoGcg6h4JEJqGUGh3IJPzJQ+ivwCOQXEcGrzudhUVBINX0Brj4R/jgj8tEoqhDAtXkDhUkU2T99jlAqlLEIPthXPiFSmxPhHbySIrmBWAIo+937K9zq9br9ThN1+rjv9tyrTrfRzGMElLFAEBkNUBETIZqQGAbItzB2irNyyvBLT8RiKTYgGXnGKY99q1m6bGmk1wPU61b3NdB4rWvDrvgyEgCrs2h40nmSSdUvyhtGecd11JUZfC5pdVONEsGFSkkI9bPSzwzq1r08+jw34ds7z1te398sp98W3t3950ovMs3MGr+XtbYrq+lG05CwqaQxfZ3kw29mvJjOKn1Kn4BNVysFprY30NSjb9uumXK7UXe+axTrrbb4IkSyEPbBTnOJibigCZgybbuBRuNyUofLl5CYDVwzZuc+9fsJvgrBronaS9d1yxrOS1Hz9X8IO8XYP1F2zNkRaXvWDmk7i7e/Enc5c3+i7nLuLiVvP4nduZh095hYTWtY9DneZ/5Ik1RIjTLJbLMuDUnKiMnpBFn4CBqHSpVZEBo6b12HEd0gGo1O/EpRyIhS5mWVMTY3K/Gt8dAx+iNXJkhEeTwtichl69bYK40Y46Fjrqc9tRAsIPIg8i8

Beilinson avatar Jun 11 '25 13:06 Beilinson

@Beilinson This is a bug regarding billboards and label background. Sometimes billboards (or label backgrounds) need one more render... Sometimes it is fixed, then it is broken again (or broken in another way).

I adapted your sandcastle so that the label should re-appear with a red background, but that only happens after another render:

Image

I documented that issue regarding label backgrounds here: https://github.com/CesiumGS/cesium/issues/12138, maybe that helps?

anne-gropler avatar Jun 11 '25 14:06 anne-gropler

I looked into the billboard issue quickly, it stems from #12495, the commit right before (bea07c6f4572ce4c2f2b5ed02efc09cb252fa142) doesn't have the billboard issue with requestRenderMode.

The surprising part @anne-gropler is that the label issue doesn't exist in the commit above either, at least from my local testing, despite that being Cesium 1.126, from your ticket I saw the issue documented at 1.120. In #12138 your first sandcastle (which I can confirm is still broken) is an issue with the label primitive, not the entity, here its an issue with a newly created entity, so these are most likely only partially related.

Beilinson avatar Jun 11 '25 14:06 Beilinson

couple hours of research has led to some conclusions:

#12495 was a significant refactor so I'm still looking through it to understand exactly what can be fixed, but the main issue seems to be that as part of the transition to the new model, the image ends up being added the to processing queue only after being resolved asynchronously. This results in the the image queue being empty the first few frames immediately after an entity is added, as can be seen from this debug:

Image

Unlike in the previous implementation, there is no afterRender.push(() => true) when the image gets resolved, and any trigger to a render before had already completed so the label doesn't get rendered. This is what causes the label background to not appear... only the first time. After one label with background has loaded, the texture (just a plain white background) already exists, so all other labels don't have this issue.

The main issue fixing this is that with the current implementation, there is no way to know when to call BillboardCollection.update again when the image resolves in order to trigger the processImageQueue function in order to finally resolve the addImage method...

I have a fix for billboards in the PR, however it doesn't work for labels, not sure why currently but as I said its less of an issue

Beilinson avatar Jun 11 '25 20:06 Beilinson

this issue was also mentioned in https://github.com/CesiumGS/cesium/issues/12626

lukemckinstry avatar Jul 29 '25 14:07 lukemckinstry

The following is a sandcastle that adds a poyline entity and calls requestRender. The polyline is not displayed. Only after calling requestRender after some delay, the polyline is displayed

https://sandcastle.cesium.com/#c=rVRdb9owFP0rV7yUStTkiySmFG1iH5q0aVNb7WXZg4lvwaoTs9gppVX/+24CBcqo1If5Jfa9x+dc2+cmN6V1cKdwiRVcQIlLmKBVdcF+trFu1snb9cSUTqgSq6zTg8esBKjwT43WXWIpsfpmJA7BVTX2mlwh7lVRF+vctSpwMhfljBBfyhtVKrfKyqfT86zMW3mbY4mkvi6DtUtKtl8mcVrPruZm+akSBdofWF0hbZOEb+QIl5X9PryXEgQsjF5pqhLEjaMDCZCoxQqcoYpuEWxdIeAdVis3V+UMlAVthERJYuiaOk3tut1TuBivz7ipCEunnELLhJTdNgFbqSFsAuugJSAdagi/dlEaj1nnPusM4cz3fR57CYuT1AvSxEviXtZZtalBGMZBPGA+D9IgShJKPDSJMOA8DlI2CHkUxaHPn3rHuYMg4p7HIj/waUpjRx3EXuSnzIuj2POTKN5yD9J4ENAeKiaOojRMXiPnoRfzgEUJDzknON+SRzyI+SBm3OMekUX+lpwHPPI9SkQDUg3T17j/y6XsqH/vyeRaFItr87kydSn3HLoehSCbKKGHz66fGG0qdvnxwx5oqaSbD2GwjrQ6rXmJnF7aaGTazLonE6F1Y6oXfUFekqrC3OnVxpNuThZs/LSCpbBAjkJ5sqbb9z87oGkBx036xjrEjPr3ZWNsdN+g/NQD36PRrDbz07b1Or3OyLqVxvHzhb1TxcJUDupKdxnrOywWmq7Z9qd1fouO5dY+ywI4MdW7B3Hz3VTu99XUVFTLEPzFPdBJlYTlXDk8P0Sc5UZrsbDUlc+zLWZrEOdetCy9AF3XENLF/SF21N8/2kiqO1Dy4sgvsbGZtZS5qbW+Ug+YdcajPuH/2dr8b0juO/2E6AEa2Nwff10HGWOjPi2P73TG6KmoDpj/Ag

Regardless of different attitudes that people might have about ~"what should trigger an update", the fact that the object is not displayed even though requestRender is called looks like a clear-cut bug to me. (One might think that it should be one that is easy to fix: "Just add some ready.then(render()); at the right place". But ... "Pull requests welcome"...)

javagl avatar Aug 26 '25 14:08 javagl

The following is a sandcastle that adds a poyline entity and calls requestRender. The polyline is not displayed. Only after calling requestRender after some delay, the polyline is displayed

@javagl I don't know if that info helps, but I can reproduce the problem in your sandcastle only in Chrome. It works well in Firefox. If I change the first timeout from 1 second to 5 seconds, I also have the problem in Firefox, so I guess the first requestRender happens when the scene is still rendering anyways. Just my 2 cents in case somebody looks at the Sandcastle and thinks that it wouldn't be reproducible. :)

anne-gropler avatar Sep 02 '25 07:09 anne-gropler

@anne-gropler I just tried it out in FireFox, and could reproduce it there as well. The change that you described for making it happen on FireFox sounds a bit surprising: "Everything" that is relevant here is happening after 1 (or then 5) seconds - I don't see how "doing this later" should affect it. Regardless of the details, there is a race condition: The viewer.entities.add triggers some worker, and this worker may only be done after the requestRender call was issued.

javagl avatar Sep 02 '25 11:09 javagl

@javagl I'm also having trouble reproducing the issue you describe in main.

Using a modified version of the sandcastle you provided that remove all requestRender calls (and a very long initial timeout) still always renders the polyline. I'm using Chrome on a Mac if that makes a difference.

ggetz avatar Sep 22 '25 20:09 ggetz

Here is the sandcastle that I originally posted, with 3/5 second delays:

Image

The sandcastle that you posted prints "add polyline" after 15 seconds, but nothing is displayed without further interaction.

Both on Chrome. It's hard to imagine that this depends on the OS, but ... nobody can really be sure here. (And... spoiler: The Browser is the OS ๐Ÿ˜ )

In the draft PR, I "confirmed" some of this behavior with debug logs. In doubt, I could try to re-insert them, but don't know whether that would bring any insights for why it sometimes does work.

javagl avatar Sep 22 '25 21:09 javagl

Bizarre. Turns out I can consistency reproduce in Firefox. I have no idea why, but that should at least be sufficient for testing https://github.com/CesiumGS/cesium/pull/12841.

ggetz avatar Sep 22 '25 21:09 ggetz