Proper way to support HDPI/Retina display at full resolution and scaled properly?

Hi all,

I am looking for help figuring out the proper way to support HDPI/Retina displays with the BabylonJS engine and a fullscreen ui.

I understand that I can use the adaptToDeviceRatio parameter when constructing the engine to render at the full resolution of the display. This is a very easy and simple feature work with and the output looks stellar on high DPI displays!

Where I’m getting stuck is in the GUI. When the engine is adapting to the device’s pixelRatio, the GUI gets smaller which is not desired. My current monitors have a pixelRatio of 2, making the GUI half the size it should be.

I created a playground example with a button that toggles the engine’s hardwareScalingLevel between 1 and your device’s pixelRatio to demonstrate this. Note that if your display’s pixel density is 1 you won’t see a difference when you toggle.

How can I use adaptToDeviceRatio without the UI shrinking?

1 Like

Here we are:

I’m using the adt.renderScale :slight_smile:


@Deltakosh Thanks again for your very quick reply! I’ve been analyzing this for a couple hours now and I’m not sure I’m getting the effect I hoped for. The scaling is certainly fixed with adt.renderScale, but I don’t see any improvement in the legibility of the text.

I updated the playground with a Torus Knot to help visualize the clarity of the 3D scene. The corners and lines of the torus are slightly clearer when the engine’s hardware scaling level is 2 instead of 1. However, the text looks identical to me.

I took a screenshot with and without adapting to the device ratio and layered it in photoshop to create this comparison. The left side is hardwareScalingLevel = 1 and the right side is hardwareScalingLevel = 0.5.

Its subtle, but we can clearly see the difference in the rendered scene.

Unfortunately the same is not true for the UI. Here’s the same two screenshots layered again to showcase the difference between the two. The left side is hardwareScalingLevel = 1 and the right side is hardwareScalingLevel = 0.5.

As far as I can tell, there is no change to the clarity or resolution of the GUI. After further comparison in Photoshop, the pixels that make up the GUI are actually identical regardless of the hardwareScalingLevel & renderScale.

Is this expected?
Is this just a current limitation or is there any way to get crisper text?

What I could suggest is then doing something like that (we want more pixel for the texture):

Ah, now that’s the clarity I was searching for! Unfortunately, the frame rate dropped from 60fps to less than 10fps, so maybe this isn’t a practical solution?

I also noticed that the rounded corners are no longer accurate when going with this high of a resolution. I suspect there would be others GUI elements that would have similar issues.
EDIT: Ok, I didn’t notice you had to multiply all the values by the scale to get that to work.

Is the texture for the 3D scene tied to the texture of the GUI? For example, could we choose to render the 3D scene normally but render the GUI texture with more pixels to get crisper text?

maybe 4 times is TOO much
also you may not need to scale the engine. Just the texture

Thanks for your help @Deltakosh!

While I dislike the thought of having to manually multiply all GUI values in the project by scale, I cannot deny that this works!

I made a few improvements to my code in the playground example. On line 42 the user can set their desiredScaleFactor. Dropping from 4 to 2 significantly improved the frame rate.
EDIT: Actually, seems like my math is only good if the desiredScaleFactor is 1 or 2. But I think it gets the point across. :slight_smile:

It would be cool to figure out how to control the scale of the engine separately from the GUI texture. Might give it a try tomorrow.

1 Like

Hey, this thread was super useful to me. I’ve posted something related and thought it could be useful to cross link: Billboard UI with zoom based scaling (including retina screens)

1 Like