[D3D9] Deferred Rendering: Point Lights (includes PICTURES)
If you need more information or code, just let me know.
turn this:
struct VertexShaderOutput
{
float4 position : POSITION0;
float4 screen_position : TEXCOORD0;
};
to this:
struct VertexShaderOutput
{
float4 worldPos;
float4 position : POSITION0;
float4 screen_position : TEXCOORD0;
};
and this:
[font="Consolas,"]
VertexShaderOutput MyVertexShader ( VertexShaderInput input )
[/font][font="Consolas,"]{
[/font][font="Consolas,"]VertexShaderOutput output;
[/font][font="Consolas,"][/font][font="Consolas,"]
//processing geometry coordinates
[/font][font="Consolas,"]float4 world_position = mul(float4(input.position,1), mat_world);
[/font][font="Consolas,"]float4 view_position = mul(world_position, mat_view);
[/font][font="Consolas,"]output.position = mul(view_position, mat_projection);
[/font][font="Consolas,"]output.screen_position = output.position;
[/font][font="Consolas,"][/font][font="Consolas,"]
return output;
[/font][font="Consolas,"]}
[/font]to this:
[font="Consolas,"]
VertexShaderOutput MyVertexShader ( VertexShaderInput input )
[/font][font="Consolas,"]{
[/font][font="Consolas,"]VertexShaderOutput output;
[/font][font="Consolas,"][/font][font="Consolas,"]
//processing geometry coordinates
[/font][font="Consolas,"]float4 world_position = mul(float4(input.position,1), mat_world);
[/font][font="Consolas,"]float4 view_position = mul(world_position, mat_view);
[/font][font="Consolas,"]output.[color="#1C2837"]worldPos = world_position;
[/font][font="Consolas,"]output.position = mul(view_position, mat_projection);
[/font][font="Consolas,"]output.screen_position = output.position;
[/font][font="Consolas,"][/font][font="Consolas,"]
return output;
[/font][font="Consolas,"]}
[/font]turn this:
[font="Consolas,"]
//transform to world space
[/font][font="Consolas,"]position = mul(position, mat_invviewproj);
[/font][font="Consolas,"]position /= position.w;
[/font]to this:
[font="Consolas,"]
//transform to world space
[/font][font="Consolas,"]position = input.[color="#1C2837"]worldPos;
[/font][font="Consolas,"]
Hope that helps
Oh yeah, and one other thing, to tell you the truth, I can't quite see whats wrong with your picture, it looks fine to me except maybe the walls and ceiling turn blue far off, is that what the problem is?
[/font]I committed those changes but it didn't change anything (thanks for the simplification though). I guess I can also delete these lines?
position.xy = input.screen_position.xy;
position.z = depth_val;
position.w = 1.0f;
And I had to bind your float4 worldPos to TEXCOORD1 in order to get the shader to compile, I guess that's okay?
I have investigated further and I'm pretty sure the problem lies with the attenuation! That's the term that should make sure the stuff in the back, as can be seen in the shot in my first post, should NEVER be lit (as that stuff is too far away from the light and its radius) and it should also make sure the floor itself, which never gets lit currently, SHOULD be lit, right?
To answer your question, that's what is not working and making me think there's something wrong, the light sphere sits right on the floor plane of the environment, but it lights the background like a see-through sphere instead of leaving the background and point-lighting that floor.
Inverting the depth (which is stored in the alpha channel of my view-space normal render target in the G-Buffer just fine, I can check it in NVidia PerfHUD) like this doesn't change anything surprisingly:
float depth_val = tex2D(smp_normal,tex_coord).a;
depth_val = -depth_val + 1;
My G-Buffer fill shader stores the depth like this:
// in the vertex shader
// get the position of the vertex in view-space, retrieve depth and pass it on
float3 position_view = mul ( input.position, mat_worldview );
output.depth = position_view.z;
// in the pixel shader
// linear depth
output.gbuffertex2.a = input.depth / render_distance;
Since my render distance is large and that environment pretty small, the depth values stored in the G-Buffer are, according to PerfHUD, 0.00 and sometimes 0.01 - is that maybe a problem? I can lower the render distance and get much more variety between these numbers.
This might help.
This thread is about deferred rendering, while the link talks about classic dynamic lighting using 4 point lights.
Also - the thread is DX9, link DX10.
Attenuation = att0 + (att1 * d) + (att2 * d²)
This is what i have for a pixel shader in my lesson on point lights, it could possibly be of use:
float4 PS(VS_OUTPUT input) : SV_TARGET
{
input.normal = normalize(input.normal);
float4 diffuse = ObjTexture.Sample( ObjSamplerState, input.TexCoord );
float3 finalColor = float3(0.0f, 0.0f, 0.0f);
//Create the vector between light position and pixels position
float3 lightToPixelVec = light.pos - input.worldPos;
//Find the distance between the light pos and pixel pos
float d = length(lightToPixelVec);
//Create the ambient light
float3 finalAmbient = diffuse * light.ambient;
//If pixel is too far, return pixel color with ambient light
if( d > light.range )
return float4(finalAmbient, diffuse.a);
//Turn lightToPixelVec into a unit length vector describing
//the pixels direction from the lights position
lightToPixelVec /= d;
//Calculate how much light the pixel gets by the angle
//in which the light strikes the pixels surface
float howMuchLight = dot(lightToPixelVec, input.normal);
//If light is striking the front side of the pixel
if( howMuchLight > 0.0f )
{
//Add light to the finalColor of the pixel
finalColor += howMuchLight * diffuse * light.diffuse;
//Calculate Light's Falloff factor
finalColor /= light.att[0] + (light.att[1] * d) + (light.att[2] * (d*d));
}
//make sure the values are between 1 and 0, and add the ambient
finalColor = saturate(finalColor + finalAmbient);
//Return Final Color
return float4(finalColor, diffuse.a);
}
I pass this in as the attenuation factor for the light (of course you will want to change it, and it can take a little time to find a good combination of attenuation factors:
light.att = XMFLOAT3(0.0f, 0.2f, 0.0f);
notice how i also use a variable for the range of the point light, you might consider doing that too, but if the attenuation lets the light go to far, then you can see a definite cut off at the range of the light (which can be useful sometimes)
(sorry if its hard to read without formatting, i can never get the code or source tags to work right...
[color="#cccccc"]
Any other ideas, anyone?
i also made my baby-steps in deferred rendering based on his tutorial and it's really well written and rather easy to understand
have a look at catalins xna blog here
i also made my baby-steps in deferred rendering based on his tutorial and it's really well written and rather easy to understand
This is even less helpful than the previous response. You have linked the same blog the OP was following.
@ op; I know how frustrating it is seeing the view count go up and the reply count stand dormant. I've looked at your post but as I'm still forward rendering I won't be as helpful as those with time in the trenches.
First, have you tried shrinking the size of your view frustum, there by increasing resolution in the Depth buffer? you had mentioned it in a previous post, and it struck me that this could be a depth issue( especially with the grainy vertical blue lines on the right of the second picture, although upon closer inspection it appears to be the pleats of the curtains). If you have and it wasn't the issue than I would try some simpler geometry that we can solve by pen and paper if need be. Maybe a sphere light with a simple box around it?