Jump to content
  • Advertisement
Sign in to follow this  
QQemka

Two constant buffers - cant get it to work

This topic is 810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. I've got a problem i was tryin to resolve last hour...

I want to update 2 constant buffers to the shader: one per frame (view*projection) and one per every object (world matrix)

 

cbuffer cbPerFrameViewProjection : register(cb0)
{
    float4x4 ViewProjection;
};

cbuffer cbPerObjectWorldMatrix : register(cb1)
{
    float4x4 World;
};

 

With trial and error i noticed i cannot set both at once.

From what i read, i got to pass 0/1 to VSSetConstantBuffers:

 

0 for camera (because cb0)

and 1 for world (because cb1)

 

it did not work. So for temporary test, i decided to multiply the XMMATRIX (world*view*proj) on cpu and simply pass it to cbPerObjectWorldMatrix. And now:

when i set cbuffer cbPerObjectWorldMatrix : register(cb1) and first param to 1 in VSSetConstantBuffers it did NOT draw anything.

When i set cbPerObjectWorldMatrix : register(cb0) and apram to 0, it worked. Other 0/1 combinations do not work too

 

d3d11DevCon->VSSetConstantBuffers(0, 1, &cbPerObjectBuffer); // works with cbPerObjectWorldMatrix : register(cb0)

Edit: first param 0 also works with cb1... and even wtih cb any number... whats goin on here

d3d11DevCon->VSSetConstantBuffers(1, 1, &cbPerObjectBuffer); // does not with cbPerObjectWorldMatrix : register(cb1)

 

So from what i see it COMPLETLY ignores the register cb number part...

 

Whats wrong?

 

tl;dr

How can i make 2 or more constant buffers and properly refer to and update each?

 

At the beginning of frame i call

 

d3d11DevCon->UpdateSubresource(cbPerFrameBuffer, 0, NULL, &XMMatrixTranspose(cam.GetViewMatrix()*cam.GetProjectionMatrix()), 0, 0);
    d3d11DevCon->VSSetConstantBuffers(1, 1, &cbPerFrameBuffer); // 1 for cb1

 

And for every object

 

d3d11DevCon->UpdateSubresource(cbPerObjectBuffer, 0, NULL, &XMMatrixTranspose(world.GetTransform()), 0, 0);
    d3d11DevCon->VSSetConstantBuffers(0, 1, &cbPerObjectBuffer); // 0 for cb0

 

Thanks in advance

Edited by QQemka

Share this post


Link to post
Share on other sites
Advertisement

By the way, i am using this runtime compile function. Would hlsl compile time compilation warn me? if yes, then im switching right now... :)

Share this post


Link to post
Share on other sites

Does that shader not emit any warnings on compile?

 

The older versions of the shader compiler (pre-Windows 10) didn't warn you at all about this, they would just silently ignore your register assignment and do it automatically. The latest version of d3dcompiler_47 will give you a proper error message.

Edited by MJP

Share this post


Link to post
Share on other sites

Compiling at runtime or offline shouldn't affect your ability to capture, store, and display warnings and errors.  In either case, it is up to you to be setup to do so, however.

 

This page should give you some info, but you should be able to pass in that last, optional variable to then parse and see if you have any warnings/errors.

Share this post


Link to post
Share on other sites

I've got another strange problem. i am doin THE SAME thing in 2 different ways, and second gives wrong result.... So i want to draw the 3d object on screen. I got a class containing XYZ, rotation and scale. All the maths works fine.

 

What do i do now:

-count world*view*proj on cpu, send to constant buffer, render with shader -> works perfectly BUT I want gpu to multiply the world * camera

 

What do i want then:

-count view*proj once per frame on cpu and send to constant buffer "b1"

-count world matrix for each object on cpu and send to constant buffer "b0"

-inside shader, mul the view * world

 

And for some reason, option 1 (which i want to move to gpu) does not work properly.

 

Thats piece of code and the shader for each option

Option 1 - doing all multiplcation on cpu - works

d3d11DevCon->UpdateSubresource(cbPerObjectBuffer, 0, NULL, &XMMatrixTranspose(world.GetTransform() * cam.GetViewMatrix()*cam.GetProjectionMatrix()), 0, 0);
d3d11DevCon->VSSetConstantBuffers(0, 1, &cbPerObjectBuffer);

Option 2 - whats wrong??

d3d11DevCon->UpdateSubresource(cbPerFrameBuffer, 0, NULL, &XMMatrixTranspose(cam.GetViewMatrix()*cam.GetProjectionMatrix()), 0, 0);
d3d11DevCon->VSSetConstantBuffers(1, 1, &cbPerFrameBuffer);
d3d11DevCon->UpdateSubresource(cbPerObjectBuffer, 0, NULL, &XMMatrixTranspose(world.GetTransform()), 0, 0);
d3d11DevCon->VSSetConstantBuffers(0, 1, &cbPerObjectBuffer);

As you can see, it should work. I know the matrix has to be transposed, but second option counts the view*proj, trnasposes it, and then inside shader mutiples the result * world which results in world*view*proj transposed (basic math behind transposing matrices).

 

Thats the shader. Commented line is used in first case (working)

cbuffer cbPerFrameViewProjection : register(b1)
{
    float4x4 ViewProjection;
};

cbuffer cbPerObjectWorldMatrix : register(b0)
{
    float4x4 World;
};

struct VS_OUTPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
};

VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR)
{

    VS_OUTPUT output;

    float4x4 wvp = mul(ViewProjection, World); // this and below line are for gpu multiplication - blank screen
    output.Pos = mul(inPos, wvp);

    //output.Pos = mul(inPos, World); // thats for cpu multipled matrix, works
    output.Color = inColor;

    return output;
}

Camera:

StaticCamera cam ({ 0.0f, 0.0f, -10.5f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f }, 800, 600); //look from, look at, width,height

 

From test and trial i see that the gpu multiplication works only for x y values between -1 and 1, and it places the object proportionally to the screen width/height... but that makes no sense at all. If i set xy to anythingf more than 1 it is blank...

Edited by QQemka

Share this post


Link to post
Share on other sites

I resolved it...

 

The multiplication order is... very non intuitive, at least i will know from now on

//float4x4 wvp = mul(ViewProjection, World); // this and below line are for gpu multiplication - blank screen
    //output.Pos = mul(inPos, wvp);

    float4x4 wvp = mul(World, ViewProjection); // Multiplication order - works
    output.Pos = mul(inPos, wvp);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!