directx11点光源问题。从原点转换的对象未正确点亮

时间:2014-05-15 10:26:44

标签: c++ directx hlsl directx-11 lighting

正如标题中所述,我的问题是我的点光似乎没有考虑到任何物体的当前位置。它似乎点亮了对象,好像它仍然是围绕原点绘制的。

实施例: 我正在使用的当前场景包含两个盒子,第一个尚未翻译,所以仍然围绕原点,我增加了z轴的比例,这个盒子拉伸它,光线似乎与新的大小合适物体。   第二个框已经沿z轴平移,并且x和y轴按比例缩放以创建一种墙。在这个盒子上可以看到没有光线,直到光线本身离开盒子,此时表面上出现一个明亮的光点,好像光线从盒子上的那个点出来。

当光线到达盒子表面时应该保留在原点的位置时会发生这种情况。

我希望上面的例子解释了我遇到的问题,这可能是由于我传递给着色器的矩阵,但我一直无法找到我出错的地方。

更新矩阵并呈现代码

//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
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);
}

欢迎任何帮助/建议,我无法理解导致此问题的原因。 如果您需要更多信息,请告诉我。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

这一行:vout.posW = mul(vin.pos, worldMatrix);
应该是这样的:vout.posW = mul( float4(vin.pos,1), worldMatrix);
因为现在你没有将翻译应用到你的posW向量。