我正在尝试使用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);
结果:
看起来很好。但光线在10 * 10的平面上,光线的半径为5,因此光线应该几乎覆盖在表面上。
我理解这个问题,我只是不知道如何修复它......
nDotL的其他像素将会更小,从而导致这种“神器”。
如果我删除“* nDotL”部分,灯光如下所示:
在这种情况下,范围很好,但地板的底部也是点亮的......
如果有人能告诉我如何解决这个问题,我将不胜感激。
答案 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;
使用这个"公式"看起来它应该正常工作。