You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm afraid this may be a noobie question given how common this use case must be, but for the same reason I figured it would be an easy question for some wgpu gurus.
What's the best practice for updating per-draw uniform data? In particular, I really just want to pass a 4x4 transformation matrix for each draw call.
Some possibilities:
Tutorial here suggests that using a staging buffer is the way to go, but this path involves creating a new staging buffer for each draw, which seems kind of expensive. But if a second person were to tell me that this is the way to go, I'd be happy to accept this for the time being.
Push constants: I think this would be exactly what I'd want if it were available, but thread here seems to suggest it might not be available anytime soon...
The same thread above suggests dynamic offsets as a workaround. I might not be understanding this correctly, but it's not clear to me how changing offsets into the buffer will allow me to pass in arbitrary 4x4 matrices to my shaders.
I've also come across this which compares push-constants with mapped buffers. I would guess that this would be like using the Buffer::map_read/map_write methods? I was kind of hoping to avoid them if I could for now, because of the situation with event loops described in the docs, but if someone tells me that that's the recommended way to do this, I might try it anyway.
Are any of the above possibilities the recommended way to update per-draw data with wgpu today?
Are there other better ways to update per-draw uniform data?
The text was updated successfully, but these errors were encountered:
That's a great question! It comes up regularly, and there is a reason for it - WebGPU doesn't offer a solution that would be obvious to use. The closest thing you can get to an obvious solution is push constants. I filed #734 for us to try implementing them as a native extension, but this wouldn't be portable to the web.
Here is how you'd do it in a portable way. First important fact: you can't do any transfers in the middle of a render pass. Transfers are done on command encoder outside of a render pass. Therefore, each separate object/entity that you draw in a render pass needs to use a separate area in a GPU buffer somewhere (if it needs its own matrix). That means, all your data has to be ready by the time a render pass starts executing (but not necessarily recording!). Here is some pseudo-code:
fn init(){let uniform_buffer = device.create_buffer(size = <big enough for a frame>).// this will allow us to specify the offsets at binding time
let uniform_bind_group = device.create_bind_group(uniform_buffer, dynamic_offset = true).}fnrender(queue:&wgpu::Queue){let encoder = device.create_command_encoder();letmut offset = 0;letmut pass = encoder.begin_render_pass();for entity in world.entities{// this is an operation on the queue, it will be scheduled before anything in this render pass
queue.write_buffer(&self.uniform_buffer, offset, entity.matrix,size_of::<Matrix>());// here comes handy the dynamic offset
pass.set_bind_group(1,&self.uniform_bind_group,&[offset]);// we don't want to overwrite any existing data this frame
offset += size_of::<Matrix>();}// our draw commands are scheduled after the updates
queue.submit(iter::once(encoder.finish()));}
Also worth noting that we landed an experimental staging belt in wgpu-rs, as an alternative to write_buffer.
Closing this. Please free to re-open and/or continue discussion!
I'm afraid this may be a noobie question given how common this use case must be, but for the same reason I figured it would be an easy question for some wgpu gurus.
What's the best practice for updating per-draw uniform data? In particular, I really just want to pass a 4x4 transformation matrix for each draw call.
Some possibilities:
Buffer::map_read/map_write
methods? I was kind of hoping to avoid them if I could for now, because of the situation with event loops described in the docs, but if someone tells me that that's the recommended way to do this, I might try it anyway.Are any of the above possibilities the recommended way to update per-draw data with wgpu today?
Are there other better ways to update per-draw uniform data?
The text was updated successfully, but these errors were encountered: