OpenGL延迟渲染:点光源实现
OpenGL deferred rendering: point light implementation
我正在尝试使用 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;
浮点衰减 = clamp(1.0 - length(toLight)/LightRadius,0.0,1.0);
toLight =归一化(toLight);
float nDotL = max(dot(pixelNormal, toLight),0.0);
vec3 diffuseLight = diffuseColor * nDotL;
LightMap = LightIntensity * attenuation * vec4(diffuseLight,1.0);
结果:
看起来不错。但是光线是在一个10*10的平面上,光线的半径是5,所以光线应该几乎覆盖了这个表面。
我明白问题所在,只是不知道如何解决...
nDotL 的更多像素会更小,这导致 "artifact"。
如果我删除“* nDotL”部分,灯看起来像这样:
在这种情况下范围很好,但地板底部也被照亮了...
如果有人能告诉我如何解决这个问题,我将不胜感激。
结合衰减 + 漫反射时,闪电变暗是正常的。
因为它们不是 1.0(而是 0.0,1.0 之间的某个值),所以如果将两者相乘,您会得到更暗的结果。你应该增加光的强度。你可以做到
lightStrength / (ConstantDecay + distance*LinearDecay + distance*distance*CuadraticDecay).
它会给你一个更柔和的衰减,并允许你增加光照效果以照亮更大的半径。
vec3 distance = toLight * (1.0 / LightRadius);
float attenuation = clamp(1 - dot(distance, distance), 0, 1);
attenuation = attenuation * attenuation;
使用这个 "formula" 它看起来像它应该的那样工作。
我正在尝试使用 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; 浮点衰减 = clamp(1.0 - length(toLight)/LightRadius,0.0,1.0); toLight =归一化(toLight); float nDotL = max(dot(pixelNormal, toLight),0.0); vec3 diffuseLight = diffuseColor * nDotL; LightMap = LightIntensity * attenuation * vec4(diffuseLight,1.0);
结果:
看起来不错。但是光线是在一个10*10的平面上,光线的半径是5,所以光线应该几乎覆盖了这个表面。
我明白问题所在,只是不知道如何解决...
nDotL 的更多像素会更小,这导致 "artifact"。
如果我删除“* nDotL”部分,灯看起来像这样:
在这种情况下范围很好,但地板底部也被照亮了...
如果有人能告诉我如何解决这个问题,我将不胜感激。
结合衰减 + 漫反射时,闪电变暗是正常的。 因为它们不是 1.0(而是 0.0,1.0 之间的某个值),所以如果将两者相乘,您会得到更暗的结果。你应该增加光的强度。你可以做到
lightStrength / (ConstantDecay + distance*LinearDecay + distance*distance*CuadraticDecay).
它会给你一个更柔和的衰减,并允许你增加光照效果以照亮更大的半径。
vec3 distance = toLight * (1.0 / LightRadius);
float attenuation = clamp(1 - dot(distance, distance), 0, 1);
attenuation = attenuation * attenuation;
使用这个 "formula" 它看起来像它应该的那样工作。