Bevy-Rust-GPU / rust-gpu-sdf

Signed distance field library usable on both CPU and GPU.
Apache License 2.0
12 stars 1 forks source link

Investigate possibility of a custom 'flipped depth' prepass in bevy #15

Open Shfty opened 1 year ago

Shfty commented 1 year ago

Since rasterized depth can be used as a free start / end distance for raymarching, using prepasses to make both front-side and back-side depth available would ensure maximum performance regardless of whether the camera is inside or outside a given SDF's bounding mesh. (Prepass perf overhead notwithstanding.)

Shfty commented 1 year ago

This may be achievable without a custom prepass - since separate shaders can be specified for the main pass and prepass, using a vertex shader to flip normals in one of them would allow use of rasterized fragment depth in conjunction with the pre-rendered (flipped) depth texture.

In which case, would probably have to switch to front-face culling instead of no culling; ensures backsides are always available while allowing a vertex shader to control visibility via flip.

Shfty commented 1 year ago

Also worth investigating prepass / shadow interaction; may be a route to making SDFs cast shadows.

Shfty commented 1 year ago

Access to the depth prepass texture from Rust shaders is blocked on a combination of limited rust-gpu support for OpImageFetch * * * Sample * (needs to be manually emitted via asm!), and what appears to be a naga bug:

Required coordinate type should have been set up by 'parse_type_image'!
Shfty commented 1 year ago

Might be able to work around this similarly to uniform vs storage buffers - i.e. by forcing bevy to use a simpler depth texture format.

Shfty commented 1 year ago

Ended up being a naga bug - patching SPIR-V passthrough into bevy results in correct behaviour.

However, the flipped-depth operation is not achievable without a custom prepass, or specialized vertex shader logic that isn't general enough for the use case. Reprojection code is in place for when this becomes available, but a working implementation will have to wait on upstream.