#Custom arrays in bindless material extension?

19 messages · Page 1 of 1 (latest)

last forum
#

Hello, I want to add a custom array of textures/samplers to a bindless material extension.

My use case is for my character system. I want to have access in shaders to overlay textures (scars, bruise, makeup, tattoo, whatever) ideally without having to bake out new base textures. So each character could store an int in their uniform to index into the array. Something like this. In the ideal case I would also store texture dimensions and uv offsets in a separate binding.

Is this achievable with MaterialExtension or would I have to do something lower level like a custom render pass?

round wagon
#

Use decals?

lament canopy
last forum
#

I'm going to assume the answer is no, it's not possible.

decals can work OK in some situations but it's not a replacement

makeup/blackeye/facial scars won't work with face animations for example. something locked to UV space in the shader is needed

#

chatgpt is telling me it's not possible even with a custom render pass with the current state of wgpu, except possibly with fixed texture sizes and texture_2d_array

i guess im back to just baking new textures then

lament canopy
last forum
#

idk. it said binding arrays of arbitrary texture resources is not yet supported in wgpu. it is possible on modern hardware with modern APIs like vulkan but not yet implemented in wgpu. textures are a different kind of resource than uniform data. of course chatgpt is often wrong and im no gpu expert so idk.

3d textures im sure i could get to work but its limited to fixed resolution. to save vram id crop the textures. then id have to store the uv offsets separately in a global buffer, its not really per instance data, which i assume still means writing a custom render pass.

#

or i could draw new textures as needed in a compute shader and just use those. decals are too limiting. only works if you can parent to a bone and the relevant verts are only affected by that 1 bone. so no large overlays, no facial effects with animations etc.

round wagon
#

if your material has a defined list of textures to layer, than you could have

#[derive(Clone, Asset, Reflect, AsBindGroup)]
#[bindless(index_table(range(0..6)))]
struct MaterialExt {
    #[texture(0)]
    #[sampler(1)]
    bruises: Handle<Image>,
    #[texture(2)]
    #[sampler(3)]
    tatoos: Handle<Image>,
    ...
}

no?

#

with the correct indices to not overlap with the StandardMaterial (if using material extensions)

last forum
#

yes exactly but how to store a global buffer of UV offsets? if i use full 2k texture for each overlay most of it is empty and wasting ram. i can probably just do per instance but it's a lot of duplication since it's the same data for all instances. maybe it's worth it. it's just an array of vec2<f32>, one for each texture

#

maybe i can make the offset data also an Asset? then i can reference by a handle?

round wagon
#
#[storage(2, binding_array(10), read_only)]
pub cube_faces: Handle<ShaderStorageBuffer>,

i have this on one of my materials

last forum
#

but is that global data or per instance?

round wagon
#

instance

#

the Handle<ShaderStorageBuffer> can be shared by multiple instances

last forum
#

ok so only the handle is duplicated?

round wagon
#

yes

last forum
#

that will work, thanks