Resize and DPR

Handling Resize and Device Pixel Ratio

The engine sizes its drawing buffer at creation, so call engine.resize() whenever the canvas's CSS size changes; otherwise the image stretches. adaptToDeviceRatio multiplies the size by devicePixelRatio, as Resizing the Context did by hand. These canvases differ only in that flag, captured at a pixel ratio of 2:

adaptToDeviceRatio false and true, resized with a ResizeObserverHTMLLive
<style>canvas { width: 228px; height: 170px; margin-right: 4px }</style>
<canvas id="blurry"></canvas><canvas id="sharp"></canvas>
<script src="https://cdn.jsdelivr.net/npm/babylonjs@9.28.0/babylon.js"></script>
<script>
for (const [canvas, adapt] of [[blurry, false], [sharp, true]]) {
  const engine = new BABYLON.Engine(canvas, true, {}, adapt);
  const scene = new BABYLON.Scene(engine);
  scene.clearColor = BABYLON.Color4.FromHexString('#eceff1ff');
  BABYLON.MeshBuilder.CreateTorusKnot('knot', { tube: 0.15, radialSegments: 256 }, scene);
  scene.createDefaultCameraOrLight(true, true, false);  // camera framing the knot, light
  new ResizeObserver(() => engine.resize()).observe(canvas);
  scene.executeWhenReady(() => engine.runRenderLoop(() => scene.render()));
  scene.onAfterRenderObservable.add(() => { window.__done = scene.getFrameId() > 3; });
}
</script>
Browser output of Listing 7.7
Browser output of 7

The left engine renders 228 x 170 pixels, which the browser stretches over 456 x 340 device pixels, so its edges blur. Babylon 89,603 stores the ratio's inverse as a hardware scaling level (1 and 0.5 here); on a weak GPU, engine.setHardwareScalingLevel(1) draws a phone's 3x screen at CSS resolution, a ninth of the pixels. A ResizeObserver also catches layout changes that resize events miss.