dotrix icon indicating copy to clipboard operation
dotrix copied to clipboard

Voxels and SDF

Open QuantumEntangledAndy opened this issue 4 years ago • 21 comments

WIP Voxels

This is my in progress voxel implementation.

Design

  • Voxel crate
  • grid and voxel .rs hold the generic design of the voxel, it is kept separate from its potential uses
    • Has two values per voxel one for density and another for material ID
      • These are stored in the 3D texture at the R and G channels
  • sdf/* holds components to compute the SDF of the voxel and render that SDF

Future Additions

  • Add a marching_cubes/* to compute the marching cubes representation

QuantumEntangledAndy avatar Feb 10 '22 03:02 QuantumEntangledAndy

Thought I'd post an update to show how it is currently working.

Currently

Not yet

  • Materials and textures

Changes to Core

Here are some of the changes to core that I added to get everything working

  • Required changes
    • Add Texture3D and its bindings
    • Add TextureArray and its bindings
    • Use correct sample methods when binding integer textures
  • Optional changes
    • Add MAP buffer for reading gpu buffers to the CPU
    • Add copy methods for copying a texture to a buffer on the gpu
      • Combined with the MAP buffer it makes it possible to read textures from the gpu (I used this for debugging)

Video

(Jerkiness is mostly due to how I am capturing the video)

https://user-images.githubusercontent.com/13386481/158739540-10f68287-2c47-483e-a58e-6c9bcd44107a.mp4

QuantumEntangledAndy avatar Mar 17 '22 04:03 QuantumEntangledAndy

I can not compile it with latest rust:

error[E0658]: destructuring assignments are unstable
   --> dotrix_voxel/src/sdf/jump_flood.rs:379:48
    |
379 |                     (ping_buffer, pong_buffer) = (pong_buffer, ping_buffer);
    |                     -------------------------- ^
    |                     |
    |                     cannot assign to this expression
    |
    = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information

voxelias avatar Mar 17 '22 08:03 voxelias

I can not compile it with latest rust:

error[E0658]: destructuring assignments are unstable
   --> dotrix_voxel/src/sdf/jump_flood.rs:379:48
    |
379 |                     (ping_buffer, pong_buffer) = (pong_buffer, ping_buffer);
    |                     -------------------------- ^
    |                     |
    |                     cannot assign to this expression
    |
    = note: see issue #71126 <https://github.com/rust-lang/rust/issues/71126> for more information

Hmm I thought this was now in stable with the merge of this https://github.com/rust-lang/rust/pull/90521

Perhaps I misunderstood. I can probably do it with a three way swap instead but it's not as pretty

QuantumEntangledAndy avatar Mar 17 '22 08:03 QuantumEntangledAndy

Destructuring assignments were stabalized on 15 Dec 2021 so perhaps we should bump up our version of stable rust

QuantumEntangledAndy avatar Mar 17 '22 08:03 QuantumEntangledAndy

Just to confirm I updated my rust with rustup to current stable stable-x86_64-apple-darwin unchanged - rustc 1.59.0 (9d1b2106e 2022-02-23) and it compiles and runs fine

QuantumEntangledAndy avatar Mar 17 '22 09:03 QuantumEntangledAndy

Yeah, I had a default setting to 1.57. But now It panics on linux with Intel Iris XE card.

MESA-INTEL: warning: Performance support disabled, consider sysctl dev.i915.perf_stream_paranoid=0

Voxels: [[[0, 0, 1], [1, 1, 1], [1, 1, 0]], [[1, 1, 1], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [1, 1, 1], [1, 0, 0]]]
Compute Seed
Compute JumpFlood: n=12, k=8
Compute JumpFlood: n=12, k=4
Compute JumpFlood: n=12, k=2
Compute JumpFlood: n=12, k=1
Compute JumpFlood: n=12, k=1
Compute JumpFlood: n=12, k=2
Compute JumpFlood: n=12, k=4
Compute JumpFlood: n=12, k=8
Compute DF
thread 'main' panicked at 'not implemented', /home/elias/.cargo/registry/src/github.com-1ecc6299db9ec823/naga-0.8.0/src/back/spv/block.rs:347:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

voxelias avatar Mar 18 '22 08:03 voxelias

Interesting it is panicing in naga, might need to see the backtrace to find out what is not implemented.

QuantumEntangledAndy avatar Mar 18 '22 08:03 QuantumEntangledAndy

spv/block.rs around line 347 is this

crate::BinaryOperator::Add => match *left_ty_inner {
    crate::TypeInner::Scalar { kind, .. }
    | crate::TypeInner::Vector { kind, .. } => match kind {
        crate::ScalarKind::Float => spirv::Op::FAdd,
        _ => spirv::Op::IAdd,
    },
    _ => unimplemented!(),
}

Apparently one of the add operations in the shader is not supported, perhaps something is more relaxed on metal when not converting to spv. Do you know which shader file this is? I can try and run naga-cli to cross-compile to spv and trace it down that way.

QuantumEntangledAndy avatar Mar 18 '22 08:03 QuantumEntangledAndy

So I ran cargo install naga-cli and then naga my_shader.wgsl my_shader.spv and I can get the same error for the dotrix_voxel/src/sdf/circle_trace/render.wgsl file. The other wgsl's seem fine

QuantumEntangledAndy avatar Mar 18 '22 08:03 QuantumEntangledAndy

Perhaps we should add some sort of naga-cli test into the github actions

QuantumEntangledAndy avatar Mar 18 '22 08:03 QuantumEntangledAndy

So I commented out lines in the render.wgsl until I found that R = I + sx + sx * sx * (1./(1. + c)); on line 336 is causing issues. Will try to fidn out why

QuantumEntangledAndy avatar Mar 18 '22 08:03 QuantumEntangledAndy

It is failing to add mat3x3<f32> with another mat3x3<f32>. This might be an upstream issue

QuantumEntangledAndy avatar Mar 18 '22 09:03 QuantumEntangledAndy

Yes here is the upstream issue https://github.com/gfx-rs/naga/issues/1527

QuantumEntangledAndy avatar Mar 18 '22 09:03 QuantumEntangledAndy

I have a workaround in place

QuantumEntangledAndy avatar Mar 18 '22 09:03 QuantumEntangledAndy

Great, I can run it now, I will make a review...

voxelias avatar Mar 23 '22 15:03 voxelias

Sure just remember that it's still wip. I know it needs a clean up and that the light system needs to be tied into the main lights system.

QuantumEntangledAndy avatar Mar 24 '22 00:03 QuantumEntangledAndy

Things that I still want to do:

  • Use lights in core
  • Handle case when camera is inside render box
  • handle live edits to the voxel
  • seperate render into multiple wgsl/do render in multiple passes

If you can find any high level changes you want that would be more useful then a full review.

QuantumEntangledAndy avatar Mar 24 '22 00:03 QuantumEntangledAndy

Yeah I understand I really want to work on this more too but I haven't the time either.

The algorithm at its core is:

  • March a ray from the camera for each pixel
  • use the sdf to estimate how far to march the ray in each iteration
  • stop marching when we hit a surface then Color in the pixel with the point the ray hit

Additional algorithms:

Shadows

  • From each point found from the ray march
  • march a new ray towards each light.
  • If we hit an object before the light then we are in shadow
  • if we almost hit an object before a light we are in partial shadow (pure crisp shadows only happen in space because of the way light diffuse through air)

Ambient occlusions

  • From the point a ray hits
  • march n more rays in a hemisphere from the contact point
  • if we hit (or come close) to another object we are occluded

QuantumEntangledAndy avatar Apr 11 '22 07:04 QuantumEntangledAndy

Here is it with materials now :)

https://user-images.githubusercontent.com/13386481/164591468-e87543e0-3bf5-404c-9d9f-2422115226ef.mp4

QuantumEntangledAndy avatar Apr 22 '22 03:04 QuantumEntangledAndy

So cool! Have you though about how this functionality can be used for terrain spitted into chunks with loading/unloading? Meanwhile I've extended Texture module a bit and added possibility to render image and depth buffer to textures in #161. As a result I plan to implement shadows there.

voxelias avatar Apr 22 '22 10:04 voxelias

Yes I'm going to optimise this as best I can. (Will probably use that render to texture to render shadows and ao in a different pass) Then I'll doing some terrain with it.

There are some bigger hurdles with terrains as the render speed decreases the more rays need to be marched and terrain takes up the whole screen.

When that's working I plan to take on dynamic clouds you can do some great looking clouds with volumetric rendering techniques.

QuantumEntangledAndy avatar Apr 22 '22 10:04 QuantumEntangledAndy