Path-tracing in BabylonJS

Well, I found the wood texture in the materials list and it has an UID number on the left side panel:

At least I know it’s there somewhere inside Babylon. The issue now is, I can’t get at it programmatically or with function calls from the browser console. Do you guys know how Babylon stores textures such as these (that are not specified as images, but rather binary data)? And is it possible then to send these over as a GPU texture sampler2d somehow? It looks like it has dimensions of 256x256.

You should be able to reuse the texture directly to find the material using it, select the mesh with would and you could then scene.getMaterialById("").albedoTexture

1 Like

Ahh ok thank you - I didn’t know about the scene.getMaterialById() function. Will attempt to get closer to the solution!

1 Like

The PG intellisense shows this method as being deprecated - what should folks use instead?

This was due to a typo a while back… getMaterialById is the one to use, please note the smaller case d at the end :slight_smile:

2 Likes

Subtle, yet important difference!

This will help little by little to shrink the bundle size.

1 Like

Hey @Valentine

Sorry for the delay - here’s the promised RTX 3090 debug demo for you:
RTX 3090 Debugging Demo

It starts off at 0.1 pixel resolution. If you can make it that far without crashing, please let us know when you start sliding up the resolution value, at what resolution it crashes.

This is all assuming that resolution has anything to do with the 3090 crashing problem.

I am also using a 3090. I can confirm that the demo crashes. But I am not even able to play with the pixel resolution. It crashes immediately after opening the link.

2 Likes

Ok thank you for the report. I am going to change the demo slightly to begin with a different model, but still have the bookshelf selectable in the drop-down GUI list of models.

Now I’m thinking that it has something to do with BVH, either creation of the data texture, or later walking through the tree on the GPU when ray casting.

My algorithm builds up the binary structure using a floating-point spatial median scheme (AABB dimensions * 0.5). It has a fallback just in case the floating-point median divider isn’t able to split the box into 2 smaller boxes. The fallback is an object-count median (splitting by placing 1 triangle in box A, the next in box B, the next in box A, box B, until everything is resolved.

Since there might be a lot of overlapping or very close edges in the bookshelf model, both median splitting strategies (spatial splitting and object-count splitting) might be getting tripped up, and possibly handing the 3090 a faulty BVH data texture, which in turn will cause the GPU to crash because the BVH traversal code has an infinite while(stackPointer >= 0) loop until the tree is traversed, causing the break from the loop.

Back with another test demo for 3090 users:

3090 debugging demo (begins with Utah Teapot)

Please cycle through all the available models - I put the bookshelf last. If you don’t see the model at all and it crashes upon bookshelf model selection, it means the BVH creator is getting stumped (probably with floating point precision spatial split, AABB dimensions, etc. discrepancies between your CPU and the beefy GPU).

If you see the model show up for a brief moment, but then it freezes and the context is lost and then everything crashes, it could be the shader (possibly with the material assignment troubles we’ve been having with this particular model lately). It may be the fault of the BVH traversal loop, rather than the BVH creator in this latter case.

I can load all models without any problems including the book case. No crash, no freeze, …

But increasing the pixel resolution leads to veeeery slow samples regardless of the model.

The previous demos were fine and very fast. I even thought about setting the pixel resolution above 1 but that’s not possible here :grinning:

EDIT:

I just checked the other demos from the github rep. Same problem for them. Also for the three.js demos. Weird.

2 Likes

@samevision
Thanks so much for your continued reports.

Man…I was hoping to narrow the scope of the problem down to a manageable size, but your most recent findings indicate that this is a global problem for the 3090 (and Chrome?) for all path tracing and all demos.

To quote many TV detectives, the offenders might be out of my jurisdiction on this one, lol. If this is indeed happening on all demos with all 3090s with all instances of Chrome, I’m not sure where to turn to.

I’m still hoping that @Valentine can confirm these findings with his setup. Then we can decide what the plan should be moving forward.

It’s not impossible that it is Chrome’s fault- about 5 years ago I actually filed a bug report with their team because my mobile camera controlling code was all janky all of a sudden. It was fine and smooth one day, choppy and jittery the next. I didn’t change a single character of code for months on that file either - it was just sitting there on GitHub. Anyway, the next release- magically starting working again, ha. :slight_smile:

1 Like

Your intention was right. I tested the latest debug demo with firefox. It’s really fast and looks nice. Also with the book case. It looks much better than everything I have seen in Chrome.

2 Likes

Unlike @samevision even at 0.1 pixel res it crashes on the bookshelf for me. The other models all work fine. Since my screens freeze up when it crashes, I could see it crashed after like 13-15 samples (I can’t remember the exact number). The bookshelf did load and appear on the screen, but it was like a quarter second in that crashed.

2 Likes

And the plot thickens, ha. Thanks for the update @Valentine . Once again this 3090 bug is escaping my attempts to corner it. Although I will say that the fact that you actually saw the bookshelf, even for a brief second before crashing, does give some comfort that at least the BVH builder has successfully parsed the triangles and created bounding boxes and tree, then has passed everything to the 3090.

In the early days of me trying to implement the BVH creator, it wouldn’t even get to the data texture stage (where it hands it off to your GPU) because it was spinning its wheels on the JS side due to errors in my construction process. The webpage would just crash without showing any console errors. So I was worried about your initial reports of not displaying anything and crashing, but at least it is getting to the GPU stage.

At this point, it might be something with Chrome’s WebGL2 implementation, or a conflict with their browser and your GPU drivers.

2 Likes

Hello all,

So sorry for the lack of updates on this glTF bookcase texture loading problem. I have been very busy with other random life commitments, but now I am back on the job!

Today I did some investigating into this issue of the textures of the bookcase model not being ‘seen’ by the path tracer on the GPU.

The good news is that I know what the initial problem was now. The bad news is that I’m not entirely sure how to solve the remaining problems yet. And it looks like the solution will require a lot of new plumbing.

So here’s what I understand so far:

The reason my path tracer couldn’t ‘see’ the wood textures and other textures included in the glTF bookcase model was because, unlike the damaged helmet glTF model, the bookcase model doesn’t have 1 large overarching albedo color texture. My texture checks fail if material.albedoTexture is not found for the entire model. If you look at the damaged helmet albedo texture (the actual image saved on disk/server) for instance, you’ll see that the modeling program nicely packed all the model pieces/components and their associated color textures into 1 large texture atlas:
albedo texture atlas for all model’s components

This is then specified as the material.albedoTexture, which is therefore no longer ‘null’, and passes my texture checks in the loading section. As long as your glTF model has an ‘atlas’ type texture system (not only for the albedo, but also the bump/normal, emissive, metallicRoughness, etc.), we should be ok. All your textures will have a similar size and ‘look’ to them, because the model only has 1 set of texture uv’s to use when looking up various texture data from the shader with a sampler2d, something like:
vec3 color = texture(uAlbedoTextureAtlas, uv).rgb.

However, the bookcase model does not have an overarching master texture atlas system. Instead, it is presented in a modular system consisting of no less then 150 separate meshes (components/pieces), each with their own material, texture, and triangle uv data! Now, granted the same wood texture might be assigned to 30 of the 150 pieces, but you can start to see why I’m sweating :sweat_smile:.

I have found at least the initial source of the problem: I was merging all 150 meshes into 1 giant mesh too soon - all the unique material data gets lost as soon as I do this. Then my checks fail of course because ‘material.albedoTexture’ for this new behemoth model is null: there is no nice packed texture atlas for all the pieces of the model. The model therefore shows up as all white by the time it gets to the path tracing shader. And in case you’re wondering, yes, in order for the path tracing ray caster not to crash, all models do in fact need to be merged into 1 giant mesh, for BVH reasons that we discussed earlier.

To combat this problem, I tried intercepting the load routine and cherry picking 1 small mesh (out of 150 possible mesh component choices), then seeing what I could see. Finally I could get to some of the data. If you try this updated example, open up the browser console and take a look:

bookcase model with 1 texture successful

At least we have 1 wooden texture applied (to the whole model, but it’s a start). In the console,
I can see the material Id, the fact that albedoTexture is not null (yay), the lengthy url of that texture, and the actual _buffer data. The _buffer data looks like 0-255 RGBA data that is intact, but I’m confused at the length of the flat array, which should be around the 200,000 elements range (256w × 256h x 4 channels), and instead consists of only 67,000 or so elements. I may be interpreting this incorrectly though.

But in any case, if this modular model component indeed has an albedoTexture, I should be able to send that over to the GPU as a texture uniform like I have been doing with other models. However, this plan works for just 1 mesh out of 150 (lol), so I’m assuming that we would need a system that looked for unique textures while loading. If 30 shelves use the same wood texture, we don’t send it 30 times over to the GPU as 30 textures, but rather mark the triangles of that component model piece with some sort of enumerator or unique texture id counter, that then must be dealt with inside the path tracing shader. I’m imagining something like
vec3 color = texture(uniqueAlbedoTextures[hitTriangle.albedoId], hitTriangle.uv);

The albedoId element number above could be any number up until the max texture units of your GPU I suppose (32?) - not sure what the max limit is these days, ha. For instance, the total unique material textures count for the bookcase model might be around 8. Therefore, an array of texture uniforms [8] needs to be sent once to the GPU during startup, then hopefully the triangle data texture lookup will tell us which of the 8 textures we need to sample while intersecting the model in the shader raycaster.

Like I mentioned, this is going to require a significant amount of new code to handle these situations, but at least I can see the light at the end of the tunnel. Also, we will reap the benefits of our new system because any arbitrary scene, no matter how many triangles, or how many different meshes/parts and textures, will be able to be squashed into 1 giant bvh mesh, path traced in real time, all while retaining the material data that was captured for each individual component at loading time. The only case where this wouldn’t quite work is if the original glTF has moving parts or animations. But if it’s a static scene, this ability will open up a lot of new doors for end users!

3 Likes

ps. BTW, I think I used the term ‘atlas’ incorrectly in the above post. Now that I think of it, this process of expanding the pieces of the model and making everything fit into a flat 2d surface is called “uv unwrapping” - I think. Sorry for the terminology mix-up! :slight_smile:

I think texture array is in a compressed format as binary jpeg. It’s not raw data like tga or bmp format. So it’s impossible to count anything before decompressing data
Hope that helps

1 Like

@pcarret
Ahh ok, that makes more sense. Thanks! :slight_smile: