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

Billboard clipped on right side #5154

Open
spatialillusions opened this issue Mar 27, 2017 · 7 comments
Open

Billboard clipped on right side #5154

spatialillusions opened this issue Mar 27, 2017 · 7 comments

Comments

@spatialillusions
Copy link

spatialillusions commented Mar 27, 2017

In Cesium 1.31

I have a large number (500+) of quite large (200x100pixel) billboards on my map, and this problem only occurs when the number of billboards is large. The billboard image are canvases that I draw with javascript within the application.

For some reason, the billboards are clipped on the right hand side:
screen shot 2017-03-27 at 19 33 00

This can be compared to using the same canvas images as icons in Open Layers:
screen shot 2017-03-27 at 19 43 17

What is really strange, is that I can almost solve the problem if I set the imageSubRegion to be bigger than the canvas itself.

var entity = {
  position: Cesium.Cartesian3.fromDegrees(feature.geometry.coordinates[0], feature.geometry.coordinates[1]), 
  billboard: {
    horizontalOrigin : Cesium.HorizontalOrigin.LEFT, 
    verticalOrigin : Cesium.VerticalOrigin.TOP,
    image: ctx,
    imageSubRegion: new Cesium.BoundingRectangle(0, 0, ctx.width+2, ctx.height+2),
    height: milsymbol.getSize().height,
    width: milsymbol.getSize().width,
    pixelOffset : new Cesium.Cartesian2(-milsymbol.getAnchor().x, -milsymbol.getAnchor().y)
  }
}

Now this will be displayed:
screen shot 2017-03-27 at 19 34 51
Better but not perfect

If we zoom out a lot, we can also see that some of the missing lines from the right hand side is rendered on the left hand side of some symbols:
screen shot 2017-03-27 at 19 52 39
Notice the vertical lines that shouldn't be there

I figured out that Cesium stores the images in some kind of atlas, but I couldn't find where in the code this was done, and what could be the reason for this error. Please let me know if you need more information about this.

Added:
I tried to revert to Cesium 1.27 to see if #4675 introduced in 1.28 messed anything up, but the result in 1.27 was almost the same as in 1.31.

@pjcozzi
Copy link
Contributor

pjcozzi commented Mar 28, 2017

@spatialillusions thanks for the detailed writeup! It would help if you could

  • Create a minimal code example to reproduce this issue and try to push the limits (number of billboards, size of billboards) to see where the tipping point is.
  • Investigate TextureAtlas.js if you have the time. The issue could be there or it could be in BillboardCollection.js perhaps triggered by the vertex buffer growing pass a certain size or an issue with WebGL instancing (which you could try disabling) or the attribute compression. A pull request with a fix would be a very welcomed contribution!

@spatialillusions
Copy link
Author

I'll try to make a code example and get back with that.

I just had a quick look at the code and thought that this code might trigger some kind of error if it is called a bunch of times with changes in texture width, but I'm not sure if this is the reason.
https://github.com/AnalyticalGraphicsInc/cesium/blob/00cee6b97568ea7cf38b473e46540afb871347b5/Source/Scene/TextureAtlas.js#L187

@spatialillusions
Copy link
Author

spatialillusions commented Mar 29, 2017

I have made a small example here and I'm able to reproduce the issue with 225 symbols.
The included zip file contains a html file, and milsymbol.js that is used to render the icons. (I'm guesing that you can use a bunch of external files as well, but this is the fastest way to reproduce the issue.)
Archive.zip

At the moment I also have an online version of the sample:
http://spatialillusions.com/milgraphics/examples/slf-cesium-debug/

When I was testing, I noticed that to trigger the bug the billboards must have different sizes, I think this might be that the code will have trouble to find a suitable node in the atlas then, and because of this I have added the text BAZINGA, to every seventh node. 🙂

If you zoom out you will be able to see the vertical lines on the left hand side:
screen shot 2017-03-29 at 18 49 41

And also that some of the icons are missing a few pixels on the right hand side:
screen shot 2017-03-29 at 18 50 36

I tried looking into looking into the code some more, but how images are placed in the atlas and how the boundingboxes are calculated are a bit hard to understand and debug in a simple way. If I find some time I will try to look into it some more, but my guess is that it is easier to fix for someone who understands the atlas code better than me.

Addition:
It looks like much of the problems can be solved by bumping borderWidthInPixels but this might cause unnecessary overhead when using smaller images, so I think looking into the calculations are a better idea.

@emackey
Copy link
Contributor

emackey commented Mar 29, 2017

@spatialillusions Thanks for this detailed report. One thing I'll point out is that your milsymbol library does put a good size pad on the left side, but puts the right edge of the symbol directly against the right edge of the canvas, which makes it prone to this sort of clipping. You could work around this problem by moving a pixel or two of padding from the left side to the right.

That said though, we clearly have an issue in Cesium here. It looks like the right-most edge of pixels can possibly be lost due to sub-pixel positioning. This video was recorded while moving the mouse at the bottom of the screen, well below (in screen space) the icons being recorded, with the camera at a nice tilt. This resulted in whole-pixel movements only at the bottom of the screen, and sub-pixel movements in the area being recorded:

blinkeyborders

You can see the right edges of several icons blinking on and off. Seems like the billboard texture coordinates have some sort of rounding or quantization issue going on.

@pjcozzi
Copy link
Contributor

pjcozzi commented Mar 29, 2017

CC #172

@spatialillusions
Copy link
Author

@emackey I know about the padding on the left hand side. I try to make the spacing as little as possible, and if you remove the text information on the icons they will fit tight on the left hand side as well. The thing is that since I support multiple output formats I need some way to calculate the approximate length of the text string i pixels, and that calculation is far from perfect, and in some cases it will add extra space to be sure not to cut the labels.
If it turns out that it is too hard to fix this bug on your side I can add a few extra pixels of padding in the next release of milsymbol.

@duvifn
Copy link
Contributor

duvifn commented Apr 3, 2017

FYI, on my machine, this issue (vertical black lines and the right edge clipping with the given example) was noticeably improved with the change suggested in #3411 (comment) (but definitely not fixed).

Unfortunately, I currently don't have time to get into the failing spec.
So if someone has time to look at this he's welcome to open a PR with this change.

Also, given this compressed coordinates precision, isn't it better to limit the texture size of the atlas?

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

No branches or pull requests

5 participants