I made this Sandcastle to try to illustrate a problem I’m having, but it turned out crazier than the original issue.
Let me back up for a minute. I wanted to make a “label” that stays at a fixed size while zooming, so I thought I could create an image of the text in question and use it as a billboard with sizeInMeters: true
. This mostly worked, but the “text image” wound up a bit smaller than I expected it to be – if I told it to be 55km across, it would measure out at maybe 43km. I couldn’t figure out why, so I put together a simpler version, in the sandcastle I linked above. I just made a simple rectangle, then drew a box on a canvas with the same aspect ratio and attached it to a billboard in the same entity with the same dimensions.
I expected the billboard to be a little smaller than the rectangle, same as in my project, but I got this:
WAT.
That skinny purple rectangle is a billboard with a width twice its height. The original image has the correct aspect ratio (400x200 px), which you can see by going to the console and looking at canvas.toDataURL()
– in Chrome, at least, you can right-click the resulting data:
link and Open in New Tab. I have no idea how it’s rendering at an aspect ratio of maybe 1:4 instead of 2:1. Am I using the properties incorrectly? Is there some fundamental thing I don’t understand? Or is the feature just totally broken?
Note: I am aware that my measurement for the meter-width of the rectangle is approximate. They’re not supposed to line up exactly, I’m just trying to provide rough numbers to illustrate the issue.
“Totally broken” is a bit harsh. It usually works, but this seems like a bug. With
width: 65536,
height: 32768,
the image is not distorted.
With
width: 80000,
height: 40000,
the image is slightly distorted.
I sunk some time with debugging that, and eventually, it seems to boil down to the imageWidth
being clamped to 65536
at https://github.com/CesiumGS/cesium/blob/d49c0c3b208e406e984039b03c4b96a3ab07bf8b/Source/Scene/BillboardCollection.js#L1095 for some sort of compressed storage.
(Sorry, no idea for a fix/workaround, but maybe the pointer is helpful)
2 Likes
Thanks, it is definitely helpful! It never even occurred to me that the size of the billboard would be a factor. I made my own drawing tools in the project I’m working on, so I was just kind of doodling on the globe, not really thinking about the real-world implications of a 400km shape.
With this, I can put together a repro and file an issue on their tracker to get it addressed.
A vague gut feeling is that the reason for the error (and thus a possible path of tackling this and fixing the bug) is that the imageWidth
is assumed to be the actual image size - and there’s hardly a point of having images that are more than 65536 pixels wide.
So it might be that one “only” has to change some code from
process(billboard) {
writeCompressedData(billboard.width);
...
}
to
process(billboard) {
widthInPixels = billboard.sizeInMeters ?
convertToPixels(billboard.width) :
billboard.width;
writeCompressedData(widthInPixels);
...
}
But spotting the right place for this (and not breaking other configurations when fixing it) might not be so trivial.
I’m glad you replied because I actually forgot to file the issue this morning. I just opened this.