1

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

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

点光源片段着色器:

    vec2 texCoord = gl_FragCoord.xy / ScreenSize;

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

    vec3 toLight = LightCenter - pixelPos;

    浮动衰减 = 钳位(1.0 - 长度(toLight)/LightRadius,0.0,1.0);

    toLight = 归一化(toLight);

    浮动 nDotL = max(dot(pixelNormal, toLight),0.0);

    vec3diffuseLight =diffuseColor * nDotL;

    LightMap = LightIntensity * 衰减 * vec4(diffuseLight,1.0);

结果: 结果

看起来不错。但是光线是在一个10*10的平面上,光线的半径是5,所以光线应该几乎覆盖了这个表面。

我明白这个问题,我只是不知道如何解决它......

正常问题

更多像素的 nDotL 会更小,这会导致这种“伪影”。

如果我删除“* nDotL”部分,灯光看起来像这样:

在此处输入图像描述

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

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

如果需要,源代码也在这里。

4

2 回答 2

1

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

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

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

于 2015-03-31T07:58:37.810 回答
0
vec3 distance = toLight * (1.0 / LightRadius);
float attenuation = clamp(1 - dot(distance, distance), 0, 1);
attenuation = attenuation * attenuation;

使用这个“公式”,它看起来就像它应该的那样工作。

于 2015-04-26T10:04:05.207 回答