Sign in to follow this  
david w

DX 9 deferred shading help,

Recommended Posts

david w    191
I have been using the deferred shader from codesource written by: Nikita Kindt. I have everything running and the render targets are getting the correct information. What I need help on is a way to calculate the lights. He has a section in the LightPass technique, but the dx/C++ code dont show how to actually get lights onto the scene. And it seems like his lighting section is just a sample of lighting. So I would like any advice/ideas that anyone might have, that would add lighting into the scene. here is the shader:

//-------------------------------------------------------------------------------
//           Name: deferred.fx
//         Author: Nikita Kindt (nk47@bk.ru)
//  Last Modified: 17/06/06
//-------------------------------------------------------------------------------

matrix c_mWorld;
matrix c_mView;
matrix c_mViewInverse;
matrix c_mProjection;
matrix c_mViewProjection;
matrix WorldVP:WorldViewProjection; 

// light parameters
float3 c_vLightDir;
float4 c_vLightPos;
float4 c_vLightDiffuse;
float4 c_vLightSpecular;


// material parameters
float4 c_vMaterialDiffuse;
float4 c_vMaterialSpecular;
float c_fSpecularPower;

// textures
texture2D c_tDiffuseMap;
texture2D c_tNormalMap;

texture2D c_tSceneMaterialMap;
texture2D c_tSceneNormalMap;
texture2D c_tScenePositionXYMap;
texture2D c_tScenePositionZMap;
texture2D c_tLightMap;


sampler DiffuseSampler = sampler_state
{
	Texture = <c_tDiffuseMap>;
	
	AddressU = Wrap;
	AddressV = Wrap;
	
	MagFilter = Linear;
	MinFilter = Linear;
	MipFilter = Linear;
};

sampler NormalSampler = sampler_state
{
	Texture = <c_tNormalMap>;
	
	AddressU = Wrap;
	AddressV = Wrap;
	
	MagFilter = Linear;
	MinFilter = Linear;
	MipFilter = Linear;
};

sampler LightSampler = sampler_state
{
	Texture = <c_tLightMap>;
	
	AddressU = Wrap;
	AddressV = Wrap;
	
	MagFilter = Linear;
	MinFilter = Linear;
	MipFilter = Linear;
};








// rendertargets
sampler SceneMaterialSampler = sampler_state
{
	Texture = <c_tSceneMaterialMap>;
	MagFilter = Point;
	MinFilter = Point;
};

sampler SceneNormalSampler = sampler_state
{
	Texture = <c_tSceneNormalMap>;
	MagFilter = Point;
	MinFilter = Point;
};

sampler ScenePositionXYSampler = sampler_state
{
	Texture = <c_tScenePositionXYMap>;
	MagFilter = Point;
	MinFilter = Point;
};

sampler ScenePositionZSampler = sampler_state
{
	Texture = <c_tScenePositionZMap>;
	MagFilter = Point;
	MinFilter = Point;
};



struct VS_INPUT_BUILD
{
    float3  vPos            : POSITION0;
    float2  vTex0           : TEXCOORD0;
    float3  vNrm            : NORMAL0;
    float3  vTan            : TANGENT0;
    float3  vBin            : BINORMAL0;
};

struct VS_OUTPUT_BUILD
{
	float4	vPos			: POSITION0;
    float2  vTex0           : TEXCOORD0;
	float3	vWorldPos		: TEXCOORD1;
	float3	vWorldNrm		: TEXCOORD2;
};

struct PS_OUTPUT_BUILD
{
	float4	vMaterial		: COLOR0;
	float4	vWorldNrm		: COLOR1;
	float4	vWorldPosXY		: COLOR2;
	float4	vWorldPosZ		: COLOR3;
};

VS_OUTPUT_BUILD vsBuild(VS_INPUT_BUILD i)
{
	VS_OUTPUT_BUILD o;

	o.vWorldPos = mul(float4(i.vPos, 1), c_mWorld);
	o.vPos = mul(float4(o.vWorldPos, 1), c_mViewProjection);	
	o.vTex0 = i.vTex0;	
	o.vWorldNrm = normalize(mul(float4(i.vNrm, 0), c_mWorld));
	
	return o;
};

// psBuild()
// put geometry data into render targets
PS_OUTPUT_BUILD psBuild(VS_OUTPUT_BUILD i) : COLOR0
{
	PS_OUTPUT_BUILD o;

	// material
	float4 vDiffuseMaterial = tex2D(DiffuseSampler, i.vTex0);

	o.vMaterial.rgb = vDiffuseMaterial;
	o.vMaterial.a = 1.0;
	
  	
	// convert normal to texture space [-1;+1] -> [0;1]
	float4 vNormalMaterial = tex2D(NormalSampler, i.vTex0);
	o.vWorldNrm.xyz = i.vWorldNrm * 0.5 + 0.5;
	o.vWorldNrm.rgb = i.vWorldNrm + vNormalMaterial;
	o.vWorldNrm.w = 0.0;
	
	// position
	o.vWorldPosXY = float4(i.vWorldPos.xy, 0, 0);
	o.vWorldPosZ = float4(i.vWorldPos.z, 0, 0, 0);
	
	

	return o;
};


struct PS_INPUT_LIGHT
{
	float2 vTex0		: TEXCOORD0;
};

// psLighting()
// uses data from textures (previous render targets)
float4 psLighting(PS_INPUT_LIGHT i) : COLOR0
{
	float3 vDiffuseMaterial = tex2D(SceneMaterialSampler, i.vTex0).rgb;
	float3 vSpecularMaterial = tex2D(SceneMaterialSampler, i.vTex0).a;
	
	// normals are stored in texture space [0,1] -> convert them back to [-1,+1] range
	float3 vWorldNrm = (tex2D(SceneNormalSampler, i.vTex0) - 0.5) * 2;

	float3 vWorldPos;
	vWorldPos.xy = tex2D(ScenePositionXYSampler, i.vTex0).xy;
	vWorldPos.z = tex2D(ScenePositionZSampler, i.vTex0).x;
	
	float3 vLightDir = normalize(c_vLightPos - vWorldPos);
	float3 vEyeVec = normalize(c_mViewInverse[3].xyz - vWorldPos);	
	float3 vDiffuseIntensity = dot(vLightDir, vWorldNrm);
	float3 vSpecularIntensity = pow(max(0, dot(vEyeVec, reflect(-vLightDir, vWorldNrm))), c_fSpecularPower);

	float4 color;
	color.rgb = vDiffuseIntensity * c_vLightDiffuse.xyz * vDiffuseMaterial + 
				vSpecularIntensity * c_vLightSpecular.xyz * vSpecularMaterial;
	color.a = 1.0;
	
	// here we add color to show how lighting pass affects the scene
	color.rgb += i.vTex0.rgr * 0.5;
	
	
	
	return color;
};



technique buildPass
{
	pass p0
	{
		VertexShader = compile vs_1_1 vsBuild();
		PixelShader = compile ps_2_0 psBuild();
		
		CullMode = ccw;
		FillMode = solid;
		Zenable = true;
		ZWriteEnable = true;
		ZFunc = less;
		StencilEnable = false;
		AlphaBlendEnable = false;
		AlphaTestEnable = false;		
		ColorWriteEnable = red | green | blue;
	}
}

technique lightPass
{
    pass p0
	{
		VertexShader = NULL;
		PixelShader = compile ps_2_0 psLighting();
		
		CullMode = none;
		FillMode = solid;
		Zenable = false;
		StencilEnable = false;		
		AlphaBlendEnable = true;
		Srcblend = One;
		Destblend = One;
		AlphaTestEnable = false;		
		ColorWriteEnable = red | green | blue;
	}
};













Thanks.

Share this post


Link to post
Share on other sites
MJP    19791
It looks like the psLighting pixel shader does actually compute the contribution from a single point light source (without proper attenuation) and then adds in some strange amount at the end to demonstrate...something. I would just take out that "color.rgb += i.vTex0.rgr * 0.5;" line and that should give you a good place to start. When you've got that working, try making new versions of that shader to calculate the contribution from a spot light, or a directional light.

Share this post


Link to post
Share on other sites
david w    191
Thanks for the reply. I have the scene up and running properly. I will be uploading a screen of each render target and final output. Everything looks good for the single light source that does get created. The problem is that I want to support many lights. I am not sure how to use the information in the render targets to make a light. I'm going to be googling for information about deferred shading and how to use this information. I have some ideas. But I really do need some help/explination as to how to make the final lights happen. Also my msn is dwestfall10070@hotmail.com and my yahoo is dwestfall10070@yahoo.com I have both messenger apps and if anyone can help me, could you add me, and help just explain the steps that need to happen. its alot faster than forum posts, thank you.

Share this post


Link to post
Share on other sites
MJP    19791
Typically what you'll do with a deferred shader is you'll render a "shape" for each light source. So for a directional light source you'll render a full-screen quad, for a point light a sphere, and for a spot light a cone. Each one of these "shapes" represents the area of the scene that the light can affect. Then each time your render a shape, you set the appropriate shader (for directional, point, or spot light) and then draw it with additive blending enabled. Once you've rendered everything, you end up with a buffer containing the sum of all of the lighting contributions.

There's a lot of optimizations you can apply...you might want to check out some of these references:

link
link
link
link

Share this post


Link to post
Share on other sites
david w    191
Thanks for the links I've been reading them for awhile now trying to get a grip on things. I think I understand what has to happen. I've been experimenting around to see what will work and what wont work. I have a question though. If I build a simple app and post it up here, would you be willing to help walk me through what I need to get done in order to get the "many" lights that I want? If not thanks for the help so far.

Share this post


Link to post
Share on other sites
david w    191
Thanks, Im getting busy right now. I'll try to use very little media. I will just keep it basic and I'll heavily comment the sections with what I "think" is supposed to happen. Ok, getting busy now. I'll have something soon. Thank you.

Share this post


Link to post
Share on other sites
FeverGames    126
deferred shading can be a real win if you want lots of lights in one scene. But it gets more and more tricky once shadowing and specific material stuff comes in, like object specific settings and stuff like alpha.

just my share of knowledge

Share this post


Link to post
Share on other sites
david w    191
LOL your telling me, I've already been killing myself over this for weeks and I'm just now getting close to finally "getting it." LOL, gotta love pc's.

ok I have the project done. I have everything up and running. Once you have a look over it and read my note in the render section maybe you can put me on the right path. Thanks for the help. ok I have it upload I just got to figure out how to put the link up.


ok thats the link I uploaded it to

link to my test program

copy and paste link in case the other link dont work correctly.

http://forumfiles.thegamecreators.com/download/1593784

Share this post


Link to post
Share on other sites
FeverGames    126
there's a specific XNA tutorial which gave me a great impresion of how deferred shading works. It explains in simple language how the lighting is handled and it is easily converted to DX calls. There tutorial:

http://www.ziggyware.com/readarticle.php?article_id=155

Share this post


Link to post
Share on other sites
david w    191
Thanks for that xna tutorial. Its really helping me alot. Very good information in there. I am making alot of progress as the examples are very well documented.

Share this post


Link to post
Share on other sites
FeverGames    126
when i started our deferred shading system i had a lot of help from that tutorial, it is a great way to start understanding the logic of it all. If you understand that the more advanced subjects aren't so much pain anymore ;)

Share this post


Link to post
Share on other sites
david w    191
I just want to let everyone know that I have gotten deferred shading to work with many lights..thanks for all the help.

BUT I'm still not done. I need to get deferred shading to work with shadows. So If anyone has any information on the fastest/easiest method to put shadows into my game please let me know. I dont care if the shadows are super smooth, I just want basic shadowing in-game.

Thank you all.

Share this post


Link to post
Share on other sites
FeverGames    126
Now to be honest i think you should try to find this out yourself. It is not as difficult as it might seem, since in your lighting calculation the position of the treated pixel is restored. From this point on you can simply do simple shadow map calculations just as in any other shading system.

just try simple shadow mapping. draw the scene from the lights point of view to a texture with just it's depth. Then try to apply this in your lighting calculation.

http://www.ziggyware.com/readarticle.php?article_id=161

just a simple search in my previous given site answers your question :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this