Skip to content
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

setting a value in a uniform that's an array of structures #11

Open
jowens opened this issue Sep 26, 2024 · 3 comments
Open

setting a value in a uniform that's an array of structures #11

jowens opened this issue Sep 26, 2024 · 3 comments

Comments

@jowens
Copy link

jowens commented Sep 26, 2024

Respectfully requesting enhancing the makeStructuredView with an example of setting a structure (or a partial structure) that's part of a member of structures. "Views" are complicated, and I don't have my mind wrapped around them yet, but I did this wrong many many ways before doing it by hand, and I bet there's a much cleaner way to do it.

const uniformsCode = /* wgsl */ `
  const MAX_LEVEL = 10;
  struct Level {
    f: u32, e: u32, v: u32, t: u32,
  };
  struct MyUniforms {
    uni1: f32,
    uni2: f32,
    @align(16) levelCount: array<Level, MAX_LEVEL>,
    @align(16) levelBasePtr: array<Level, MAX_LEVEL>,
  };
  @group(0) @binding(0) var<uniform> myUniforms: MyUniforms;`;

I'd then like to set levelCount, which I'm (sadly) doing as:

for (let j = 0; j <= mesh.maxLevel; j++) {
  uni.views.levelCount[j].f[0] = mesh.levelCount[j].f;
  uni.views.levelCount[j].e[0] = mesh.levelCount[j].e;
  uni.views.levelCount[j].v[0] = mesh.levelCount[j].v;
  uni.views.levelCount[j].t[0] = mesh.levelCount[j].t;
}

Surely this can be done with less code.

An example of how to set a structure (or a piece of structure) when that structure is within an array would be helpful.

@greggman
Copy link
Owner

greggman commented Sep 27, 2024

You can set the whole thing like this

const v = makeStructuredView(defs.uniforms.myUniforms);
v.set({
  uni1: 123,
  uni2: 456,
  levelCount: [
    { f: 1, e: 2, v: 3, t: 4 },
    { f: 5, e: 6, v: 9, t: 2 },
    ...
  ],
  levelBasePtr: [
    { f: 1, e: 2, v: 3, t: 4 },
    { f: 5, e: 6, v: 9, t: 2 },
    ...
  ],
});

You can set portions. Example

const v = makeStructuredView(defs.uniforms.myUniforms);
v.set({
  uni2: 456,
});

v.set({
  levelBasePtr: [
    { f: 1, e: 2, v: 3, t: 4 },
    { f: 5, e: 6, v: 9, t: 2 },
    ...
  ],
});

If you want to set arrays of structs sparcely it gets harder as you need to make the input sparce to match

v.set({
  levelBasePtr: [
    ,
    ,
    { f: 1, e: 2, v: 3, t: 4 },
  ],
});

Set's only levelBasePtr[2]

Looking at your code above, it looks like you could do this

v.set({ levelCount: mesh.levelCount });

@greggman
Copy link
Owner

Checking, you can also set sparse arrays like this

// Sets f and t of levelBasePtr[9]
setStructuredView({ f: 112233, t: 445566 }, v.views.levelBasePtr[9]);

@jowens
Copy link
Author

jowens commented Sep 27, 2024

This is splendid. Thank you. My frantic "try everything" was not nearly as successful as your knowledge-based suggestions. Perhaps good additions to the docs?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants