Babylon LITE not working inside Android WebView

Hi,

I’m trying to get the basic Babylon LITE (v1.26.0) demo/example working within an Android WebView v151.0.7…(sic) (with Jetpack Compose code). It works fine inside the Chrome Browser on my phone, but doesn’t display anything inside the WebView in my App.

I’ve enabled Javascript, etc (as per another bug report) to no avail. I’ve also used Chrome DevTools to see if any problems are reported to the Console, but everything looks ok.. however, nothing is visible from BabylonJS (the rest of the page displays fine)!

For info, all the babylonJs code is bundled into one html file (using Bun) and is loaded and displayed, but BabylonJS doesn’t seem to render anything in the canvas tag! :frowning:

Here’s the main code below (any help appreciated!)

@SuppressLint("SetJavaScriptEnabled")
@Composable
fun MyView(context: Context,
             initialUrl: String = "https://appassets.androidplatform.net/assets/www/index.html",
             modifier: Modifier = Modifier) {
     val assetLoader =  WebViewAssetLoader.Builder()
        .addPathHandler("/assets/", WebViewAssetLoader.AssetsPathHandler(context))
        .build();

    AndroidView(
        modifier = modifier.fillMaxSize(),
        factory = { context ->
            WebView.setWebContentsDebuggingEnabled(true) // DEBUG TMP - use Chrome DevTools on PC to debug... https://developer.android.com/develop/ui/views/layout/webapps/debug-chrome-devtools

            WebView(context).apply {
                webViewClient = LocalContentWebViewClient(assetLoader)
                settings.javaScriptEnabled = true
                settings.allowContentAccess = true
                settings.allowFileAccess = true
                settings.allowFileAccessFromFileURLs = true
                settings.allowUniversalAccessFromFileURLs = true
                settings.domStorageEnabled = true
                settings.databaseEnabled = true
                settings.mediaPlaybackRequiresUserGesture = false
                loadUrl(initialUrl)
            }
        }
    )
}

private class LocalContentWebViewClient(private val assetLoader: WebViewAssetLoader) : WebViewClientCompat() {
    override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
        return assetLoader.shouldInterceptRequest(request.url)
    }

    @RequiresApi(Build.VERSION_CODES.O)
    override fun onRenderProcessGone(view: WebView?, detail: RenderProcessGoneDetail?): Boolean {
        // 1. Log or track the cause of the crash
        val didCrash = detail?.didCrash() ?: false
        Log.e("WebViewClient", "WebView renderer process gone. Did crash: $didCrash")

        view?.let {         // 2. Clean up the dead WebView instance
            it.destroy()             // Remove it from its layout parent if necessary
        }
        // 3. Trigger your custom UI update (e.g., show a reload button) - see below...
        //onCrashHandled()
        // 4. Return true to stop the Android app from crashing
        return true
    }
}

Chrome DevTools Web Console output:

WebGPU is supported on this Android device!
index.html:650 Hello world!
/favicon.ico:1  Failed to load resource: net::ERR_CACHE_MISS
index.html:36 Babylon Lite v1.26.0 - WebGPU engine

index.ts

import { init, destroy } from "./mine";

window.onload = init;

window.addEventListener('pagehide', (event) => {
  // If the event's persisted property is `true` the page is about // to enter the back/forward cache, which is also in the frozen state.
  // If the event's persisted property is not `true` the page is // about to be unloaded.
  const is_dead = !(event.persisted)
  if (is_dead) { destroy() }
});

mine.ts

import {
    createEngine,
    startEngine,
    destroyEngine,
    createScene,
    addToScene,
    registerScene,
    loadEnvironment,
    loadGltf,
    createSceneContext,
    createDefaultCamera,
    createFreeCamera,
    createArcRotateCamera,
    attachControl,
    createHemisphericLight,
    createGround,
    createSphere,
    createPbrMaterial,
    startRenderLoop,
} from "@babylonjs/lite";

let g_engine: any = null; // Keep a global tracking variable outside the init block to handle re-initialisation safely
let g_scene: any = null; // Keep a global tracking variable outside the init block to handle re-initialisation safely


export async function init() {
    if (navigator.gpu) {
        console.log("WebGPU is supported on this Android device!");
    } else {
        console.log("ERROR: WebGPU is not supported in this WebView! Falling back to WebGL.");
        alert("ERROR: WebGPU is not supported in this WebView! (Falling back to WebGL?)");
    }

    init2().catch( (e) => { console.error(e); alert("ERROR: "+e); } )
}
async function init2() {
    console.log("Hello world!");
    alert("MINE ON!");

    // setup ---------------------
    const canvas = document.getElementById("renderCanvas") as HTMLCanvasElement;

    if (g_engine) { await g_engine.dispose(); } // CRITICAL MEMORY FIX: If an engine instance exists from a previous run, destroy it completely
    g_engine = await createEngine(canvas); // Save reference to prevent leaks on reload

    if (g_scene) { await g_scene.dispose(); }
    g_scene = createSceneContext(g_engine);

    // create ---------------------
    test(canvas, g_engine, g_scene);

    // run ---------------------
    await registerScene(g_scene);
    await startEngine(g_engine);

    // final setup-------------
    window.addEventListener("resize", () => {
        g_engine.resize();
    });
}

export function destroy() {
    if (g_scene != null)  { disposeScene(g_scene);   }    // releases all meshes, renderables, disposables
    if (g_engine != null) { disposeEngine(g_engine); }    // destroys GPU device, render targets, swapchain
}

async function test(canvas, engine, scene) {
    const camera = createArcRotateCamera(-Math.PI / 2, Math.PI / 2.5, 4, { x: 0, y: 0, z: 0 });
    scene.camera = camera;
    attachControl(camera, canvas, scene);

    addToScene(scene, createHemisphericLight([0, 1, 0], 1.0));

    const sphere = createSphere(engine, { segments: 16, diameter: 2 });
    sphere.material = createPbrMaterial({ baseColorFactor: [0.9, 0.1, 0.1, 1], metallicFactor: 0.1, roughnessFactor: 0.4 });
    addToScene(scene, sphere);
}

Sorry if this code looks horrible: I don’t really know what I’m doing! :slight_smile:

The html:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Mine On!</title>
<style>
body {
    min-height: 100vh;
    margin: 0;
    padding: 0;
}

canvas {
    max-width: 100vw;
    max-height: 100vh;
    width: 100vw;
    height: 100vh;
    touch-action: none;
}
</style>
<script src="./index.ts"></script>
</head>
<body>
<h1>Help Me!</h1>
<p>
Hello
</p>
<hr>
<canvas id="renderCanvas"></canvas>
<hr>
<p>
.. canvas is above here..
</p>
<img src="./brdf-lut.png">
</body>
</html>

cc @Cedric to have a look

Hi @twjobs2005 , is the html available somewhere? or whole project actually

Hi Cedric, yes the html is in the bug report above, together with the typescript files, sorry the whole project isn’t accessible anywhere, but the things I’ve pasted are 99% of the project other the build (which is bun bundling and minifying ts with html into one html file for release and use in the app, ie the WebView only has to load one file, and this all seems to be working ok). As you can see, this is a minimal test project, so hopefully you can reproduce easily? Let me know if there’s something specific you need, but hopefully you have enough in the report? Thanks for your time!

I’ve adked an LLM to do an Android project with webview and your sources.

Result is available here : GitHub - CedricGuillemet/BabylonLiteAndroidWebview: Standalone Babylon Lite v1.26 Android WebView reproduction with Antigravity Racer · GitHub

Try to run this project on your device. Then, when it works, try to find the difference with your project (via an LLM as well). I’m sure there is a flag or another small tweak that needs to be done.

Let me know how it goes!

Thaks, I’ll have a look at that a bit later, but in the meantime, I wanted to see if maybe it was related to the canvas tag size not being set correctly (I think in old bjs, css sizing didn’t work well), so I got rid of the css sizing for the canvas and set it inside the html tag directly

<canvas id="renderCanvas" width="330" height="330"></canvas>

This then seemed to change the background color of the canvas to grey (it had been zero height and white background, ie like the rest of the page before), so it now looks like the engine is running at least, but I get the following repeated errors (or are they really just “INFO”?) in my web console:

21:36:57.426  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:9720, height:13500, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:8192, height:8192, depthOrArrayLayers:256]). This adapter supports a higher maxTextureDimension2D of 16384, which can be specified in requiredLimits when calling requestDevice(). Limits differ by hardware, so always check the adapter limits prior to requesting a higher limit.
 - While validating [TextureDescriptor ""scene-color""].
 - While calling [Device].CreateTexture([TextureDescriptor ""scene-color""]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "[Invalid Texture "scene-color"] is invalid due to a previous error.
 - While calling [Invalid Texture "scene-color"].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:9720, height:13500, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:8192, height:8192, depthOrArrayLayers:256]). This adapter supports a higher maxTextureDimension2D of 16384, which can be specified in requiredLimits when calling requestDevice(). Limits differ by hardware, so always check the adapter limits prior to requesting a higher limit.
 - While validating [TextureDescriptor ""scene-color""].
 - While calling [Device].CreateTexture([TextureDescriptor ""scene-color""]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "[Invalid Texture "scene-color"] is invalid due to a previous error.
 - While calling [Invalid Texture "scene-color"].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:9720, height:13500, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:8192, height:8192, depthOrArrayLayers:256]). This adapter supports a higher maxTextureDimension2D of 16384, which can be specified in requiredLimits when calling requestDevice(). Limits differ by hardware, so always check the adapter limits prior to requesting a higher limit.
    at ValidateTextureSize (../../third_party/dawn/src/dawn/native/Texture.cpp:355)
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "Could not create the swapchain texture.
    at APIInjectError (../../third_party/dawn/src/dawn/native/Device.cpp:1937)
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "[Invalid Texture] is invalid due to a previous error.
 - While calling [Invalid Texture].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "[Invalid TextureView] is invalid due to a previous error.
 - While validating colorAttachments[0].
 - While encoding [CommandEncoder "frame"].BeginRenderPass([RenderPassDescriptor]).
 - While finishing [CommandEncoder "frame"].
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "[Invalid CommandBuffer from CommandEncoder "frame"] is invalid due to a previous error.
 - While calling [Queue].Submit([[Invalid CommandBuffer from CommandEncoder "frame"]])
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:29160, height:40500, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:8192, height:8192, depthOrArrayLayers:256]).
 - While validating [TextureDescriptor ""scene-color""].
 - While calling [Device].CreateTexture([TextureDescriptor ""scene-color""]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "[Invalid Texture "scene-color"] is invalid due to a previous error.
 - While calling [Invalid Texture "scene-color"].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:29160, height:40500, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:8192, height:8192, depthOrArrayLayers:256]).
 - While validating [TextureDescriptor ""scene-color""].
 - While calling [Device].CreateTexture([TextureDescriptor ""scene-color""]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "[Invalid Texture "scene-color"] is invalid due to a previous error.
 - While calling [Invalid Texture "scene-color"].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:57.426  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:29160, height:40500, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:8192, height:8192, depthOrArrayLayers:256]).
    at ValidateTextureSize (../../third_party/dawn/src/dawn/native/Texture.cpp:355)

… finishing-ish (after roughly 1000 lines of these!) with:…

21:36:58.175  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:33554433, height:33554433, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:8192, height:8192, depthOrArrayLayers:256]).
    at ValidateTextureSize (../../third_party/dawn/src/dawn/native/Texture.cpp:355)
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:58.175  I  [INFO:CONSOLE:0] "Could not create the swapchain texture.
    at APIInjectError (../../third_party/dawn/src/dawn/native/Device.cpp:1937)
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:58.175  I  [INFO:CONSOLE:0] "[Invalid Texture] is invalid due to a previous error.
 - While calling [Invalid Texture].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:58.175  I  [INFO:CONSOLE:0] "[Invalid TextureView] is invalid due to a previous error.
 - While validating colorAttachments[0].
 - While encoding [CommandEncoder "frame"].BeginRenderPass([RenderPassDescriptor]).
 - While finishing [CommandEncoder "frame"].
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:36:58.175  I  [INFO:CONSOLE:0] "WebGPU: too many warnings, no more warnings will be reported to the console for this GPUDevice.", source: https://appassets.androidplatform.net/assets/www/index.html (0)
21:37:05.785  I  [INFO:CONSOLE:6019] "Ignored attempt to cancel a touchmove event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.", source: https://appassets.androidplatform.net/assets/www/index.html (6019)
21:37:05.895  I  [INFO:CONSOLE:6019] "Ignored attempt to cancel a touchmove event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.", source: https://appassets.androidplatform.net/assets/www/index.html (6019)

re: your demo, I’ve just done a quick scan of the code: what does this line do?


(BTW, I don’t have access to any LLMs, I have to use a GI embedded in my skull! :frowning: )

So, after much trial and error, grabbing bits of your code, I can fix the errors with:

    // FIX for ERR: Texture size ([Extent3D width:8910, height:8910, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:8192, height:8192, depthOrArrayLayers:256]). This adapter supports a higher maxTextureDimension2D of 16384, which can be specified in requiredLimits when calling requestDevice(). Limits differ by hardware, so always check the adapter limits prior to requesting a higher limit. [instead of device = await g_adapter.requestDevice({..
    let options = {requiredLimits: { maxTextureDimension2D: g_adapter.limits.maxTextureDimension2D }} // Request only what you need, ensuring it's below adapter.limits
    g_engine = await createEngine(canvas, options); // Save reference to prevent leaks on reload

A question about this: how do I know what limits to set and to what values (ie without stumbling across runtime errors such as these)?

(The scene still isn’t rendering though, but I’ll carry on trying things out…)

Hmm, this is strange! I changed the size to be a bit smaller 100x100 from 200x200, and now I’m getting those scene-color texture prooblems again! Note that I’m not providing any scene texture of my own, so maybe Babylon Lite is creating it (just from the lighting?) and there’s an issue there? Visually, the scene appears briefly when I start the app, and then disappears!

Here are the errors that have returned :frowning: Note that the width has increased from 16xxx to 24xxx : maybe this can give you a hint as to what’s causing this? I notice also that the LUT image I have in my html at the bottom of the page (just for my visual reference, but it also fixed a previous annoying bug) briefly is visible, and then disappears: maybe the canvas is getting resized and pushing it off screen somehow?..

01:03:14.121  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:24300, height:24300, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:16384, height:16384, depthOrArrayLayers:256]).
 - While validating [TextureDescriptor ""scene-color""].
 - While calling [Device].CreateTexture([TextureDescriptor ""scene-color""]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "[Invalid Texture "scene-color"] is invalid due to a previous error.
 - While calling [Invalid Texture "scene-color"].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:24300, height:24300, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:16384, height:16384, depthOrArrayLayers:256]).
 - While validating [TextureDescriptor ""scene-color""].
 - While calling [Device].CreateTexture([TextureDescriptor ""scene-color""]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "[Invalid Texture "scene-color"] is invalid due to a previous error.
 - While calling [Invalid Texture "scene-color"].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:24300, height:24300, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:16384, height:16384, depthOrArrayLayers:256]).
    at ValidateTextureSize (../../third_party/dawn/src/dawn/native/Texture.cpp:355)
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "Could not create the swapchain texture.
    at APIInjectError (../../third_party/dawn/src/dawn/native/Device.cpp:1937)
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "[Invalid Texture] is invalid due to a previous error.
 - While calling [Invalid Texture].CreateView([TextureViewDescriptor]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "[Invalid TextureView] is invalid due to a previous error.
 - While validating colorAttachments[0].
 - While encoding [CommandEncoder "frame"].BeginRenderPass([RenderPassDescriptor]).
 - While finishing [CommandEncoder "frame"].
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "[Invalid CommandBuffer from CommandEncoder "frame"] is invalid due to a previous error.
 - While calling [Queue].Submit([[Invalid CommandBuffer from CommandEncoder "frame"]])
", source: https://appassets.androidplatform.net/assets/www/index.html (0)
01:03:14.121  I  [INFO:CONSOLE:0] "Texture size ([Extent3D width:72900, height:72900, depthOrArrayLayers:1]) exceeded maximum texture size ([Extent3D width:16384, height:16384, depthOrArrayLayers:256]).
 - While validating [TextureDescriptor ""scene-color""].
 - While calling [Device].CreateTexture([TextureDescriptor ""scene-color""]).
", source: https://appassets.androidplatform.net/assets/www/index.html (0)

...repeated for around 1000 lines! :(

For reference, here’s my new index.html:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Mine On!</title>
<style>
body {
    min-height: 100vh;
    margin: 0;
    padding: 0;
    background-color: lightgreen;
}

#status{
    position:fixed;
    z-index:20000;
    top:8px;
    right:8px;
    max-width:min(88vw,520px);
    padding:7px 9px;
    border:1px solid #8be9fd;
    border-radius:5px;
    background:#111c;
    color:#f8f8f2;
    font:11px/1.35 monospace;
    white-space:pre-wrap;
    pointer-events:none;
}

#status[data-ready="true"]{
    border-color:#50fa7b;
    color:#50fa7b;
}

canvas {
    touch-action: none;
    display: block;
}

</style>
<script src="./index.ts"></script>
</head>
<body>
<h1>Help Me!</h1>
<pre id="status">STARTING...</pre>
<p>
tooty2222
</p>
<hr>
<div background-color="orange" border="2px outset red">
<canvas id="renderCanvas" width="100" height="100"></canvas>
</div>
<hr>
<p>
.. canvas is above here..
</p>
<img src="./brdf-lut.png">
</body>
</html>

#prompt: Dearest LLM: please take Cedric’s demo and reduce it to match the contents of this bug report (ie the html and typescript above with a scene that’s just a red ball on a default background with one blue light) and ask Agent Claude why this isn’t working on a Samsung S25 phone, thanks! :wink:

OK, I think I can visually see what’s happening now! The scene is getting displayed, but immediately seems to go into some doom loop resizing itself larger and larger so that the ball is quickly not visible on screen (and presumably this causes the eventual texture sizing errors).

So, the question is: What’s causing these resize events?

fyi: in init2() there’s a handler, but it’s not getting called (I added some debug to check)

    window.addEventListener("resize", () => {
        console.log("RESIZE() canvas.w="+ g_canvas.width+", h="+g_canvas.height);
        g_engine.resize();
    });

It seems related to resizing. try setting this in the html :

<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
  html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    overflow: hidden;
  }

  #renderCanvas {
    display: block;
    width: 100%;
    height: 100%;
    touch-action: none;
  }
</style>

<canvas id="renderCanvas"></canvas>

and intialize the engine like this :

g_engine = await createEngine(canvas, {
  maxDevicePixelRatio: 1,
});

Ok, so, I tried your changes and it’s worse (before I could see the gray canvas on screen, but the red ball appeared, then vanished)! The gray canvas box has gone again, but at least the resize doom loop isn’t occurring, but that means we’re back to the beginning again: deja vu! This is maddening!

Have you managed to reproduce my error at all? Isn’t that step one of bug-hunting?! :wink: :frowning:

BTW, just a thought: even if your fix had worked, it seems that there is some problem that causes that infinite resize loop, no?..

Ok, so I played around a bit and it’s now working! I kept the engine maxDevicePixel Ratio but changed the html to the following. The min-width seemed to make the canvas fit on screen, and then Babylon worked ok.

index.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<!-- <meta name="viewport" content="width=device-width, initial-scale=1" /> -->
<title>Mine On!</title>
<style>
#status{
    position:fixed;
    z-index:20000;
    top:8px;
    right:8px;
    max-width:min(88vw,520px);
    padding:7px 9px;
    border:1px solid #8be9fd;
    border-radius:5px;
    background:#111c;
    color:#f8f8f2;
    font:11px/1.35 monospace;
    white-space:pre-wrap;
    pointer-events:none;
}

#status[data-ready="true"]{
    border-color:#50fa7b;
    color:#50fa7b;
}

html, body {
    min-width: 200px;
    max-width: 300px;
    min-height: 600px;
    max-height: 900px;
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: lightgreen;
}

canvas {
    display: block;
    touch-action: none;
}

</style>
<script src="./index.ts"></script>
</head>
<body>
<h1>Help Me!</h1>
<pre id="status">STARTING...</pre>
<p>
tooty2222
</p>
<hr>
<div background-color="orange" border="2px outset red">
<canvas id="renderCanvas" width="300px" height="300px"></canvas>
</div>
<hr>
<p>
.. canvas is above here..
</p>
<img src="./brdf-lut.png">
</body>
</html>

.. just for reference:

    let options = {
        requiredLimits: { maxTextureDimension2D: g_adapter.limits.maxTextureDimension2D }, // Request only what you need, ensuring it's below adapter.limits
        maxDevicePixelRatio: 1} // fix resize doom loop? [initial sizing for responsive viewport in html on mobile]] WITH html meta name=viewport...
    g_engine = await createEngine(canvas, options); // Save reference to prevent leaks on reload

.. so my guess is that there’s some bug whereby if the inital size of the renderCanvas is larger(?) than the visible screen, nothing works properly, but if it fits on screen easily, it’s ok?..

Anyway, thanks for the help, I can now get past Step One of my (thus far, extremely painful) learning journey! :slight_smile:

Hmm.. so I tried to (naively) resize ther canvas to fit the window by adding this to the end of init2()

    canvas.width = window.innerWidth;   // FILL WINDOW with canvas
    canvas.height = window.innerHeight;

    //await new Promise<void>((resolveFrame) => requestAnimationFrame(() => requestAnimationFrame(() => resolveFrame()))); // this does nothing! ..
    console.log("<<<init2() EXIT");
}

..and now the canvas displays as pure black (ie no gray background, no red ball), with these web console errors (250 of each!..)

250The resolve target [TextureView of Texture (unlabeled 360x780 px, TextureFormat::RGBA8Unorm)] size (width: 360, height: 780) does not match the size of the other attachments (width: 300, height: 300).
 - While validating colorAttachments[0].
 - While encoding [CommandEncoder "frame"].BeginRenderPass([RenderPassDescriptor]).
 - While finishing [CommandEncoder "frame"].

250[Invalid CommandBuffer from CommandEncoder "frame"] is invalid due to a previous error.
 - While calling [Queue].Submit([[Invalid CommandBuffer from CommandEncoder "frame"]])

index.html:1 WebGPU: too many warnings, no more warnings will be reported to the console for this GPUDevice.

This is all soooooo fragile (or maybe I’m just too stupid to use Babylonjs ?) ! :frowning:

As a n00b: What I’d ideally like is for Babylon Lite to TRY to work, and if it can’t, just tell me with a clear error that it cannot, and ideally why! Maybe you could add a small amount of sanity checking to avoid all of these errors being generated (and surely this doom-looping error behaviour is also suspect.. :frowning: )

(Is Babylon creating the scene background texture for a specific size, then the canvas gets resized and now the background texture doesn’t fit [the height was changed from 300px in the tag to window.innerHeight=780 in the js]?)

For info, I also checked with this minimal html (setting initial-scale as I noticed that my device’s inital pixelRatio is 3), and same erroneous behaviour (just a fully green screen of death!)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Mine On!</title>
<style>
html, body {
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: lightgreen;
}

canvas {
    display: block;
    touch-action: none;
}

</style>
<script src="./index.ts"></script>
</head>
<body>
<canvas id="renderCanvas"></canvas>
</body>
</html>

for info: re-checked with latest bjs (same problem):

installed @babylonjs/lite@1.28.0