OpenGL延迟渲染:点光源实现

时间:2015-02-13 15:10:16

标签: c# opengl glsl opentk deferred-rendering

我正在尝试使用C#和OpenGL(使用OpenTK)编写延迟渲染器。

但是不明白我应该如何实现点光源的正常计算。

点光源片段着色器:

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

结果: The result

看起来很好。但光线在10 * 10的平面上,光线的半径为5,因此光线应该几乎覆盖在表面上。

我理解这个问题,我只是不知道如何修复它......

Normal problem

nDotL的其他像素将会更小,从而导致这种“神器”。

如果我删除“* nDotL”部分,灯光如下所示:

enter image description here

在这种情况下,范围很好,但地板的底部也是点亮的......

如果有人能告诉我如何解决这个问题,我将不胜感激。

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

2 个答案:

答案 0 :(得分:1)

当你将Decay + Diffuse结合起来时,你的闪电会变得更加正常。 因为它们不是1.0(但是某些值在0.0,1.0之间),如果你乘以两者,你会得到一个更暗的结果。你应该增加光的强度。你可以做到

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

它会给你一个更柔和的衰减,并允许你增加光效,以增加半径。

答案 1 :(得分:0)

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

使用这个"公式"看起来它应该正常工作。