Thin instances don't render in the depth buffer - part 2, the instances attack again

Bug: the gbuffer depth texture only includes the thin instances when mesh.freezeWorldMatrix() is called. This might be related to gBuffer doesn't handle thin instances properly (whose fix is still working, so it was not a regression).

“Please, bruno, tell me that you made a PG this time that reproduces your weird bug”. Well, I got a PG that DOES NOT reproduce it :smiley: does not reproduce it, but is as close as I could get to real code and it works perfectly well. I also tested disabling autoClear, which is commented out in the PG but didn’t reproduce the bug either.

But I made a “ok it’s not a PG sorry but it reproduces the bug and I removed all unnecessary code” branch. All the babylon code is at lajevr/Underwaterb.vue at gbuffer-bug · Corollarium/lajevr · GitHub, and this line fixes the issue if it’s uncommented. Fish might not be immediately viewable if you run the code, just rotate the mouse and you’ll see them.

Screenshot showing only the thin instances, and that they are not in the gbuffer depth texture:


cc @CraigFeldspar / @Evgeni_Popov

Unfortunately the repo does not work in Windows, I get this error when doing yarn dev:


The error message means "NUXT_HOST" is not recognized as an internal or external command, nor as an executable program or a command file.

a quick fix is to add “cross-env”: “latest” to devDependencies (or install globally) and then change any npm task starting with “NUXT_HOST…” to “cross-env NUXT_HOST …”.

Not related, but probably generally helpful, I have to do this all the time for scripts that use NODE_ENV

I have installed cross-env but could not see any occurrences of NUXT_HOST in the source code of the repo.

Its part of the npm script, all its doing is setting an environment variable. You could actually delete it probably. Chrome on windows sometimes doesnt open as localhost , it seems to change version to version.

Sorry, I don’t use windows. NUXT_HOST is an environment variable. I think you can ignore it and just run nuxt, it’s there to accept connections from external hosts instead of binding to localhost.

I can also publish a test page on the public site. But it’ll be compiled in production mode, so crappy traces. Is that helpful?

I think it could be helpful for evgeni and others on windows that arent so familiar with the node ecosystem. On windows, to set env variables you have to prefix it with set , for ex “dev”: “set NUXT_HOST …”. The cross-env cli tool just makes it work on both linux and windows consistently.

What, how can you people write Typescript and not use node and those awful JS builders? I miss just adding <script> so much! How can you live without webpack and babel and where do I sign to do the same? :smiley:

Sorry, I thought this would be trivial to build in any platform. Laje de Santos em Realidade Virtual is online now. Fish around you are generated randomly, so please rotate the camera if they’re not immediately visible.

1 Like

I think most people just rely on others to provide a working build. Thats good tbh, webpack has killed enough brain cells as it is


incredible photos @brunobg . i’m a Rescue Diver, but never been to Brazil - thanks for sharing. Cool website - really enjoyed reading the technical page and also impressive what you did with caustics. This is one of my favourite webgl articles on caustics even though it was made >10 years ago:
Rendering Realtime Caustics in WebGL | by Evan Wallace | Medium

ps: All of my vue is vue3 and in TypeScript. It’s a great way to work with Vetur and once you get past a learning curve!

Thank you @brianzinn! I have a ton of other photos and videos to upload, but haven’t had time to process them yet. Brazil has some nice dive spots, and this one has some sentimental value because it took part in the earliest days of diving here, as well as becoming the first marine park.

Thank you! I’ll update that page very soon. The new material plugins made caustics much easier and faster to do, and avoids a second render per frame.

I love Vue, but that build stuff is always awful. JS somehow managed to become a dynamic compiled language :smiley:

1 Like

It’s a problem with the world matrix passed by the geometry buffer renderer, which is (1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1) whereas the one used for the regular display of the fishes is (1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1).

There has been some changes lately on skeleton/effective mesh handling in Babylon.js code, you should try to use the very latest version of 5.0 and see if that helps (but make sure this PR is in: Fix issue with glTF skeletons by bghgary · Pull Request #11919 · BabylonJS/Babylon.js · GitHub - I think @sebavan will know).

I tried to reproduce the bug in but it does work there (it does not work in 4.2.1 because the geometry buffer renderer did not handle thin instances at all in that version).

1 Like

Thank you. As soon as a new release goes out with this patch I’ll try it and update here.

1 Like


When i lived in okinawa i snorkled all the time. Never seen anything like that omg


Yup might totally be related to what @Evgeni_Popov highlighted @brunobg keep us posted with what you find.

I just tried it with beta-11 and it doesn’t seem fixed. “seem” because there may be a separate regression where models are not rendered at the same place as in beta-5, although the issues might be linked.

First, short digression that may help to pinpoint the problem given @Evgeni_Popov 's answer about the world matrix. I’m fixing some weird model issues (glb exported from Blender has negative scaling in one axis and some bizarre base rotation) manually:

    const baseMesh = loadedMeshes[0]; // assumes __root__ is zero
    const mainMesh = loadedMeshes[1];

    // reset weird scaling
    baseMesh.scaling.z = 1;
    baseMesh.scaling.y = 1;
    baseMesh.scaling.x = 1;
    baseMesh.rotationQuaternion.y = 0;

    // reset base quaternion
    mainMesh.parent.rotationQuaternion.x = 1.0;
    mainMesh.parent.rotationQuaternion.y = 0.0;
    mainMesh.parent.rotationQuaternion.z = 0.0;
    mainMesh.parent.rotationQuaternion.w = 0.0;

I didn’t bother to understand why this is happening on the export since this “reset” works, but this probably explains the discrepancy of the matrices. In fact, the freezeWorldMatrix() from the original report is even weirder, since I’m making these updated after that call. But with this code and beta-5 the instances are rendered in world coordinates as expected:

    new BABYLON.Vector3(1, 1, 1),
    orientation, // some quaternion
    boid.position, // in world coordinates
m.copyToArray(bufferMatrices, i * 16);

With beta-11 this doesn’t happen anymore. And this doesn’t happen only with instances, another model that I load (loadTurtle in the Github code) and apply the same reset is rendered at a completely different location with beta-11 compared to beta-5.

BTW, is there some easy way to run the online PG with a previous alpha/beta version? It would make it easier to show this regression.

@bghgary anything that comes to mind ?

Note that the identity quaternion is (0,0,0,1), not (1,0,0,0). wrt:

    // reset base quaternion
    mainMesh.parent.rotationQuaternion.x = 1.0;
    mainMesh.parent.rotationQuaternion.y = 0.0;
    mainMesh.parent.rotationQuaternion.z = 0.0;
    mainMesh.parent.rotationQuaternion.w = 0.0;

Resetting this is also removing the right-hand to left-hand conversion. Are you sure this is what you want?