I’m working on a lighting kind of system, and I’m having some major trouble calculating the distance from the light to the fragment position. The system’s first pass (the regular rendering of the screen) is done by rendering the whole scene with a full white ambient light. Then the second pass shades it through a Filter. (Deferred lighting more or less; I’m not really planning on making it super great, it’s for a small project.) I’m using the exact same methods of getting the fragment’s position as that which is used in the SSAOFilter’s frag shader: reconstructing position from a depth buffer. From what I can gather by looking at it, it returns the position in eye-space.
As a test-case, I put a light at the origin, and a box slightly forward from the origin and within the light’s radius. I run the test-case and at first it looks fine, until I move the camera. When the camera moves, the light follows it. I realized quickly that this was because it was taking the light’s world-space position in eye-space, and the origin in eye-space is the camera’s location. So, I multiplied the light’s position by inverse(g_WorldViewMatrix). That didn’t work, so I tried just regular g_WorldViewMatrix. Again, the same result. I tried converting the returned position from the depth buffer into world-space by multiplying by basically every imaginable matrix and its inverse, and nothing helped.
Frag shader code:
[java]
vec3 getPosition(in vec2 uv) {
//Reconstruction from depth
depthv = texture2D(m_DepthTexture, uv).r;
float depth = (2.0 * m_FrustumNearFar.x) / (m_FrustumNearFar.y + m_FrustumNearFar.x - depthv * (m_FrustumNearFar.y - m_FrustumNearFar.x));
//one frustum corner method
float x = mix(-m_FrustumCorner.x, m_FrustumCorner.x, uv.x);
float y = mix(-m_FrustumCorner.y, m_FrustumCorner.y, uv.y);
return depth * vec3(x, y, m_FrustumCorner.z);
}
vec3 getNormal(in vec2 uv){
return normalize(texture2D(m_Normals, uv).xyz * 2.0 - 1.0);
}
void main() {
int lightType = 0;
vec3 position = getPosition(texCoord) - m_CameraPosition;
if(lightType == 0) {
float dist = length(m_LightPosition - position);
if (dist > m_LightRadius) {
discard;
}
float attenuation = 1.0 - (dist / m_LightRadius);
clamp(attenuation, 0.0, 1.0);
gl_FragColor = texture2D(m_Texture, texCoord) * m_LightColor * vec4(attenuation);
//gl_FragColor = vec4(clamp(distance(position, vec3(0.0)) / 200.0, 0.0, 1.0));
gl_FragColor.a = attenuation;
}
}
[/java]
Note that for the distance between the two I’ve tried the length of their differences and using the distance method, both of which resulted in no change.
If any more code is needed, just ask.
PS: I realize there are probably many mistakes, probably major ones in the general structure of the thing, but this is my attempt at bettering my knowledge of GLSL so I expect it to be riddled with errors. I wanted to figure this problem out myself but after 2 days of trying to literally no avail I have given up.