CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.86k stars 3.47k forks source link

Poor billboard quality #4235

Open hpinkos opened 8 years ago

hpinkos commented 8 years ago

Reported on the forum: https://groups.google.com/d/msg/cesium-dev/OLbOuzNRM7U/MHgo_4N6CwAJ

The icon to the left is a billboard, the icon to the right is the original image

image

emackey commented 8 years ago

I believe this happens because billboards are not aligned to the nearest pixel. When a billboard has a non-integer screen location, it becomes blurred by the fullscreen AA process.

There's a suggested fix on Stack Overflow that involves making a one-line change to BillboardCollectionVS.glsl#L245, to change it from:

gl_Position = czm_viewportOrthographic * vec4(positionWC.xy, -positionWC.z, 1.0);

to:

gl_Position = czm_viewportOrthographic * vec4(floor(positionWC.xy + 0.5), -positionWC.z, 1.0);

This has the effect of greatly reducing blur on both Billboards and Labels.

What do you guys think of this? If you like it, I can make a pull request out of it (assuming we can take code from SO. I presume most projects already have quite a bit of uncredited SO code around).

The reasoning seems clear: Billboards are always raster images, so non-integer screen locations will always be worse quality than pixel-aligned locations.

lilleyse commented 8 years ago

Ah cool, can you post a screenshot of the difference?

emackey commented 8 years ago

The Stack Overflow answer has a good screenshot:

http://stackoverflow.com/questions/33784256/cesium-label-blurred/33786151#33786151

shunter commented 8 years ago

If this feels like deja-vu, you're right. Here's where clamp-to-pixel functionality was added: #188 Here's where it was removed again: #565.

emackey commented 8 years ago

Good memory @shunter. In experimenting with this code, it looks like the clamp-to-pixel is not what's actually improving this guy's screenshots. He's also turning off scene.fxaa at the same time, and that appears to be what actually cleans up the label.

mramato commented 8 years ago

Yeah, fxaa is probably the real culprit here. Clamping to pixel actually does not do what we would hope it would do (Especially with text). It also causes all kinds of problem when during motion (either because the item is moving or the camera is moving). Not clamping really is the "correct" option.

I asked Dan about possibly not running fxaa on labels and billboards and he things it might be possible but might require too much overhead or other craziness.

I just noticed he's also provided us with an svg, that's probably compounding the problem because the svg is properly be anti-aliased on rasterization by the browser (and depending on the browser it could be doing a bad job).

@hpinkos can you reach out and get the original icon? I didn't notice it in that thread.

emackey commented 8 years ago

I asked @bagnell offline how our fxaa is actually implemented. He suggested this was based on an older approximation where high-contrast edges are intentionally blurred, which is fast enough for realtime, but is a very different implementation from true anti-aliasing. There was talk of this possibly being upgraded to a different algorithm when WebGL 2 becomes more widely available.

So it sounds like the blurring is a design feature of the current fxaa system, making it almost unavoidable without a rewrite or disabling of fxaa.

pjcozzi commented 8 years ago

I don't think it is out of the question to render to one framebuffer that would get FXAA, and another for labels/billboards/points that would not, and then composite them. This would also work well with the need to render labels on top of polygons since the low level-renderer now would have explicit-ish knowledge of labels/billboards/points.

This will be a non-trivial amount of time though so we can't do it for a few months.

hpinkos commented 8 years ago

Here is a png and svg version of the icon from the user. He says the png looks better than the svg

icon-sourdough-library 2x icon-library.svg.txt

mramato commented 8 years ago

Here is a png and svg version of the icon from the user. He says the png looks better than the svg

This is exactly what I assumed a large part of the problem was. Browsers do not all do an equally good job of rasterizing/resizing SVGs, so the fact that it's an SVG is one of the reasons it looked so blurry.

emackey commented 8 years ago

True, but we still have big problem with fxaa intentionally blurring our billboards and labels. I think @pjcozzi's comment is the path to persue, when time permits.

mramato commented 8 years ago

I think everyone agrees @emackey I just wanted to point out that SVGs can compound the issue.

denverpierce commented 8 years ago

Related to #2752 and #3279 . If you're considering separate frame buffers, being able to selectively apply it to imagery tiles as well would be helpful. An AA pass on tiles, especially those with labels, reduces quality.

hpinkos commented 7 years ago

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

bagnell commented 7 years ago

I investigated this at the bug bash. It would be quite a bit of work to selectively apply anti-aliasing. Here is the post process that would happen after each frustum instead of on the entire scene: 20170209_122413

pjcozzi commented 7 years ago

@bagnell can you post a link to the branch-in-progress and before/after screenshots?

bagnell commented 7 years ago

The branch is selective-fxaa. Before: image After: image

pjcozzi commented 7 years ago

Another idea is to render pick ids with MRT (or a separate pass to an offscreen framebuffer/texture), and then only blur pixels where the surrounding pick ids are different so only the ends of objects are blurred. Billboards, the globe texture, etc. would not be blurred except at the silhouettes.

denverpierce commented 7 years ago

Would these fixes apply to #3279 as well?

pjcozzi commented 7 years ago

@denverpierce they would be part of the solution.

expatiating commented 2 years ago

I believe that this is still an issue - has there been any additional thought on this topic in the last ~5 years?

Or is there a recommended approach to solve with billboards and text overlays?

ggetz commented 1 year ago

Quality issue when moving reported in https://community.cesium.com/t/billboard-with-custom-canvas-image-gets-darker-brighter-on-scrolling-rotating/25221/2.

Huyston commented 1 year ago

I'm still having this issue. Here is an example: sandcastle I'm trying to create many billboards with a rectangle texture. I tried supplying an image with the "pixelated" style to prevent the image from blurring. Note that the image on the top is not blurred, but the rendered rectangle in Cesium is blurred. Also tried disabling fxaa and antialias, without success. Update: The only way I could achieve the pixelated image texture render was changing the shader code.

dukeofcool199 commented 11 months ago

Any further investigation into this issue? I can see that even in the sandcastle examples the billboard quality is low as well.

ggetz commented 11 months ago

Thanks for the interest. There hasn't been any activity on this item recently, but it is definitely on our radar.

dukeofcool199 commented 11 months ago

for anyone else that has found this thread, my co-worker came across this other thread explaining how billboards were made intentionally blurry to help with running on mobile devices. and that viewing billboards at a browser zoom level of anything other than 100% will cause this issue to become more noticeable. The workaround from the thread states to adjust the value of viewer.resolutionScale property I tested this fix in this sandcastle with some success.

UPDATE:

change this setting for the viewer viewer.useBrowserRecommendedResolution to be false

badg0003 commented 10 months ago

@dukeofcool199 Thanks big time for this. I've been searching and made too many attempts to fix this than I want to admit lol, but your tip did the trick! :)

CassandraCat commented 1 day ago

for anyone else that has found this thread, my co-worker came across this other thread explaining how billboards were made intentionally blurry to help with running on mobile devices. and that viewing billboards at a browser zoom level of anything other than 100% will cause this issue to become more noticeable. The workaround from the thread states to adjust the value of viewer.resolutionScale property I tested this fix in this sandcastle with some success.

UPDATE:

change this setting for the viewer viewer.useBrowserRecommendedResolution to be false

nice bro.