-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Single-pass IBL shadow voxelization for WebGPU #17270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Single-pass IBL shadow voxelization for WebGPU #17270
Conversation
Please make sure to label your PR with "bug", "new feature" or "breaking change" label(s). |
Snapshot stored with reference name: Test environment: To test a playground add it to the URL, for example: https://snapshots-cvgtc2eugrd3cgfd.z01.azurefd.net/refs/pull/17270/merge/index.html#WGZLGJ#4600 Links to test babylon tools with this snapshot: https://playground.babylonjs.com/?snapshot=refs/pull/17270/merge To test the snapshot in the playground with a playground ID add it after the snapshot query string: https://playground.babylonjs.com/?snapshot=refs/pull/17270/merge#BCU1XR#0 |
WebGL2 visualization test reporter: |
Devhost visualization test reporter: |
Visualization tests for WebGPU |
In a real-world scenario, I think we would let the user decide when to update the voxelization (meshes can also be moved without using animation, a custom vertex shader can apply deformation, etc.). But for a test PG, I think this is fine. Let us know when the PR is ready for review! |
2111655
to
4775e9e
Compare
Devhost visualization test reporter: |
Visualization tests for WebGPU |
WebGL2 visualization test reporter: |
if (this._engine.isWebGPU) { | ||
// Clear the voxel grid storage texture. | ||
// Need to clear each layer individually. | ||
// Would a compute shader be faster here to clear all layers in one go? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
#ifdef MORPHTARGETS_POSITION | ||
#ifdef USE_VERTEX_PULLING | ||
positionUpdated = positionUpdated + (readVector3FromRawSampler(i, vertexID) - inputPosition) * uniforms.morphTargetInfluences[i]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change ties morphTargetsVertex.fx
too closely to iblVoxelGrid.vertex.fx
, because inputPosition is defined in the latter file, and we don't yet know how we're going to handle vertex pulling for our standard materials. In the meantime, check out my suggestion in iblVoxelGrid.vertex.fx
to work around this issue.
|
||
varying vNormalizedPosition : vec3f; | ||
flat varying f_swizzle: i32; | ||
varying vNormal : vec3f; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this declaration, as vNormal
is not used.
|
||
#include <morphTargetsVertexGlobal> | ||
let inputPosition: vec3f = positionUpdated; | ||
#include <morphTargetsVertex>[0..maxSimultaneousMorphTargets] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of updating morphTargetsVertex.fx
, you can modify this declaration as follows:
#include <morphTargetsVertex>("vertexInputs.position),inputPosition)")[0..maxSimultaneousMorphTargets]
This should (not tested!) replace the two occurrences of vertexInputs.position)
with inputPosition)
, which will allow you to achieve the desired result without using inputPosition in morphTargetsVertex.fx
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Popov72 The code, as given, has syntax errors in it (two ')' brackets without matching '('). However, I can't find examples of the expected syntax for this. Are there existing places in the code where this type of substitution happens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's on purpose :)
In the #include<XXX>("YYYY")
syntax, the YYY part is a simple find and replace mechanism, where YYYY has this format: find1,replace1,find2,replace2,etc
.
So, what I did is to replace vertexInputs.position)
with inputPosition)
. I put the closing parenthesis in the string, else it does a replacement for an additional occurrence (vertexInputs.position{X}
) that we don't want to update.
We use this syntax a lot in the PBR/OpenPBR/standard vertex shaders:
This changes the voxelization strategy for WebGPU to allow it to be done in a single pass (though, generation of mips still takes additional steps). This is possible using
textureStore
to write to arbitrary texels in a 3D texture. It also uses vertex pulling to correctly determine the provoking vertex for each triangle and retrieve adjacent vertices so that we can calculate the triangle's normal. This is used to swizzle the xyz components to maximize the rasterized area and not miss voxels.Anywho, this makes updating shadows for animated meshes much more plausible. I'm not sure the best way to do this but currently, in my playground, I'm doing this:
Is there a better way to query whether there is currently an animation happening?