• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Medo Mex

Per-Pixel Point Light

18 posts in this topic

I have been having some troubles to get point light to work, I looked into some code samples, but always getting a problem when trying to implement point light.

 

Can someone show me how do I modify my shader to implement point light? 

matrix World;
matrix View;
matrix Projection;

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

// Texture
texture colorMapTexture;

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

struct PS_INPUT
{
   float4 Pos : SV_POSITION;
   float2 UV : TEXCOORD0;
   float3 Normal : TEXCOORD1;
};

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

struct VS_OUTPUT 
{
   float4 Pos : SV_POSITION;
   float2 UV : TEXCOORD0;
   float3 Normal : TEXCOORD1;
};

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

//-----------------------------------------------------------------------
// Pixel shader function
//-----------------------------------------------------------------------
float4 PS( PS_INPUT IN ) : COLOR
{
     // *** I need to modify this function for point light ***
     return tex2D(colorMap, IN.UV);
}

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

 

Edited by Medo3337
-1

Share this post


Link to post
Share on other sites
Okay, I have been trying for a while to do basic lighting in shader and here is what I got so far (Point Light):

[attachment=16818:5948.png]

 

So here I have 2 problems:

1. The point light is weird (as shown in the screenshot)

2. When the mesh move away from the point light it get black

 

Shader code:

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
float 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(tex2D(colorMap, IN.UV).rgb * 2.0f - 1.0f);
    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);
            
    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();
    }
}

 

0

Share this post


Link to post
Share on other sites

The whiteness looks like your specularity is too high (if materialPower is too big) and the darkness is something you should expect from a point light. The brightness decreases with the square of the distance. So it may be the case that it is just falling off too quickly from lightRange being too small.

 

VS_OUTPUT and PS_INPUT are the same thing--use a typedef or just use one of them to avoid mistakes.

0

Share this post


Link to post
Share on other sites

@menohack: I notice that the whiteness decrease when I give higher materialPower.

 

However, it still doesn't look like specular light, I see just white pixels on the mesh.

 

How do I avoid the darkness? For example, when there is a fire, there should be a point light, however the point light should not make everything black

 

lightRange is not too small, I notice in a direction the falloff decrease smoothly, while in the other direction it decrease not smoothly (like in the screenshot).

 

So, I guess that there is something wrong with the Shader code.

0

Share this post


Link to post
Share on other sites

I am confused as you are trying to use diffuse map as normal, WTF?

Do following changes and report back if it works as expected:

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

Share this post


Link to post
Share on other sites

@belfegor: Okay, the problem is partly resolved, the falloff transition is now smooth.

 

But I have two problems:

1. I don't see the speular light anymore

2. The mesh get black when it's far away from the light, how do I make it never black? the mesh should be AFFECTED by the light but never get black

0

Share this post


Link to post
Share on other sites

By my logic, this:

float4 color = (materialAmbient * (globalAmbient + (atten * lightAmbient))) + ...

should be like this:

// ambients should be added not multiplied or modified by light attenaution
float4 color = (materialAmbient + globalAmbient) + ...

When you fix this above also set some reasonable values for specular color and "materialPower".

Edited by belfegor
0

Share this post


Link to post
Share on other sites

@belfegor: When I change the line to:

float4 color = (materialAmbient + globalAmbient) + (FinalDiffuse * nDotL * atten) + (FinalSpecular * power * atten);

I don't see the light anymore.

Edited by Medo3337
0

Share this post


Link to post
Share on other sites


I don't see the light anymore.

This is not descriptive enough.

Give me all your color values that you are sending to shader.

0

Share this post


Link to post
Share on other sites

@belfegor:

static D3DXHANDLE hTechnique;
hTechnique = pEffect->GetTechniqueByName("PointLighting");
if (FAILED(pEffect->SetTechnique(hTechnique)))
    return;

pEffect->SetMatrix("World", &world);
pEffect->SetMatrix("View", &view);
pEffect->SetMatrix("Projection", &proj);

// Light
float lightDiffuse[4] = {1.0f, 1.0f, 1.0f, 255.0f};
float lightAmbient[4] = {1.0f, 1.0f, 1.0f, 255.0f};
float lightSpecular[4] = {255.0f, 1.0f, 1.0f, 255.0f};
float lightRange = 100.0f;
pEffect->SetValue("lightDiffuse", &lightDiffuse, sizeof(lightDiffuse));
pEffect->SetValue("lightAmbient", &lightAmbient, sizeof(lightAmbient));
pEffect->SetValue("lightSpecular", &lightSpecular, sizeof(lightSpecular));
pEffect->SetValue("lightRange", &lightRange, sizeof(lightRange));


// Material
float materialDiffuse[4] = {1.0f, 1.0f, 1.0f, 255.0f};
float materialAmbient[4] = {1.0f, 1.0f, 1.0f, 255.0f};
float materialSpecular[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float materialPower = 20;
pEffect->SetValue("materialDiffuse", &materialDiffuse, sizeof(materialDiffuse));
pEffect->SetValue("materialAmbient", &materialAmbient, sizeof(materialAmbient));
pEffect->SetValue("materialSpecular", &materialSpecular, sizeof(materialSpecular));
pEffect->SetValue("materialPower", &materialPower, sizeof(materialPower));

float LightPos[4] = {0.0f, 0.0f, -50.1f, 0.0f};
pEffect->SetValue("lightPosition", &LightPos, sizeof(LightPos));
pEffect->SetValue("eyePos", &camera->GetPosition(), sizeof(camera->GetPosition()));

// Texture
pEffect->SetTexture("colorMapTexture", texture);

UINT passes = 0;
HRESULT hr = pEffect->Begin(&passes, 0);
hr = pEffect->BeginPass(0);

model->Render();

pEffect->EndPass();
pEffect->End();

Here is the current shader code as well:

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
float 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();
    }
}

 

0

Share this post


Link to post
Share on other sites

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));
0

Share this post


Link to post
Share on other sites

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.

Edited by belfegor
0

Share this post


Link to post
Share on other sites

@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...

Edited by Medo3337
0

Share this post


Link to post
Share on other sites

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.

Edited by belfegor
0

Share this post


Link to post
Share on other sites

@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();
    }
}

 

0

Share this post


Link to post
Share on other sites

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?

Edited by Medo3337
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0