0

我正在使用 Frank Luna 的书来学习 DirectX 10,但我对我得到的一些照明有点困惑。我有几个对象,一个定向光和一个可以在场景中移动的点光源。我的问题是,当我移动点光源时,光会移动,但距离原点越远,它就会越暗。在原点时,它具有强烈的白光。为什么会这样,我怎样才能让它正常工作?谢谢。

这是点光源的代码:

 float3 PointLight(SurfaceInfo v, Light L, float3 eyePos)
    {
    float3 litColor = float3(0.0f, 0.0f, 0.0f);

    // The vector from the surface to the light.
    float3 lightVec = L.pos - v.pos;

    // The distance from surface to light.
    float d = length(lightVec);

    if( d > L.range )
        return float3(0.0f, 0.0f, 0.0f);

    // Normalize the light vector.
    lightVec /= d; 

    // Add the ambient light term.
    litColor += v.diffuse * L.ambient;  

    // Add diffuse and specular term, provided the surface is in 
    // the line of site of the light.

    float diffuseFactor = dot(lightVec, v.normal);
    [branch]
    if( diffuseFactor > 0.0f )
    {
        float specPower  = max(v.spec.a, 1.0f);
        float3 toEye     = normalize(eyePos - v.pos);
        float3 R         = reflect(-lightVec, v.normal);
        float specFactor = pow(max(dot(R, toEye), 0.0f), specPower);

        // diffuse and specular terms
        litColor += diffuseFactor * v.diffuse * L.diffuse;
        litColor += specFactor * v.spec * L.spec;
    }

    // attenuate
    return litColor / dot(L.att, float3(1.0f, d, d*d));
    }

效果文件:

#include "lighthelper.fx"
#define MaxLights 2

cbuffer cbPerFrame
{
    uniform extern Light gLight[MaxLights];
    int gLightType; 
    float3 gEyePosW;
};

bool gSpecularEnabled;

cbuffer cbPerObject
{
    float4x4 gWorld;
    float4x4 gWVP; 
    float4x4 gTexMtx;
};

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

SamplerState gTriLinearSam
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU=Mirror;
    AddressV=Mirror;
};

struct VS_IN
{
    float3 posL    : POSITION;
    float3 normalL : NORMAL;
    float2 texC    : TEXCOORD;
    float4 diffuse : DIFFUSE;
    float4 spec    : SPECULAR;
};

struct VS_OUT
{
    float4 posH    : SV_POSITION;
    float3 posW    : POSITION;
    float3 normalW : NORMAL;
    float2 texC    : TEXCOORD;
    float4 diffuse : DIFFUSE;
    float4 spec    : SPECULAR;
};

VS_OUT VS(VS_IN vIn)
{
    VS_OUT vOut;

    // Transform to world space space.
    vOut.posW    = mul(float4(vIn.posL, 1.0f), gWorld);
    vOut.normalW = mul(float4(vIn.normalL, 0.0f), gWorld);

    // Transform to homogeneous clip space.
    vOut.posH = mul(float4(vIn.posL, 1.0f), gWVP);

    // Output vertex attributes for interpolation across triangle.
    vOut.texC  = mul(float4(vIn.texC, 0.0f, 1.0f), gTexMtx);
    vOut.diffuse = vIn.diffuse;
    vOut.spec    = vIn.spec;

    return vOut;
}

float4 PS(VS_OUT pIn) : SV_Target
{
    // Get materials from texture maps.
    float4 diffuse = gDiffuseMap.Sample( gTriLinearSam, pIn.texC );
    float4 spec    = gSpecMap.Sample( gTriLinearSam, pIn.texC );

    // Map [0,1] --> [0,256]
    spec.a *= 256.0f;

    // Interpolating normal can make it not be of unit length so normalize it.
    float3 normalW = normalize(pIn.normalW);

    // Compute the lit color for this pixel.
    SurfaceInfo v = {pIn.posW, normalW, diffuse, spec};
    float3 litColor;
    for(int i = 0; i < MaxLights; ++i)
    {
        if( i==0) // Parallel
        {
            //litColor += ParallelLight(v, gLight[i], gEyePosW); 
        }
        else // Point
        {
            litColor += PointLight(v, gLight[i], gEyePosW);
        }
    }
      return float4(litColor, diffuse.a);}

technique10 TexTech
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS() ) );
    }
}

光定义:

 myLight[1].ambient  = D3DXCOLOR(0.4f, 0.8f, 0.4f, 1.0f);
    myLight[1].diffuse  = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    myLight[1].specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
    myLight[1].att.x    = 0.0f;
    myLight[1].att.y    = 0.1f;
    myLight[1].att.z    = 0.0f;
    myLight[1].range    = 50.0f;
4

0 回答 0