Oh this might be a bug. Looks if you if your device ratio is not 1. Adding render scale back will make it blurry. Let me log it and take a further look.
After further investigation this is not a bug. Instead this is functionality correct.
The solution of using render scale is correct provided you do set the correct hardware scaling to match. (I hard code 0.5 as the scale in this example to be consistent for everyone looking) https://playground.babylonjs.com/#2ARI2W#140
Further explanation of what’s happening when you set the root container’s scale.x and scale.y. Best way to show this is debug drawing in the inspector.
When we set the root containers scale. We are basically taking all the correct calculations we had and saying “shrink that” by the center. So now the entire boundary of the adt has been changed. If you were that determine to go the scale route, you would have to manually offset the position of the adt to match.
I will definitely update the documentation to reflect this!
Hope that gives a little more insight and let us know if you have any questions about this.
Your playground example rendered blurry text on my comp (it is more blurry than normal), even though my device pixel ratio is 2, so renderScale 0.5 should work.
Please clarify how to use renderScale correctly if I misunderstood.
That doesn’t work, I tried, the 20px fontSize becomes 5px (i.e. it got smaller by x4 times), so did the Multiline, which was supposed to have 1px lineWidth, became almost invisible.
Which means the renderScale here must be 1/window.devicePixelRatio - which results in correct fontSize, but blurry text like above screenshot.
Ah, yes! I see what you mean. You are correct the engine.setHardwareScalingLevel should be 1/window.devicePixelRatio. Right right.
I’m not entirely sure why it is blurry on your screen but not mine then…even with the same values. hmm
If changing the rootContainer.scale.X worked for you. How about just changing the scale.x of the button container itself? Your text is inside the button container.
I had the same issue with blurry text using the renderScale solution but scaling the button as recommended looks nice and crispy (I had to scale both x and y otherwise the button was half as tall as it should be). I’m on a new MacBook with devicePixelRatio 2, so maybe a 2X device is needed to see the blurry text issue I guess.
Looks like a bug, Blake’s solution worked for Text, but then Images and all other GUI controls that do not have scaleX, scaleY set got smaller x2 times.
The blurry issue happens to all GUI elements, including SVG image, MultiLine, Rectangle, etc.
@sebavan, is there another alternative solution to get crisp GUI, without setting engine hardware scaling level?
I see similar issue three years ago, still not resolved.
Correcting:this example had reversed label, setting engine.setHardwareScalingLevel < 1 did result in crispier 3D content. But current work around requires setHardwareScalingLevel < 1, and manually setting all GUI controls with scaleX = window.devicePixelRatio.
Right now, it’s impossible to achieve crisp GUI on retina screens without suffering performance for 3D content.
This is not an issue we can resolve easily or within the framework. Basically it all boils down to how high dpi is handled.
By default we use css size meaning the back buffer of the canvas is inversely proportional to the zoom level (devicePixelRatio) so every canvas pixel are laid out on several native pixels → text looks blurry.
By changing the hardwareScalingLevel you now have on the canvas back buffer the same res as native which is a lot of pixels to display and rendered think about rendering games at native 8k for instance which obviously is a lot but the text would not be blurry.
The only workaround bringing the best of both worlds could be in your application to setHardwareScalingLevel to native res, then render all of your scene but gui into a renderTargetTexture of your css or desired resolution (smaller than native)
Finally, blit the RTT on the canvas (linear interpolation to magnify) and render the GUI on top.
This would only work for full screen GUI and not for texture created for 3d content.
Using RTT could end up being slower because I have hundreds of Meshes, Materials and Textures on the scene.
Would be more useful to have a 3D position → 2D screen coordinates link observable that I can use to render Text and all other GUI elements using React/ReactNative components with CSS transform: translateX..., instead of Babylon’s GUI.
Does Babylon have something like that?
It opens a lot more possibility than what Babylon GUI currently offers. It means you have the entire frontend UI ecosystem at your disposal, and less components to maintain for Babylon.