Per-Pixel Point Light

Started by
17 comments, last by Waaayoff 10 years, 9 months ago

Color values should be in 0 - 1 range, ambients should be relatively small, so try this:

// Light
float lightDiffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
//float lightAmbient[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float lightSpecular[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float lightRange = 100.0f;
...

// Material
float materialDiffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float materialAmbient[4] = {0.05f, 0.05f, 0.05f, 1.0f};
float materialSpecular[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float materialPower = 8.0f;
...

and you are missing "globalAmbient":

float gAmbient[4] = { 0.15f, 0.15f, 0.15f, 1.0f };
pEffect->SetValue("globalAmbient", &gAmbient, sizeof(gAmbient));
Advertisement

@belfegor: Now, the mesh is completely black all the time.

It should not be completely black, have you enabled dx debug runtime? Check any dx debug messages in output window!

Repost your cpp code and shader.

@belfegor: Nothing really in the output window, the shader is working correctly, but the mesh is black all the time.

You might want to the check the shader code...

It can't be pure black, should have at least ambient of 0.2 no matter the view and light angles, unless you have done something wrong in cpp code and then it skips shader.

I ask you again have you enbled dx debug runtime and set proper options in dx control panel?

Repost your cpp and shader!

I see you have your camera position in shader as single float set it as float3.

@belfegor: Now, the mesh is not black, however I see the texture and it's dark and I don't see any light affecting it when it's very close to the light position.

Shader:


float4x4 World;
float4x4 View;
float4x4 Projection;

// Point light
float4 lightPosition;
float4 lightDiffuse;
float4 lightAmbient;
float4 lightSpecular;
float lightRange;

// Material
float4 materialDiffuse;
float4 materialAmbient;
float4 materialSpecular;
float materialPower;

float4 globalAmbient;

// Camera position
float3 eyePos;

// Texture
texture colorMapTexture;

sampler2D colorMap = sampler_state
{
    Texture = <colorMapTexture>;
    MagFilter = Linear;
    MinFilter = Anisotropic;
    MipFilter = Linear;
    MaxAnisotropy = 16;
};

struct PS_INPUT
{
   float3 Pos : POSITION;
   float2 UV : TEXCOORD0;
   float3 Normal : TEXCOORD1;
   float3 worldPos : TEXCOORD2;
};

struct VS_INPUT 
{
   float3 Pos : POSITION;
   float2 UV : TEXCOORD0;
   float3 Normal : TEXCOORD1;
};

struct VS_OUTPUT 
{
   float4 Pos : POSITION;
   float2 UV : TEXCOORD0;
   float3 Normal : TEXCOORD1;
   float3 worldPos : TEXCOORD2;
};

//-----------------------------------------------------------------------
// Vertex shader function
//-----------------------------------------------------------------------
VS_OUTPUT VS( VS_INPUT IN )
{
    VS_OUTPUT Out;
    Out = (VS_OUTPUT)0;
    float4x4 WVP = mul(World, mul(View, Projection));
    Out.Pos = mul(float4(IN.Pos, 1.0f), WVP);
    Out.UV = IN.UV;
    Out.Normal = mul(IN.Normal, (float3x3)World);
    Out.worldPos = mul(float4(IN.Pos, 1.0f), World).xyz;
    return Out;
}

//-----------------------------------------------------------------------
// Pixel shader function
//-----------------------------------------------------------------------
float4 PS( PS_INPUT IN ) : COLOR
{
    float3 viewDir = eyePos - IN.worldPos;
    float3 lightDir = (lightPosition - IN.worldPos) / lightRange;

    float atten = saturate(1.0f - dot(lightDir, lightDir));


    float3 n = normalize(IN.Normal);
    float3 l = normalize(lightDir);
    float3 v = normalize(viewDir);
    float3 h = normalize(l + v);
    
    float nDotL = saturate(dot(n, l));
    float nDotH = saturate(dot(n, h));
    float power = (nDotL == 0.0f) ? 0.0f : pow(nDotH, materialPower);

    float4 FinalDiffuse = materialDiffuse * lightDiffuse;
    float4 FinalSpecular = materialSpecular * lightSpecular;

    // float4 color = (materialAmbient * (globalAmbient + (atten * lightAmbient))) +
    //             (FinalDiffuse * nDotL * atten) + (FinalSpecular * power * atten);
    
    float4 color = (materialAmbient + globalAmbient) + (FinalDiffuse * nDotL * atten) + (FinalSpecular * power * atten);
    return color * tex2D(colorMap, IN.UV);
}


//-----------------------------------------------------------------------------
// Techniques.
//-----------------------------------------------------------------------------
technique PointLighting
{
    pass
    {
        AlphaBlendEnable = false;
        ZEnable = true;
        VertexShader = compile vs_3_0 VS();
        PixelShader = compile ps_3_0 PS();
    }
}

I notice that the global ambient color is the only color that affect the mesh, there is no light at all.

The weird thing is that the light works perfectly when I change this line:


float3 n = normalize(IN.Normal);

To the old invalid value:


float3 n = normalize(tex2D(colorMap, IN.UV).rgb * 2.0f - 1.0f);

blink.png

What's going on?

Bump

Output the normals from the pixel shader as colour. Do they look correct?

"Spending your life waiting for the messiah to come save the world is like waiting around for the straight piece to come in Tetris...even if it comes, by that time you've accumulated a mountain of shit so high that you're fucked no matter what you do. "

This topic is closed to new replies.

Advertisement