Blinn-Phong shading with HLSL and D3D11: point light


Staff member
I am currently trying to implement point lights in my game using Blinn-Phong shading in HLSL. The tutorial I followed is linked <a href="" rel="nofollow noreferrer">here</a>.<br>
The code I have now is:

struct VS_INPUT
    float4 Position : POSITION;
    float3 Normal : NORMAL;
    float2 TexCoord : TEXCOORD;

struct VS_OUTPUT
    float4 Position : SV_POSITION;
    float4 WorldPosition : POSITION;
    float3 Normal : NORMAL;
    float2 TexCoord : TEXCOORD;

    float4 Diffuse;
    float4 Ambient;
    float3 Position;
    float3 Attitude;
    float Range;
    int BindSlot;

// Constant Buffer Variables
cbuffer CB_PROJECTION : register(b0)
    matrix Projection;

cbuffer CB_VIEW : register(b1)
    matrix View;
    float4 CameraPosition;

cbuffer CB_WORLD : register(b2)
    matrix World;

cbuffer Light : register(b5)

// Vertex Shader
    VS_OUTPUT Output = (VS_OUTPUT)0;

    // Change the position vector to be 4 units for proper matrix calculations.
    Input.Position.w = 1.0f;

    // Aply the perspective to every vertex.
    Output.Position = mul(Input.Position, World);
    Output.WorldPosition = Output.Position;
    Output.Position = mul(Output.Position, View);
    Output.Position = mul(Output.Position, Projection);

    // Normalise the normal vector.
    Output.Normal = mul(Input.Normal, (float3x3)World);
    Output.Normal = normalize(Output.Normal);

    // Transfer the texture coordinates.
    Output.TexCoord = Input.TexCoord;

    return Output;

// Pixel Shader
float4 PS(VS_OUTPUT Input) : SV_Target
    // Phong relfection is ambient + light-diffuse + spec highlights.
    // I = Ia*ka*Oda + fatt*Ip[kd*Od(N.L) + ks(R.V)^n]
    // Ref:
    // and

    // Get light direction for this fragment
    float3 lightDir = normalize(light.Position - Input.WorldPosition);

    // Note: Non-uniform scaling not supported
    float diffuseLighting = saturate(dot(Input.Normal, -lightDir)); // per pixel diffuse lighting

    // Introduce fall-off of light intensity
    diffuseLighting *= ((length(lightDir) * length(lightDir)) / dot(light.Position - Input.WorldPosition, light.Position - Input.WorldPosition));

    // Using Blinn half angle modification for perofrmance over correctness
    float3 h = normalize(normalize( - Input.WorldPosition) - lightDir);
    float specLighting = pow(saturate(dot(h, Input.Normal)), 2.0f);

    return saturate(light.Ambient + (light.Diffuse * diffuseLighting * 0.6f) + (specLighting * 0.5f));

The problem can be seen in this photo:
<a href=" " rel="nofollow noreferrer"><img src=" " alt="enter image description here"></a>
Note that the frames are deliberately not in order and I tried to capture them so that the bug could be very clear to understand.

The asteroid is a simple model which orbits around the origin of the point light. The specular light should be uniform on all faces and pixels, but as you can see, if the mesh is located in front of the camera, the reflected light forms a sharp shape on it.<br>
I also realised that my code is wrong and if I remove the specular light from the equation, the problem disappears. Can anybody explain me what is happening here and how could I solve this problem? Thank you in advance.