Advertisement

VS output problem

Started by September 15, 2018 07:20 AM
3 comments, last by karnaltaB 6 years, 4 months ago

Hello,

 
I am stuck on a problem since 24h and it's driving me crazy.
 
I have my original DX12 renderer which is written under ShaprDX and now, I have ported it in C++ /CLI. But my draw calls with the C++ renderer doesn’t produce anything at VS stage (at least at depth pass).
 
Here are two screenshot of PIX, the OK.jpg  is the VS stage output of my working .NET renderer and the NOK.jpg is what I get with the native one. The depth map is left empty as geometry seem far far away or bugged.
 
I have compared everything in PIX and I cannot find what’s the difference. Vertex buffer, index buffer, constant buffer data, all states (rasterizer, depth, blend, ...) are identical.
 
It look like a simple projection problem but how is it possible with the same matrices, the same vertices and the same vertex shader.
 
I join two PIX frames if someone can help me out. Just look at the first draw call which is the draw call to render a shadow map from a spot light. This is a ultra minimalist scene to reduce thing to their simplest  state.
 
Thank a lot if someone can tell me what’s wrong I am doing.

OK.pix3

NOK.pix3

NOK.jpg

OK.jpg

I finally found my error !

By default, when initializing a D3D12_INPUT_ELEMENT_DESC structue with SharpDX, it set the  input classification as D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA.

In my native renderer, I was initializing my input element with D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA. So, my vertices ID were entering the VS in a wrong order...

I don't know what is exactly input classification but it was my issue :)

 

Advertisement

The "per-instance" classification comes into play when you're drawing multiple instances of something, and you want per-instance data to come from a vertex buffer. The classic setup is two vertex buffers: the first one has all of your "normal" mesh vertex data, with PER_VERTEX_DATA classification for all attributes. Then the other one contains a per-instance unique transform with PER_INSTANCE_DATA. Conceptually you can think of it working like there's an invisible prologue to your vertex shader that pulls the data from your buffers using either the vertex index (PER_VERTEX_DATA) or the instance index (PER_INSTANCE_DATA):


// This is a normal, simple vertex shader
struct VSInput
{
    float3 VtxPosition : VTXPOS;           // PER_VERTEX_DATA
    float3 InstancePosition : INSTPOS;     // PER_INSTANCE_DATA
};

float4 VSMain(in VSInput input) : SV_Position
{
    float3 vtxPos = input.VtxPosition;
    vtxPos += input.InstancePosition;
    return mul(float4(vtxPos, 1.0f), ViewProjectionMatrix);
}

// ======================================================================================================

// Imagine that this hidden VS "prologue" runs first for every instance of the vertex shader:
Buffer<float3> VtxPositionBuffer;
Buffer<float3> InstancePosBuffer;

float4 VSPrologue(in uint vertexIndex : SV_VertexID, 
                  in uint instanceIndex : SV_InstanceID) : SV_Position
{
    VSInput vsInput;

    // PER_VERTEX_DATA means index into the buffer using the vertex index, typically from an index buffer
    vsInput.VtxPosition = VtxPositionBuffer[vertexIndex];  

    // PER_INSTANCE_DATA means index into the buffer using instance index
    vsInput.InstancePosition = InstancePosBuffer[instanceIndex];

    return VSMain(vsInput);
} 

 

Thank you very much.

I got it ;)

This topic is closed to new replies.

Advertisement