Problems implementing perspective projection in 3D graphics, (d3d)

389 views Asked by At

I'm having massive difficulties with setting up a perspective projection with direct x. I've been stuck on this for weeks, any help would be appreciated.

As far as I can my pipeline set up is fine, in as far as the shader is getting exactly the data I am packing it, so I'll forgo including that code, unless I'm asked for it.

I am using glm for maths (therefore column matrices) on the host side. It's set to use a left handed coordinate system. However I couldn't seem to get its projection matrix to work, (I get a blank screen if I use the matrix I get from it) so I wrote this - which I hope only to be temporary.

namespace
{
    glm::mat4 
    perspective()
    {
        DirectX::XMMATRIX dx = DirectX::XMMatrixPerspectiveFovLH(glm::radians(60.0f), 1, 0.01, 1000.0f);
        glm::mat4 glfromdx;

       for (int c = 0; c < 3; c++)
       {
            for (int r = 0; r < 3; r++)
            {
                glfromdx[c][r] = DirectX::XMVectorGetByIndex(dx.r[c], r);
            }
       }

       return glfromdx;
    }
}

this does hand me a projection matrix that works - but I don't really think that it is working. I'm not certain whether its an actual projection, and my clipspace is miniscule. If I move my camera around at all it clips. Photos included.

photo 1: (straight on)

looking directly at a triangle, with no camera rotation.

photo 2: (cam tilted up)

camera tilted up.

photo 3: (cam tilted left)

camera tilted to the left.

Here is my vertex shader https://gist.github.com/anonymous/31726881a5476e6c8513573909bf4dc6

cbuffer offsets
{
     float4x4 model; //<------currently just identity
     float4x4 view; 
     float4x4 proj;
}

struct idata
{
    float3 position : POSITION;
    float4 colour : COLOR;
};
struct odata 
{
    float4 position : SV_POSITION;
    float4 colour : COLOR;
};


void main(in idata dat, out odata odat)
{
    odat.colour = dat.colour;
    odat.position = float4(dat.position, 1.0f);

    //point' = point * model * view * projection
    float4x4 mvp = mul(model, mul(view, proj)); 

    //column matrices.
    odat.position = mul(mvp, odat.position);
}

And here is my fragment shader https://gist.github.com/anonymous/342a707e603b9034deb65eb2c2101e91

struct idata
{
    float4 position : SV_POSITION;
    float4 colour : COLOR;
};
float4 main(in idata data) : SV_TARGET
{
    return float4(data.colour[0], data.colour[1], data.colour[2] , 1.0f);
}

also full camera implementation is here https://gist.github.com/anonymous/b15de44f08852cbf4fa4d6b9fafa0d43 https://gist.github.com/anonymous/8702429212c411ddb04f5163b1d885b9

Finally these are the vertices being passed in position 3 colour 4

(0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f), (0.45f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f), (-0.45f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f)

Edit:

I changed the P*M*V*P calculation in the shader to this; odat.position = mul(mul(mul(proj, view), model), odat.position); still having the same issue.

Edit 2:

Hmm, the above changes mixed with a change of what generates the perspective, now just purely using glm.

glm::mat4 GLtoDX_NDC(glm::translate(glm::vec3(0.0, 0.0, 0.5)) *
        glm::scale(glm::vec3(1.0, 1.0, 0.5)));
glm::mat4 gl = GLtoDX_NDC * glm::perspectiveFovLH(60.0f, 500.0f, 500.0f, 100.0f, 0.1f);

This works, in as far as object no longer cull at about a micrometre, and are projected to their approximate sizes. However, now everything is upside down and rotating causes a shear...

0

There are 0 answers