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

Small fonts have misaligned glyphs #8474

Open
OmarShehata opened this issue Dec 18, 2019 · 7 comments
Open

Small fonts have misaligned glyphs #8474

OmarShehata opened this issue Dec 18, 2019 · 7 comments

Comments

@OmarShehata
Copy link
Contributor

Originally reported here: #4108 (comment)

Small text in labels seems to break the alignment:

image

This is a 12px font. It's less visible but still there at 24px, and not visible at 40px. This seems to happen regardless of whether the label is created with a small size font, or just a scaled down with the scale property. See this Sandcastle to explore this.

You can also see this in the Labels SDF Sandcastle if you turn off the animating morgantown to make it easier to see on a scaled down "Philadelphia" label.

This used to work as of 1.62. I'm guessing it's something we overlooked in #8351? CC @IanLilleyT

Here's a 1.62 Sandcastle showing it works correctly.

@mramato
Copy link
Contributor

mramato commented Dec 19, 2019

This doesn't seem to happen when devicePixelRatio is 1.0 (at least I don't see the problem on my achine), so I think you're right that it's #8351 related.

@mramato
Copy link
Contributor

mramato commented Dec 19, 2019

@lilleyse @IanLilleyT Since this is a recent regression, any change we can get to it for the next release? (It's okay if the answer is no, just figured I'd ask).

I assume this is completely orthogonal to #7376?

@IanLilleyT
Copy link
Contributor

IanLilleyT commented Dec 19, 2019

This is tricky... The old label code did pixel ratio stuff on the JS side. Then the vertex attributes (scale, offset, etc) were quantized and packed together to use as few attributes as possible. The new code does the attribute quantization the same but does the pixel ratio in the shader, which exaggerates this quantization error. 12px with that font could be uniquely bad looking depending on where the values are rounding from. Even the Cesium 1.62 version at 12px looks slightly wrong on the first 'a'

This comment in BillboardCollectionVS.glsl pointed me in this direction:

// Note the halfSize cannot be computed in JavaScript because it is sent via
// compressed vertex attributes that coerce it to an integer.

Question is, do we go back to doing pixel ratio on the JS side or figure out how to improve the vertex attribute compression...

@Maarondesigns
Copy link

This isn't a fix to the underlying issue, but I am achieving a better label solution creating an HTML canvas element and using it as a billboard.
Some of the variables are being computed based on different conditions like fontSize and translucencyByDistance

                //create div to get height and width then remove it
                let font = `bold ${fontSize}px Helvetica`
                var canvas = document.createElement("canvas");
                let textDiv = document.createElement("div");
                textDiv.style.position = "absolute";
                textDiv.style.font = font;
                textDiv.innerHTML = text;
                document.body.appendChild(textDiv);
                let { height, width } = textDiv.getBoundingClientRect();
                canvas.width = width + 10;
                canvas.height = height + 5;
                document.body.removeChild(textDiv);

                //create font in canvas element
                let ctx = canvas.getContext("2d");
                ctx.font = font;
                ctx.fillStyle = "white";
                ctx.lineWidth = 2;
                ctx.strokeText(text, 0, height);
                ctx.fillText(text, 0, height);

                //add to datasource
               myDatasouce.entities.add({
                    position: Cesium.Cartesian3.fromDegrees(lat, lon),
                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                    billboard: {
                        image: canvas,
                        translucencyByDistance,
                        disableDepthTestDistance: 100000,
                        eyeOffset: new Cesium.Cartesian3(0, 0, -1000000),
                        horizontalOrigin: Cesium.HorizontalOrigin.CENTER
                    }
                });

@demode29
Copy link

demode29 commented Jul 4, 2023

Hello, @IanLilleyT as pointed out I think issue is related to 'compressed vertex attributes that coerce it to an integer'. translate property in billboard coerces to int value and this issue occurs. We decided to pass translate property to shader directly without compression, however we lose compression. What are pros and cons of compression? Are there any alternatives? Thank you so much

@r20
Copy link

r20 commented Apr 3, 2024

I'm experiencing this bug and the billboard workaround has its own problems when I have 50 points with labels.
I asked if there's another workaround here: https://community.cesium.com/t/label-text-misaligned/31241

@r20
Copy link

r20 commented Apr 4, 2024

My workaround was to keep the font at 30px and use scaleByDistance. Using scale worked some times and was perhaps better than nothing, but with scaleByDistance it looked even better (even though I set the nearValue and farValue to the same thing)

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

7 participants