Jump to content

  • Log In with Google      Sign In   
  • Create Account

Instancing not working correctly


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Sobe118   Members   -  Reputation: 104

Like
0Likes
Like

Posted 08 May 2014 - 04:09 AM

I am attempting to just draw a few thousand instanced basic spheres that will move around in the scene. Also I need to eventually use both DrawIndexed and DrawIndexedInstanced or DrawInstanced, and beable to change each instances rotation as well but don't need to worry about that atm. 
 
The main question is just how to get the instanced spheres to draw? Currently the instancing version of my program is drawing one flat sphere at position (0,0,0)
 
There are no compile or run time errors in the code it just doesn't work correctly. Below is what I think is the relevant code. Thanks!
 
Vertex.cpp

const D3D11_INPUT_ELEMENT_DESC InputLayoutDesc::PosNormal[6] = 
{
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
    {"NORMAL",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
    {"WORLD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1},
    {"WORLD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 16, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
    {"WORLD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 32, D3D11_INPUT_PER_INSTANCE_DATA, 1 },
    {"WORLD", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, 48, D3D11_INPUT_PER_INSTANCE_DATA, 1 }
};

#pragma endregion

#pragma region InputLayouts

ID3D11InputLayout* InputLayouts::PosNormal = 0;

void InputLayouts::InitAll(ID3D11Device* device)
{
    //
    // PosNormal
    //

    D3DX11_PASS_DESC passDesc;
    Effects::BasicFX->Light1Tech->GetPassByIndex(0)->GetDesc(&passDesc);
    HR(device->CreateInputLayout(InputLayoutDesc::PosNormal, 6, passDesc.pIAInputSignature, 
        passDesc.IAInputSignatureSize, &PosNormal));
}

void InputLayouts::DestroyAll()
{
    ReleaseCOM(PosNormal);
}

From Basic.fx file

cbuffer cbPerFrame
{
    DirectionalLight gDirLights[3];
    float3 gEyePosW;

    float  gFogStart;
    float  gFogRange;
    float4 gFogColor;
};

cbuffer cbPerObject
{
    float4x4 gWorld;
    float4x4 gWorldInvTranspose;
    float4x4 gWorldViewProj;
    float4x4 gTexTransform;
    Material gMaterial;
}; 

// Nonnumeric values cannot be added to a cbuffer.
Texture2D gDiffuseMap;

SamplerState samAnisotropic
{
    Filter = ANISOTROPIC;
    MaxAnisotropy = 4;

    AddressU = WRAP;
    AddressV = WRAP;
};
struct VertexIn
{
    float3 PosL    : POSITION;
    float3 NormalL : NORMAL;
    row_major float4x4 World  : WORLD;
    uint InstanceId : SV_InstanceID;
};

struct VertexOut
{
    float4 PosH    : SV_POSITION;
    float3 PosW    : POSITION;
    float3 NormalW : NORMAL;
};

VertexOut VS(VertexIn vin)
{
    VertexOut vout;

    // Transform to world space space.
    vout.PosW    = mul(float4(vin.PosL, 1.0f), vin.World).xyz;
    vout.NormalW = mul(vin.NormalL, (float3x3)vin.World);
        
    // Transform to homogeneous clip space.
    vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
    
    return vout;
}

Creating buffer instanced object's locations

    D3D11_BUFFER_DESC instBuffDesc; 
    ZeroMemory( &instBuffDesc, sizeof(instBuffDesc) );
    instBuffDesc.Usage = D3D11_USAGE_DEFAULT;
    instBuffDesc.ByteWidth = sizeof(InstancedData) * OBJECTCOUNT;
    instBuffDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    instBuffDesc.CPUAccessFlags = 0;
    instBuffDesc.MiscFlags = 0;
    HR(md3dDevice->CreateBuffer( &instBuffDesc, NULL, &segmentInstanceBuffer));

Updating buffer in UpdateScene()

        //Copy Data to buffers
        for(int i = 0; i < OBJECTCOUNT; ++i)
        {
            //XMStoreFloat3(&objVector[i], XMVectorSet(segList[i].loc[0], segList[i].loc[1], segList[i].loc[2], 0.0f));
            XMMATRIX sphereOffset = XMMatrixTranslation(segList[i].loc[0], segList[i].loc[1], segList[i].loc[2]);
            XMStoreFloat4x4(&objVector[i].World, sphereOffset);
        }
        md3dImmediateContext->UpdateSubresource( segmentInstanceBuffer, 0, NULL, &objVector, 0, 0);

Relevant code from the Draw (I think)

   UINT strides[2] = {sizeof(Vertex::PosNormal), sizeof(InstancedData)};
    UINT offsets[2] = {0,0};

        md3dImmediateContext->IASetInputLayout(InputLayouts::PosNormal);
        ID3D11Buffer* vbs[2] = {mSphereVB, segmentInstanceBuffer};
        md3dImmediateContext->IASetVertexBuffers(0, 2, vbs, strides, offsets);
        md3dImmediateContext->IASetIndexBuffer(mSphereIB, DXGI_FORMAT_R32_UINT, 0);

        world = XMLoadFloat4x4(&mSphereWorld);
        worldInvTranspose = MathHelper::InverseTranspose(world);

        Effects::BasicFX->SetWorld(world);
        Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
        Effects::BasicFX->SetWorldViewProj(worldViewProj);
        Effects::BasicFX->SetMaterial(mSphereMat);

        activeTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
        md3dImmediateContext->DrawIndexedInstanced(mSphereIndexCount, OBJECTCOUNT, 0, 0, 0);

Let me know if there is any more code that I should show, Thanks! 



Sponsor:

#2 Mona2000   Members   -  Reputation: 624

Like
1Likes
Like

Posted 08 May 2014 - 04:45 AM

You forgot to use the instance world matrix here:

 // Transform to homogeneous clip space.
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);

It should be more like this:

 // Transform to homogeneous clip space.
vout.PosH = mul(float4(vout.PosW, 1.0f), gViewProj);

Edited by Mona2000, 08 May 2014 - 04:48 AM.


#3 Sobe118   Members   -  Reputation: 104

Like
0Likes
Like

Posted 08 May 2014 - 06:48 AM

When I changed it to : 
 // Transform to homogeneous clip space.
vout.PosH = mul(float4(vout.PosW, 1.0f), gViewProj);

I had the shape drawn everywhere (not a sphere any more, covered screen)

 

When I changed it to this : 
// Transform to homogeneous clip space.
vout.PosH = mul(float4(vin.PosL, 1.0f), gViewProj);

It is no longer a flat, and looks like a normal sphere, but there is only one stationary. 

 

I know for sure the location data is being created. I, cant seem to verify the information going to the Buffer (no symbol for the dll, and cant seem to download) but I dont think that's the issue.

 

Im confused why I lost reputation, but I still have a problem...

 

So if this is correct why does is mess up all my visuals? 

vout.PosH = mul(float4(vout.PosW, 1.0f), gViewProj);

Edited by Sobe118, 08 May 2014 - 08:37 AM.


#4 Sobe118   Members   -  Reputation: 104

Like
0Likes
Like

Posted 09 May 2014 - 08:09 AM

I just re did the project a bit to fix the issue. 

 

solved






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS