Mark Sibly
unread,Mar 7, 2024, 4:14:49 PMMar 7Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Dawn Graphics
Hi,
Not sure if this is the right place to ask this, perhaps it should be at the webgpu 'matrix' site? Please advise moderators.
My excuse for asking here is it may be a bug and involves C++ which may or may not be relevant to my problem, but I also kind of dislike discord/matrix style sites for support anyway, 90% of the time your question just disappears in an endless stream of discussion, unanswered and perhaps even unread (esp. if it's longish) who knows? And there's no way to even gauge what questions have already been asked - there are no 'topics' or even email threads to browse/search. What am I missing with the appeal of these places?
Anyway, enough grumbling...
Unless I'm using it wrong, I think there's a bug in unpack4xU8. I am using unpack4xU8 to extract joint indices from a vertex, eg:
// C++
struct Vertex {
Vec3f position;
Vec3f normal;
Vec4f color;
uint8_t joints[4]; // 4 joint indices - each element is used to index an array of joint matrices (not shown here).
float weights[4];
};
// END C++
// WGSL
struct Vertex {
@location(0) position: vec3f,
@location(1) normal: vec3f,
@location(2) color: vec4f,
@location(3) joints: u32,
@location(4) weights: vec4f,
};
struct Varying {
...
};
@vertex fn vertexMain(vertex: Vertex, @builtin(instance_index) instanceId : u32) -> Varying {
let joints = unpack4xU8(vertex.joints);
// OK, joints.x, joints.y, joints.z and joints.w should now contain the same integral indexes that were passed in the vertex, correct?
var out: Varying...
...
return out;
}
// END WGSL
However it doesn't seem to work correctly for any vertex joints[] value except the 0th. For example, if I write the vec4<u32> joints value directly to the output fragment color like this...
out.color = vec4f(joints) / 255;
...and return this value as the output fragment color from the fragment shader, I get red for joints values of 255,0,0,0 as expected, but I don't get green or blue for 0,255,0,0 or 0,0,255,0 I just get black. I have tried it with 127, 63 too, still just black. I get red for 255,255,0,0 too, not yellow.
Am I using unpack4xU8 properly?
My vertex buffer attributes are:
// C++
wgpu::VertexAttribute vertexBufferAttribs[]{
{wgpu::VertexFormat::Float32x3, 0, 0}, // Vec3f position
{wgpu::VertexFormat::Float32x3, 12, 1}, // Vec3f normal
{wgpu::VertexFormat::Float32x4, 24, 2}, // Vec4f color
{wgpu::VertexFormat::Uint8x4, 40, 3}, // Vec4ub joints
{wgpu::VertexFormat::Float32x4, 44, 4}, // Vec4f weights
};
static_assert(sizeof(Vertex) == 60);
// END C++
I have since changed the joint system to use float[4]/vec4f instead of uint8_t[4]/u32/unpack4xU8 and everything works as expected, my skinned meshes actually work!
Also works with uint32_t[4]/vec4u.
Bye,
Mark