   Point lighting with Deferred Shading
  I'm trying to implement deferred shading with DirectX 9.0 and have things mostly working until I get to point lights. I'm trying to render the lights by using actual geometry, but I'm confused as to where I actually render the light (i.e. which render target). Right now I have color/normal/depth render targets. Scene geometry is sent to those and then I switch to a light target to determine directional lighting. I am also trying to do point lighting at this stage but the point lights seem to either never be occluded or are never drawn at all (depending on, at this point, fairly random changes to settings). The last stage is combining the color with the light. I've been reading a few different things but most of it's been from following http://www.catalinzima.com/?page_id=55#comment-20463 (an XNA tutorial that I've been using to get the basic idea, then implementing in DirectX). If I have the shaders (and I'm fairly sure the general algorithm) match the article I get the point lights to always be rendered on top of any scene geometry.Is there a difference between how XNA and DirectX work that would be causing this, am I missing something obvious, or am I just going about it the wrong way entirely? Do I have to render the light spheres with the rest of the scene geometry and then come back and shade it? The closest thing to working has been adding the point lights to the color target while rendering the rest of the scene geometry, but then the point lights won't show up at all unless a directional light is present in the final image.Sorry if the answer to this should be obvious from other posts, I've read as much as I can find but this is pretty new to me. Any advice would be appreciated. Let me know if more information is needed about the problem.   
  It sounds like you got the right idea. Quote:I am also trying to do point lighting at this stage but the point lights seem to either never be occluded or are never drawn at all (depending on, at this point, fairly random changes to settings).Make sure that you use the same depth buffer as you did when rendering the geometry. Also, make sure that depth buffer writing is disabled during rendering of the lights, and that depth testing is disabled during rendering of the directional light. Now, for rendering of the point lights: if (point light radius + near clip plane < distance from camera to point light)   Reverse culling and disable depth testing;else   Normal culling and enable depth testing;Hope this helps!   ;  Thanks for trying to help. The directional lighting seems fine but points still get drawn on top of everything..  I'm using the same depth buffer, but Quote:if (point light radius + near clip plane < distance from camera to point light)Reverse culling and disable depth testing;elseNormal culling and enable depth testing;doesn't seem to work for me. If I use if (cameraToCenter < lightRadius * 2)   SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)else   SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW) it makes the light not disappear when inside the sphere (i.e. do what I think it's supposed to). Does that mean I'm probably scaling the sphere incorrectly or that my depth actually isn't working (since the enable/disable don't seem to make a difference)? If I look at my depth render target it's almost entirely white until I get really close to an object, when it then can be seen as darker.Also, the point light isn't attenuating.. I have an attenuation factor as attenuation = saturate(1.0f - length(lightVec)/lightRadius) where lightVec is the light's position minus a vector with the screen's x, y, depth, and 1.That is being multiplied by the final color, but the sphere ends up being a uniform color instead of fading out. Could the attenuation be a problem with the sphere itself? I'm using the one created with D3DXCreateSphere.   ;  Hi,I'm interested in deferred rendering too ;)Quote:... If I look at my depth render target it's almost entirely white until I get really close to an object, when it then can be seen as darker.It's quite normal. In a R32F render target texture, you see a turquise pixel when it's so close to camera; and white for far objects. Like  this Quote:Also, the point light isn't attenuating.. I have an attenuation factor as attenuation = saturate(1.0f - length(lightVec)/lightRadius) where lightVec is the light's position minus a vector with the screen's x, y, depth, and 1.I'm using a different technique for attenuation. Here (HLSL):half D = MyLight.range;half OneOverSquareD = 1/(D * D);half3 Lg = MyLight.WorldPos - VertexWorldPos;half attenuation = (1 - dot(Lg, Lg) * OneOverSquareD);You can see the results of this formula hereHope this helps.Regards,Rohat.   ;  Your program looks really nice, hopefully I can get mine like that, ha ha.I tried the different attenuation but I had the same result still. It is lighting things inside of it but the light is constant and not getting occluded by objects in front of it.For the depth, if I use R32F and try to display the target I see the regular (fully lit/colored) scene. I have to use one with four color channels to get it to show up as the white/grey/black. Would that mean I'm writing to it incorrectly? Is there any way to do some kind of print statement type thing for a shader? I know the output would be absurdly long/slow but I'm having a hard time because I feel like I'm just guessing and what could be wrong without really being able to tell what's going on with the program. I don't have a good intuition with this yet.   ;  Hi,Quote:... I have to use one with four color channels to get it to show up as the white/grey/black. Would that mean I'm writing to it incorrectly?Using 8-bits or 16-bits channel for depth may cause loss of depth data. Here some results from mine:* A8R8G8B8 for Depthand the shading result* R16F for Depthand the shading resultYou can see the artifacts in the images.How do you reconstruct the position data from your depth information? Also, does your depth information contain view-space z, or z/w, or homogeneus clip space z/w? They're important.   ;  I was using R32F, I just can't seem to look at the actual depth unless I try it with a different format (which I guess seems likely to be a problem). Is there any reason why depth couldn't be stored in a texture like the rest of it?In the vertex shader for storing depth I output a float2 (texcoord) containing the z and w from a projected position. Then in the pixel shader I divide the z by w and store that value in the render target. When I retrieve the depth in the point light shader I sample the R channel of the target (since it is an R32F) and store the value in another float. I have a float4 position variable that gets the x and y coordinates interpolated from the vertex shader and the z is assigned from the sampled depth. I set the w to 1 in position, multiple position by the inverse view projection, and then divide by w. This is the position that I'm using for the rest of the shader. Just to be sure I explained it well:Storing VSoutput.depth.x = output.position.z;output.depth.y = output.position.w;Storing PSoutput.depth = input.depth.x / input.depth.y;Retrieving position VSfloat4 worldPos = mul(float4(input.position, 1), world);float4 viewPos = mul(worldPos, view); outVS.position = mul(viewPos, proj);outVS.screenPos = outVS.position;Retrieving position PSinput.screenPos.xy /= input.screenPos.w;float depthVal = tex2D(depthSampler, texCoord).r;float4 pos;pos.xy = input.screenPos.xy;pos.z = depthVal;pos.w = 1.0f;pos = mul(pos, inverseViewProj);pos /= pos.w;Hopefully somewhere in there is something obviously wrong.. thank you for being so helpful.   ;  So.. wow, ha ha. I was checking the states in the hlsl code but didn't even think about the device clear that was clearing the depth right before lights were being drawn. I have it just clear the target now and the problem with things not being occluded is gone.I had a question about Quote:if (point light radius + near clip plane < distance from camera to point light)Reverse culling and disable depth testing;elseNormal culling and enable depth testing;I tried it this way after making the above changes and it now works better than what I had. Things look lit from in front of the light and stay lit once inside, but when I get to the middle/back of the light some things that are lit become unlit before I should actually be out of the light. Would anyone know how to fix that?Also, it still isn't attenuating properly.. I've tried different functions but it always ends up being a constant multiplier instead of anything that changes by the position of the pixel. It seems like there's probably an obvious reason why it would do that, so if anyone has suggestions they would be appreciated.   