Sign in to follow this  
Alriightyman

Constant Buffer matrix array not updating.

Recommended Posts

I have a constant buffer in my vertex shader defined as shown:

cbuffer SkinnedBuffer
{
	float4x4 BoneTransforms[96];
};

In my app I copy all the transforms matrices to my structure defined in c++ similarly to the above.  I call the map/unmap functions and use memcpy in between to copy the data to the buffer. 

 

Now, the data in the buffer has the copied values, and checking the buffer in memory, via Visual Studio gpu debugger, all the data is there.  However, upon debugging the BoneTranforms array in the shader, the values are not even remotely correct.

 

I found elsewhere that the constant buffers need to be aligned appropriately. It states the a float4 occupies 1 register, so if I am using a float4x4, then that would be using 4 registers. I found example that help with correctly working with float arrays, but nothing with float4x4 arrays.  So is there another way of defining the array above?  Or am I missing something?

 

Please note, I am a bit new to shaders and I am not using Effects11.

Share this post


Link to post
Share on other sites

What you describe sounds fine.

 

1. Assuming you're maintaining row-major matrices on the CPU side, are you transposing the matrices as you copy them to the CPU buffer, before you copy the array via Map?

 

2. Does your video card support 384 (4 x 96) constant registers for the shader version?

 

3. In your shader, do you specify the register for the buffer? If so, do you use the correct slot in VSSetConstantBuffers?

 

Not pertinent to your question, but do you really have 96 influence bones?

Edited by Buckeye

Share this post


Link to post
Share on other sites

I would suspect that you're either not binding the constant buffer correctly, or your shader isn't interpreting it correctly. Keep in mind that by default the HLSL compiler will assume that matrices in constant buffers use column-major layout, and will treat them accordingly. If you're storing row-major matrices in your constant buffer, then you can add the "row_major" prefix to your float4x4 array and the compiler will interpret it correctly.

 


Not pertinent to your question, but do you really have 96 influence bones?

 

That's nothing, we had 256 just in our heads! smile.png

Share this post


Link to post
Share on other sites

What you describe sounds fine.

 

1. Assuming you're maintaining row-major matrices on the CPU side, are you transposing the matrices as you copy them to the CPU buffer, before you copy the array via Map?

 

Yes, I transpose them before I copy them.

 

 

2. Does your video card support 384 (4 x 96) constant registers for the shader version?

Yes it does, but I have set it to a much smaller number and still get the same result.

 

 

3. In your shader, do you specify the register for the buffer? If so, do you use the correct slot in VSSetConstantBuffers?

Yes, and no.  I have tried both. Same results.  And set the correct slot as well.

 

 

I would suspect that you're either not binding the constant buffer correctly, or your shader isn't interpreting it correctly. Keep in mind that by default the HLSL compiler will assume that matrices in constant buffers use column-major layout, and will treat them accordingly. If you're storing row-major matrices in your constant buffer, then you can add the "row_major" prefix to your float4x4 array and the compiler will interpret it correctly.

 

 

 


Not pertinent to your question, but do you really have 96 influence bones?

 

That's nothing, we had 256 just in our heads! smile.png

 

 


Not pertinent to your question, but do you really have 96 influence bones?

 

96 turns up a lot, probably because it is the number of bones supported in the shader from the chapter on skeletal animation in Luna's DX11 book.

 

I have two test models.  One with just a few bones, and the other has somewhere are 72 bones I think. But ericrichards22 is right, I sort of got the information from Luna's book. Although, I don't use .fx shaders.

 

I don't mean that the right values are in the wrong places, I am missing all the right values and have really large numbers in the matrix.

For example, here is the first input matrix:

[0] = 0x0098f4a8 {2.22045002e-016, -1.00000000, 0.000000000, 0.549629986}
[1] = 0x0098f4b8 {1.00000000, 2.22045002e-016, 0.000000000, 386.503998}
[2] = 0x0098f4c8 {0.000000000, -1.54074001e-033, -1.00000000, 0.000000000}
[3] = 0x0098f4d8 {0.000000000, 0.000000000, 0.000000000, 1.00000000}

Here is the first 64 bytes of the buffer

0	[0x00000000-0x00000003]	|	   +2.22045e-016
1	[0x00000004-0x00000007]	|	              -1
2	[0x00000008-0x0000000b]	|	              +0
3	[0x0000000c-0x0000000f]	|	     +0.54962999
4	[0x00000010-0x00000013]	|	              +1
5	[0x00000014-0x00000017]	|	   +2.22045e-016
6	[0x00000018-0x0000001b]	|	              +0
7	[0x0000001c-0x0000001f]	|	        +386.504
8	[0x00000020-0x00000023]	|	              +0
9	[0x00000024-0x00000027]	|	   -1.54074e-033
10	[0x00000028-0x0000002b]	|	              -1
11	[0x0000002c-0x0000002f]	|	              +0
12	[0x00000030-0x00000033]	|	              +0
13	[0x00000034-0x00000037]	|	              +0
14	[0x00000038-0x0000003b]	|	              +0
15	[0x0000003c-0x0000003f]	|	              +1

So far so good, but here is the buffer while debugging the vertex shader:

BoneTransforms[0][0] = x = 0.000000000, y = -1.000000000, z = 0.000000000, w = NaN
BoneTransforms[0][1] = x = 1.000000000, y = 0.000000000, z = 0.000000000, w = NaN
BoneTransforms[0][2] = x = 0.000000000, y = -1996489000.000000000, z = -1.000000000, w = NaN
BoneTransforms[0][3] = x = NaN, y = NaN, z = NaN, w = NaN

It doesn't make sense to me.  especially (0,2).y = -1996489000.0???

Share this post


Link to post
Share on other sites

Yes, and no. I have tried both. Same results. And set the correct slot as well.

 

Use a structured approach to debugging. Changing things "just to see if it fixes the problem" will only confuse you and others - that's called "hacking." wink.png If you don't know whether something is coded correctly, read the docs or ask how to do it, e.g., here on gamedev. Your code must be correct for the results to be correct.

 

With regard to the above quotation, and getting help with any problem, it's difficult to provide help without knowing what code you're actually trying to debug. So, define the register in the shader, and use the slot number in the VSSetConstantBuffers call.

 

I.e.,
 

// In the shader
cbuffer cbSkinned : register(b2) // or whatever register you're using
{
   float4x4 finalMats[96];
};

// In your code
// Arguments: Into slot 2 (matching "b2"), transfer 1 buffer from SkinnedBuffer (CPU side structure loaded with transposed 4x4 matrices)
context->VSSetConstantBuffers( 2, 1, &SkinnedBuffer );


Set a breakpoint and examine the contents of the SkinnedBuffer structure just before you copy it to the shader resource. Until you've found the problem, use the simplest model you have, and, for debugging, set all the final matrices to the identity matrix CPU side for the first go-around.

 

EDIT: With regard to a structured approach to debugging, consider following the data. In that journal entry, I assume an equivalence between programming experience and experience with debugging techniques. That offends some people and I'll change that in future. However, note in particular the importance of verifying that both code and data are correct at every step.  It's easier to debug CPU code than shader code, so verify by actual examination (don't guess or assume!) that the data going to the shader is correct, before you try to interpret buffer bytes, etc.

Edited by Buckeye

Share this post


Link to post
Share on other sites

I know what is wrong.  It's not that the values are wrong, they are just too small.  That really HUGE negative number is just a very, very small number that fills the 32-bit value that it becomes a larger value. I'll have to check values when I am exporting my model data so that it doesn't have this problem.  I'm sure the data types are double being down graded to floats.  Thanks for the help.

 

Also, Buckeye, I read your following the data, it is more or less what I do until I get completely stumped.  Then, I get annoyed and start trying anything.  It's a good read though, thanks.  Also, I hate asking questions.  I usually try as much as I can by myself and ask questions when my brain is shot. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this