Sign in to follow this  

Deferred Shading/Lighting, gone completely wrong?

This topic is 4595 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Well I have been working with deferred lighting with multiple render targets taken from NVIDIA's sample code, I have rewritten so many times I cant count, and finally I have some crap temp code I put together to try every possible scenario. Im still stuck with the same output, nothing! I render a sky box and it runs fine, then I render whatever meshs are in my scene and nothing appears except the skybox. I take out the deferred code and it runs fine. So here is my temp code, if anyone can help me, it would be GREATLY APPRECIATED!! Im so lost with this, rewritten so many times, im out of ideas.. ANY idea will work, anything :(. Thanks... The code isnt 100% complete... But it gives the best idea without flooding the post.. -- LOADING CODE --
LoadRender()
{

	m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_BackBuffer);
	m_pd3dDevice->GetDepthStencilSurface(&m_DepthBuffer);

	//albedo
	htemp = m_pd3dDevice->CreateTexture(m_Camera->uiScreenWidth, m_Camera->uiScreenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_MRTSurf[0].tex, NULL);

    //normal
	htemp = m_pd3dDevice->CreateTexture(m_Camera->uiScreenWidth, m_Camera->uiScreenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_MRTSurf[1].tex, NULL);


    //depth
	htemp = m_pd3dDevice->CreateTexture(m_Camera->uiScreenWidth, m_Camera->uiScreenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_R32F, D3DPOOL_DEFAULT, &m_MRTSurf[2].tex, NULL);

	for (i = 0; i < MAX_MRT; i++)
    {
		htemp = (m_MRTSurf[i].tex)->GetSurfaceLevel(0, &m_MRTSurf[i].surf);
    }

//
    //create light transport buffers
    //
    htemp = m_pd3dDevice->CreateTexture(m_Camera->uiScreenWidth, m_Camera->uiScreenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &m_LightSurf.tex, NULL);
	htemp = (m_LightSurf.tex)->GetSurfaceLevel(0, &m_LightSurf.surf);

	CreateQuad(m_vbQuad, m_Camera->uiScreenWidth, m_Camera->uiScreenHeight);
}

CreateQuad()
{

    // create vertex buffer 
    m_pd3dDevice->CreateVertexBuffer( 4 * sizeof(LIGHT_VERTEX_MAP), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &quadVB, NULL);

    LIGHT_VERTEX_MAP *pBuff;

    // account for DirectX's texel center standard:
    float u_adjust = 0.5f / width;
    float v_adjust = 0.5f / height;

    if (quadVB)
    {
        quadVB->Lock(0, 0,(void**)&pBuff, 0);

        for (int i = 0; i < 4; i++)
        {
			if(i == 0)
			{
				pBuff->pos = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
				pBuff->tu  = 0.0f + u_adjust;
				pBuff->tv  = 1.0f + v_adjust;
			}
			if(i == 1)
			{
				pBuff->pos = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
				pBuff->tu  = 0.0f + u_adjust;
				pBuff->tv  = 0.0f + v_adjust;
			}
			if(i == 2)
			{
				pBuff->pos = D3DXVECTOR3(1.0f, 1.0f, 0.0f);
				pBuff->tu  = 1.0f + u_adjust;
				pBuff->tv  = 0.0f + v_adjust;
			}
			if(i == 3)
			{
				pBuff->pos = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
				pBuff->tu  = 1.0f + u_adjust;
				pBuff->tv  = 1.0f + v_adjust;
			}
			pBuff++; 
        }
        quadVB->Unlock();
    }

	return;
}



-- Render code --
PreRender()
{
	for (i = 0; i < MAX_MRT; i++)
		m_pd3dDevice->SetRenderTarget(i, m_MRTSurf[i].surf);
	
	m_pd3dDevice->SetDepthStencilSurface(m_DepthBuffer);

	// clear (this clears all MRTs)
	m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0);
	// Fill mode
	m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);



	htemp = m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
	htemp = m_pd3dDevice->SetStreamSource(0, m_vbMap, 0, sizeof(VERTEX_MAP));
	htemp = m_pd3dDevice->SetIndices(m_ibMap);

	matWorldView = matTranslation * m_Camera->matCameraView;
	D3DXMatrixInverse(&matWorldViewIT, NULL, &matWorldView);
    D3DXMatrixTranspose(&matWorldViewIT, &matWorldViewIT);

	D3DXMatrixIdentity( &matTranslation );
	m_pd3dDevice->GetTransform( D3DTS_WORLD, &matTranslation );
	D3DXMATRIX matWorldViewProj = matTranslation * m_Camera->matCameraView * m_Camera->matProj;
	D3DXMatrixInverse(&matInvWorld, NULL, &matTranslation);

     mtMatContainer.RunMaterial(&matWorldViewProj, &matWorldViewIT );
------ THEN RENDER MESHES  CODE TAKEN OUT(NOT RELEVANT) ------

	PostRenderMap();
}

PostRenderMap()
{
	D3DXMATRIX matTranslation;
	//D3DXMATRIX matInvWorld;

	D3DXMatrixIdentity( &matTranslation );
	m_pd3dDevice->GetTransform( D3DTS_WORLD, &matTranslation );
	D3DXMATRIX matWorldViewProj = matTranslation * m_Camera->matCameraView * m_Camera->matProj;
	//D3DXMatrixInverse(&matInvWorld, NULL, &matTranslation);
	
	m_pd3dDevice->SetRenderTarget(0, m_LightSurf.surf);

	for(i = 1; i < MAX_MRT; i++)
	{
		m_pd3dDevice->SetRenderTarget(i, NULL);
	}
	m_pd3dDevice->SetDepthStencilSurface(NULL);

	m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0);
	
	if(llLgtContainer.LightList.size() > 0)
    {
        //we need to add into fb
        m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
        m_pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
        m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
        m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
    }

	for(int ii = 0; ii < MAX_LIGHT_TYPE; ii++)
	{
		for(i = 0; i < llLgtContainer.LightList.size(); i++)
		{
			if(llLgtContainer.LightList[i].iType == ii)
			{
				llLgtContainer.SetLight(i);	//SET LIGHT CONSTANTS
				llLgtContainer.RunLight(&matWorldViewProj, &m_Camera->matCameraView, &m_Camera->matProj, &m_MRTSurf[0].tex, &m_MRTSurf[1].tex, &m_MRTSurf[2].tex);
				m_pd3dDevice->SetFVF(D3DFVF_LIGHTVERTEX);
				m_pd3dDevice->SetStreamSource(0, m_vbQuad, 0, sizeof(LIGHT_VERTEX_MAP));
				m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
			}
		}
	}

	m_pd3dDevice->SetRenderTarget(0, m_BackBuffer);
	m_pd3dDevice->SetDepthStencilSurface(NULL);

	m_pd3dDevice->SetVertexShader(m_LightTransportVS);
	m_pd3dDevice->SetPixelShader(m_LightTransportPS);


	D3DXHANDLE handle;
	handle = m_LightTransportConstTableVS->GetConstantByName( NULL, "WorldViewProj");
	m_LightTransportConstTableVS->SetMatrix(m_pd3dDevice, handle, &matWorldViewProj);

	handle = NULL;

	if( handle = m_LightTransportConstTablePS->GetConstantByName( NULL, "LightTransport" ) )
    {
        D3DXCONSTANT_DESC constDesc;
        UINT count;

        m_LightTransportConstTablePS->GetConstantDesc( handle, &constDesc, &count );

        if( constDesc.RegisterSet == D3DXRS_SAMPLER )
		{
			m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
			m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
			m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );

			m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
			m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
			m_pd3dDevice->SetSamplerState( 0, D3DSAMP_SRGBTEXTURE, 0 );
            m_pd3dDevice->SetTexture( constDesc.RegisterIndex, m_LightSurf.tex );
		}
    }
	m_pd3dDevice->SetFVF(D3DFVF_LIGHTVERTEX);
	m_pd3dDevice->SetStreamSource(0, m_vbQuad, 0, sizeof(LIGHT_VERTEX_MAP));

	m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
}

RunLight()
{
		D3DXHANDLE handle = NULL;

		
		pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
		pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);

		SetTexture( "MRT0", *mrt0, CONSTList[LightList[iCurrentLight].iConstPS]);
		SetTexture( "MRT1", *mrt1, CONSTList[LightList[iCurrentLight].iConstPS]);
		SetTexture( "MRT2", *mrt2, CONSTList[LightList[iCurrentLight].iConstPS]);

		handle = CONSTList[LightList[iCurrentLight].iConstVS]->GetConstantByName(NULL, "WorldViewProj");
		CONSTList[LightList[iCurrentLight].iConstVS]->SetMatrix(pd3dDevice, handle, matWorldProjView);
		handle = NULL;
		
		D3DXVECTOR3 veclightInViewSpace;
		D3DXVec3TransformNormal(&veclightInViewSpace, &LightList[iCurrentLight].vecTarget, matView);
		D3DXVec3Normalize(&veclightInViewSpace, &veclightInViewSpace);
		handle = CONSTList[LightList[iCurrentLight].iConstPS]->GetConstantByName(NULL, "LightVector");
		CONSTList[LightList[iCurrentLight].iConstPS]->SetValue(pd3dDevice, handle, veclightInViewSpace,sizeof(D3DXVECTOR3));
		handle = NULL;

		iLastVS = iCurrentVS;
		pd3dDevice->SetVertexShader( VSList[iCurrentVS] );

		iLastPS = iCurrentPS;
		pd3dDevice->SetPixelShader( PSList[iCurrentPS] );
}

RunMaterial()
{
		pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
		pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
		pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

	for(int ii = 0; ii < 4; ii++)
	{	
			pd3dDevice->SetSamplerState( ii, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
			pd3dDevice->SetSamplerState( ii, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
			pd3dDevice->SetSamplerState( ii, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );

			pd3dDevice->SetSamplerState( ii, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
			pd3dDevice->SetSamplerState( ii, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
			pd3dDevice->SetSamplerState( ii, D3DSAMP_SRGBTEXTURE, 0 );
		
	}
		matWorldViewProj = *matincWorldViewProj;
		matWorldViewIT   = *matincWorldViewIT;
		EffectList[iCurrentEffect].SetMatrix( pd3dDevice, "WorldViewProj", &matWorldViewProj, CONSTList[EffectList[iCurrentEffect].iConstVS]  );
		EffectList[iCurrentEffect].SetMatrix( pd3dDevice, "WorldViewIT", &matWorldViewIT, CONSTList[EffectList[iCurrentEffect].iConstVS]  );
--RUN SHADERS OMITED--		

}



VERTEX SHADER STUFF
float4x4 WorldViewProj : WorldViewProjection; // This matrix will be loaded by the application
float4x3 WorldViewIT;
sampler AmbientTexture;
sampler DiffuseTexture;
sampler SpecularTexture;
sampler ShininessTexture;
sampler ShininessStrengthTexture;
sampler SelfIlluminationTexture;
sampler OpacityTexture;
sampler FilterColorTexture;
sampler BumpTexture;
sampler ReflectionTexture;
sampler RefractionTexture;
sampler DisplacementTexture;

struct pixel
{
	float4 color : COLOR;
};

struct VS_INPUT0 {
    float4 Position : POSITION; //in object space
    float4 color	: COLOR0;
    float2 TexCoord : TEXCOORD0;
    float3 Normal   : NORMAL;
};

struct VS_OUTPUT0 {
    float4 Position  : POSITION; //in projection space
    float3 Normal    : TEXCOORD0;
    float2 TexCoord  : TEXCOORD1;
    float4 Position2 : TEXCOORD2;
};

struct PS_MRT_OUTPUT {
	float4 Color0 : COLOR0;
	float4 Color1 : COLOR1;
	float4 Color2 : COLOR2;
};

VS_OUTPUT0 SimpleVS( VS_INPUT0 In )
{
   VS_OUTPUT0 Out;

    //normal in view space  
    float3 NormalView = mul(In.Normal, WorldViewIT);
    Out.Normal = normalize(NormalView);
    Out.Position = mul(In.Position, WorldViewProj);
    Out.Position2 = mul(In.Position, WorldViewProj);
    Out.TexCoord = In.TexCoord;

	return Out;
}
vertexfragment DiffuseVertexFragment	= compile_fragment vs_1_1 SimpleVS();

PS_MRT_OUTPUT DiffusePS(VS_OUTPUT0 In)
{
	PS_MRT_OUTPUT Out;
	
	half4 diffuseTex = tex2D( DiffuseTexture, In.TexCoord);
	half3 normal = normalize(In.Normal);

	diffuseTex.w = diffuseTex.w - 0.01;
	clip(diffuseTex.www);
	
	//pack
	normal = normal * 0.5f + 0.5f;
	
	Out.Color0 = float4(diffuseTex.xyz, 1.0f);
	Out.Color1 = float4(normal, 0.0);
	Out.Color2 = float4((In.Position2.z / In.Position2.w), 0.0f, 0.0f, 0.0f); // position2????same?

	return Out;
}
pixelfragment DiffusePixelFragment	= compile_fragment ps_2_0 DiffusePS();




LIGHT SHADER STUFF
float4x4 WorldViewProj : WorldViewProjection; // This matrix will be loaded by the application
//float4x4 InvWorld;
float3 LightVector;
float3 LightColor = (1.0f,1.0f,1.0f);
float Ambient = 0.1f;
sampler MRT0;
sampler MRT1;
sampler MRT2;
sampler LightTransport;

struct VS_INPUT1 
{
    float4 Position : POSITION; //in object space
    float2 TexCoord0 : TEXCOORD0;
};

struct VS_OUTPUT1 
{
    float4 Position   : POSITION;
    float2 TexCoord0   : TEXCOORD0;
    float4 Position2  : TEXCOORD1;
};

VS_OUTPUT1 main(VS_INPUT1 IN)
{
    VS_OUTPUT1 Out;

    Out.Position = mul(IN.Position, WorldViewProj);
    Out.Position2 = mul(IN.Position, WorldViewProj);
   
    // pass texture coordinates for fetching the diffuse map
    Out.TexCoord0 = IN.TexCoord0.xy;

	return Out;
}
vertexfragment MRTVS	= compile_fragment vs_1_1 main();

float4 DirLightingPS(VS_OUTPUT1 In) : COLOR
{
	half4 diffuseTex  = tex2D(MRT0, In.TexCoord0);
	half4 normalTex   = tex2D(MRT1, In.TexCoord0);
	half  z           = tex2D(MRT2, In.TexCoord0);
	half3 finalLighting = half3(0.0, 0.0, 0.0);

	//unpack

	half3 normal = normalTex.xyz * 2 - 1;
	half3 albedo = diffuseTex.xyz;
	half3 emissive = diffuseTex.xyz * normalTex.w * 10.0f;
	
	normal = normalize(normal);
	
	//diffuse lighting
	half NdotL = dot(normal, LightVector);//float3(0.0, 0.0, -1.0));
	half selfShadow = (NdotL > 0) ? 1 : 0;
	half3 diffuse = albedo * NdotL * selfShadow * LightColor;

	finalLighting = diffuse + Ambient + emissive;//shadow * diffuse + Ambient + emissive;
	return float4(finalLighting, 1.0f);
}
pixelfragment DirPixelFragment	= compile_fragment ps_2_0 DirLightingPS();


float4 PassThroughPS(VS_OUTPUT1 In) : COLOR
{
	half4 inTex = tex2D(LightTransport, In.TexCoord0);
	return float4(inTex.x, inTex.y, inTex.z, inTex.w);
}
pixelfragment LightTransportFragment = compile_fragment ps_2_0 PassThroughPS();




Sorry for the length, but please dont walk away from it because of that. Any ideas at all would be GREATLY appreciated. Im so damn lost on this stuff... it seems right in my head... :( PS. Please dont respond to the code being slow or crappy, its been rewritten and taken out of its normal place and all fast parts were taken out to simplify it the most linear I could get it to make sure nothing was in the way. Thanks, Brad

Share this post


Link to post
Share on other sites
Step one is to output a constant color instead of the shader you're having trouble with.

Also turn zenable to false, cullmode to none, alpha test off, stencil disable, etc. etc.

Verify that something shows up.

Next try visualizing your normal and depth buffers as well by copying those values in the the backbuffer rgb.

Also try using D3DXSaveTextureToFile() to save intermediate render results.

Another idea that may help ( and be easier ) is to use NVPerfHUD, from the nvidia dev site. The 2.0 and later versions can show you your mrts during the scene rendering, and all render state settings.

Share this post


Link to post
Share on other sites
Can ya go a little more into what ya said about outputing just a color instead of teh shader? Did ya mean to try outputing a color value during hte pixel shader instead of whatever color its trying to see if im outputing anything at all? Ive tried that and only during my lightsurface output will the different color work, otherwise the other steps show the same output.

Also, all the settings you mentioned I do have set already, now the D3DXSaveTextureToFile() At what stage will this work best on? during the lighting phase and during the mrt textures?

And im definitly checking out the NVIDIA program asap. Thanks for the help, anything anyone has to add will be ALOT of help.


PS. I ran the D3DXSaveTextureToFile(...) And on MRT0 I get perfect output, on MRT1 I get all black, and on MRT2 I get teal and white on the MRT0 picture. So looks good so far...


NEW NOTE: I output LightSurf.tex and I get all black? Is my problem there then? I also ran NVIDIA's program and it shows graphs and all which is nice, and allows you to see what shader is being used, but I couldnt find anything to see on the fly what is in each surface.... but its nice for optimizing for later atleast..

Thanks

[Edited by - xsirxx on May 17, 2005 3:01:09 AM]

Share this post


Link to post
Share on other sites
I know there is MRT support, not sure how to access it, but I think it was in the readme.

If you a registered developer, the 3.0 beta is available, and has some improvements.

I looked at the code, and the only thing that jumped out at me ( which is a smaller separate issue ), is that you are outputing z/w to your r32f buffer. It think you probably really want just w stored in there. w after the projection matrix is just view space z, which is nice & linear, and requires less math to output and less math to play with in later shaders.

Share this post


Link to post
Share on other sites
SimmerD, I think it has to do with my texture coordinates within my lightsurf's pixel/vertex shaders. I was able to get it down to that after looking at each surface and noticing that my lightsurf's texture is coming out at one color, which is the color of the object under the mrt0's texture. Like the lower left or lower right pixel...

UPDATE: I went ahead and changed the pixel shader on the light surface to just map the mrt0 texture and output it to the lightsurf, and it only grabs the color of the object...

[Edited by - xsirxx on May 17, 2005 6:47:27 PM]

Share this post


Link to post
Share on other sites
I found one part of the problem, in my FVF, for some reason it doesnt like D3DFVF_TEX0, but allowed it.... I replaced it with D3DFVF_TEX1... WORKS!!! not the lighting, but it works heh. Im getting diffuse output, so far so good :).

Thank you very much!

Brad

Share this post


Link to post
Share on other sites

This topic is 4595 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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