Question

As stated in the title my issue is that my point light doesn't seem to take into account the current position of any objects. It appears to light the object as if it is still being drawn around the origin.

Example: the current scene i am using contains two boxes, the first has not been translated and so still sits around the origin, i have increased the scale of the z axis for this box stretching it and the light seems to work fine with the new size of the object. The second box has been translated back along the z axis and has had the x and y axis scaled up to create a kind of wall. The no light is visible on this box, until the light itself moves away from the box at which point a bright point of light appears on the surface as if the light was emerging from that point on the box.

This occurs when the light reaches the point where the surface of the box would have been should it have remained at the origin.

I hope the above example explains the problem I am having, this may be due to the matrices I am passing to the shader but I have been unable to find where i am going wrong.

Update Matrix and render code

//Temporary Matricies
    XMMATRIX worldMatrix;
    XMMATRIX modelMatrix;

    worldMatrix = worldMx;
    //Rotate the model Matrix
    XMFLOAT3 TempRot = m_GeometryList[ID].GetRotation();
        worldMatrix = XMMatrixRotationRollPitchYaw(TempRot.x, TempRot.y, TempRot.z);

    //Scale the model matrix
    XMFLOAT3 TempScale = m_GeometryList[ID].GetScale();
    worldMatrix *=XMMatrixScaling(TempScale.x, TempScale.y, TempScale.z);

    //translate into world space
    XMFLOAT3 TempPos = m_GeometryList[ID].GetPosition();
    worldMatrix *= XMMatrixTranslation(TempPos.x, TempPos.y, TempPos.z);

    //Create the model matrix
    modelMatrix = XMMatrixIdentity();

    modelMatrix =  worldMatrix * viewMx * projMx;

    // Update the constant buffer
    _WorldViewProjMx->SetMatrix((float*)&modelMatrix);

    // Update the World Matrix
    //worldMatrix = XMMatrixTranspose(worldMatrix);
    _WorldMx->SetMatrix((float*)&worldMatrix);

////(Earlier in the code)
_WorldViewProjMx = _fX->GetVariableByName("worldViewProj")->AsMatrix();
_WorldMx = _fX->GetVariableByName("worldMatrix")->AsMatrix();
/////

Shaders

// Shaders
struct VertexIn {
    float3 pos : POSITION; 
    float4 color : COLOR; 
    float2 TexCoord : TEXCOORD;
    float3 Normal : NORMAL;
};

struct VertexOut { 
    float4 posH : SV_POSITION; 
    float4 color : COLOR; 
    float2 TexCoord : TEXCOORD0;
    float3 Normal : NORMAL;
    float3 ViewDirection : TEXCOORD1;
    float4 posW : POSITION;
};

VertexOut RenderSceneVS(VertexIn vin) {
    VertexOut vout; 
    vout.posH = mul(float4(vin.pos, 1.0f), worldViewProj);
    vout.Normal = mul(vin.Normal, worldMatrix);//worldInverseTranspose);
    vout.color = vin.color;
    vout.TexCoord = vin.TexCoord;

    // needed for point lights
    vout.posW = mul(vin.pos, worldMatrix);
    // needed for specular lighting
    vout.ViewDirection = cameraPosition.xyz - vout.posW.xyz;
    vout.ViewDirection = normalize(vout.ViewDirection);

    return vout;
}


float4 RenderPointDiffusePS(VertexOut pin) : SV_TARGET0 
{
    float4 colour = Texture.Sample(Sampler, pin.TexCoord); 

    //Create the vector between light position and pixels position
    float3 lightToPixelVec = light.pos - pin.posW;
    //Find the distance between the light pos and pixel pos
    float d = length(lightToPixelVec);

    //Create the ambient light
    float3 finalAmbient = colour * light.ambient;
    //If pixel is too far, return pixel color with ambient light
    if( d > light.range )
    {
        return float4(finalAmbient, colour.a);
    }

    //Turn lightToPixelVec into a unit length vector describing
    //the pixels direction from the lights position
    lightToPixelVec /= d;
    //Calculate how much light the pixel gets by the angle
    //in which the light strikes the pixels surface
    float howMuchLight = dot(lightToPixelVec, pin.Normal);

    float3 tempColor = float3(0.0f, 0.0f, 0.0f);
    //If light is striking the front side of the pixel
    if( howMuchLight > 0.0f )
    {
        //Add light to the finalColor of the pixel
        tempColor += howMuchLight * colour * light.diffuse;     
        //Calculate Light's Falloff factor
        tempColor /= light.att[0] + (light.att[1] * d) + (light.att[2] * (d*d));
    }

    float3 finalColor = saturate(tempColor + finalAmbient);
    return float4(finalColor, colour.a);
}

Any help/advise would be welcome, i can't get my head around what is causing this issue. If you need any more information, please let me know.

Thank you in advance for you help.

Was it helpful?

Solution

This line: vout.posW = mul(vin.pos, worldMatrix);
Should be this: vout.posW = mul( float4(vin.pos,1), worldMatrix);
Because right now you are not applying translation to your posW vector.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top