I'm making a deferred shader and I'm having issue with point lights in that their range dosnt seem to be clamped.
When looking "through" the light volume, the entire area behind it is fully lit. The pictures below shows the problem.
I suppose there must be something I am missing when calculating the distance?
http://postimg.org/image/65ps4d6qn/
http://postimg.org/image/w7mr7a0rt/
Here is the shading pass function (depth testing is disabled aswell):
void OpenGLRenderer::ShadingPass(const RenderableLighting& lighting)
{
GLCALL(glUseProgram(mShadingProgram.mProgramHandle));
GLCALL(glBindFramebuffer(GL_READ_FRAMEBUFFER, mGBuffer.mFramebuffer));
GLCALL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
// activate all the gbuffer textures
GLCALL(glActiveTexture(GL_TEXTURE0 + GBuffer::GBUFFER_TEXTURE_POSITION));
GLCALL(glBindTexture(GL_TEXTURE_2D, mGBuffer.mGBufferTextures[GBuffer::GBUFFER_TEXTURE_POSITION]))
GLCALL(glGenerateMipmap(GL_TEXTURE_2D));
GLCALL(glActiveTexture(GL_TEXTURE0 + GBuffer::GBUFFER_TEXTURE_NORMAL));
GLCALL(glBindTexture(GL_TEXTURE_2D, mGBuffer.mGBufferTextures[GBuffer::GBUFFER_TEXTURE_NORMAL]));
GLCALL(glGenerateMipmap(GL_TEXTURE_2D));
GLCALL(glActiveTexture(GL_TEXTURE0 + GBuffer::GBUFFER_TEXTURE_DIFFUSE));
GLCALL(glBindTexture(GL_TEXTURE_2D, mGBuffer.mGBufferTextures[GBuffer::GBUFFER_TEXTURE_DIFFUSE]));
GLCALL(glGenerateMipmap(GL_TEXTURE_2D));
// draw fullscreen rect for ambient light
mUniBufferShadingPass.SetData(UnifShading(Mat4(1.0f), lighting.mAmbientLight, Vec4(0.0f), lighting.mGamma, lighting.mScreenSize, UnifShading::LIGHT_TYPE_AMBIENT, 0.0f, 0.0f));
mShadingGeometry.DrawRectangle2D();
// for point lights
GLCALL(glEnable(GL_BLEND));
GLCALL(glBlendEquation(GL_FUNC_ADD));
GLCALL(glBlendFunc(GL_ONE, GL_ONE));
// do all point lights
for (const RenderableLighting::PointLight& pointLight : lighting.mPointLights)
{
mUniBufferShadingPass.SetData(UnifShading(pointLight.mWVPMatrix, pointLight.mLightColor, pointLight.mLightPosition, lighting.mGamma, lighting.mScreenSize, UnifShading::LIGHT_TYPE_POINT, pointLight.mFalloffFactor, pointLight.mMaxDistance));
mShadingGeometry.DrawSphere();
}
// reset state
GLCALL(glDisable(GL_BLEND));
GLCALL(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
GLCALL(glUseProgram(0));
}
Here is the shading pass fragment shader:
const std::string gShadingFragmentShader =
"#version 330 \n \
\n \
layout(std140) uniform; \n \
\n \
uniform UnifShading \n \
{ \n \
mat4 mWVPMatrix; \n \
vec4 mLightColor; \n \
vec4 mLightPosOrDir; \n \
vec4 mGamma; \n \
vec2 mScreenSize; \n \
\n \
int mLightType; \n \
float mFalloffFactor; \n \
float mMaxDistance; \n \
} UnifShadingPass; \n \
\n \
uniform sampler2D unifPositionTexture; \n \
uniform sampler2D unifNormalTexture; \n \
uniform sampler2D unifDiffuseTexture; \n \
\n \
out vec4 fragColor; \n \
\n \
vec4 CalcPointLight(vec3 worldPos, vec3 normal) \n \
{ \n \
vec3 positionDiff = (UnifShadingPass.mLightPosOrDir.xyz - worldPos); \n \
\n \
float dist = max(length(positionDiff) - UnifShadingPass.mMaxDistance, 0); \n \
\n \
float attenuation = 1 / ((dist / UnifShadingPass.mMaxDistance + 1) * (dist / UnifShadingPass.mMaxDistance + 1)); \n \
attenuation = max((attenuation - UnifShadingPass.mMaxDistance) / (1 - UnifShadingPass.mMaxDistance), 0); \n \
\n \
vec3 lightDir = normalize(positionDiff); \n \
float angleNormal = clamp(dot(normalize(normal), lightDir), 0, 1); \n \
\n \
return angleNormal * attenuation * UnifShadingPass.mLightColor; \n \
} \n \
\n \
vec4 CalcDirectionalLight(vec3 worldPos, vec3 normal) \n \
{ \n \
return UnifShadingPass.mLightColor; // TODO \n \
} \n \
\n \
vec4 CalcAmbientLight() \n \
{ \n \
return UnifShadingPass.mLightColor; \n \
} \n \
\n \
void main() \n \
{ \n \
vec2 texcoord = gl_FragCoord.xy / UnifShadingPass.mScreenSize; \n \
\n \
vec3 worldPos = texture(unifPositionTexture, texcoord).xyz; \n \
vec3 normal = texture(unifNormalTexture, texcoord).xyz; \n \
vec3 diffuse = texture(unifDiffuseTexture, texcoord).xyz; \n \
normal = normalize(normal); \n \
\n \
if (UnifShadingPass.mLightType == 1) \n \
fragColor = vec4(diffuse, 1.0) * CalcPointLight(worldPos, normal); \n \
else if (UnifShadingPass.mLightType == 2) \n \
fragColor = vec4(diffuse, 1.0) * CalcDirectionalLight(worldPos, normal); \n \
else if (UnifShadingPass.mLightType == 3) \n \
fragColor = vec4(diffuse, 1.0) * CalcAmbientLight(); \n \
else \n \
fragColor = vec4(diffuse, 0.0); \n \
} \n";