1
votes

I'm trying to write a deferred renderer using C# and OpenGL (with OpenTK).

But don't understand how should I implement the normal calculation for a point light.

The point light fragment shader:

    vec2 texCoord = gl_FragCoord.xy / ScreenSize;

    vec3 pixelPos = texture2D(PositionBuffer,texCoord).xyz;
    vec3 pixelNormal = normalize(texture2D(NormalBuffer, texCoord).xyz);
    vec3 diffuseColor = texture2D(ColorBuffer, texCoord).xyz;

    vec3 toLight = LightCenter - pixelPos;

    float attenuation = clamp(1.0 - length(toLight)/LightRadius,0.0,1.0); 

    toLight = normalize(toLight);

    float nDotL = max(dot(pixelNormal, toLight),0.0);

    vec3 diffuseLight = diffuseColor * nDotL;

    LightMap = LightIntensity * attenuation * vec4(diffuseLight,1.0);

Result: The result

It looks fine. But the light is on a 10*10 flat surface, and the radius of the light is 5, so the light should almost cover the surface.

I understand the problem, I just don't know how to fix it...

Normal problem

nDotL of further pixels will be smaller, which leads to this "artifact".

If I remove the "* nDotL" part the light looks like this:

enter image description here

In this case the range is fine, but the bottom of the floor is lit too...

I would be grateful if somebody could tell me how to fix this.

Also the source code is here if it's needed.

2
The attenuation terms looks somehow wrong to me. Shouldn't this in general be 1/length(toLight)? What you do at the moment is a linear fadeout between 0 and LightRadius.BDL
Using "float attenuation = clamp(1.0 / length(toLight),0.0,1.0);" it looks better, but something is still wrong because I can see the edge of the light sphere. i.imgur.com/Vzlyj1s.pngrobot9706

2 Answers

1
votes

It is normal that your lightning gets darkers when you combine Decay + Diffuse. As they are not 1.0 (but some value between 0.0,1.0) if you multiply both you get a darker result. You should increase the strength of the light. You can do

lightStrength / (ConstantDecay + distance*LinearDecay + distance*distance*CuadraticDecay). 

It would give you a softer decay and allow you to increase the light effect to enlight more radius.

0
votes
vec3 distance = toLight * (1.0 / LightRadius);
float attenuation = clamp(1 - dot(distance, distance), 0, 1);
attenuation = attenuation * attenuation;

Using this "formula" it looks like it's working as it should.