• Advertisement
Sign in to follow this  

Blending Problem

This topic is 3729 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

Hi heres a VIDEO of my problem. Im having problems with blending my shadow map with my coloured scene. At the moment, im rendering the shadow map to a texture which ranges from black (shadow) to white (fully lit). Then im rendering my coloured scene to another texture. Im then drawing my shadow map to the backbuffer and setting the blend mode so that the next colour is dependent on the last and rendering the coloured scene. So that each coloured pixel is multiplied by the shadow map:
//-----------------------------------------------------------------------------
// Name:  frame()
// Desc:  Frame Method implements virtual Application frame method, called 
//		  once per frame.
//-----------------------------------------------------------------------------
BOOL Demo::frame() 
{

	//Update the delta time 
	UpdateDeltaTime();

	//Update the physics
	gScene->simulate(DeltaTime);


	//Update Scene
	{
		base->input->getInput();
		controlCamera();
		
		//sky->Render();
		//Draw the floor
		mainObject->Render();
		

		//Retrieve cube transformations, apply them, and render the boxes
		for(int i = 0; i < NUM_CUBES; i++)
		{
			PhysXCubes[i]->getGlobalPose().getColumnMajor44(World);

			crate->WorldMatrix = World;
			crate->update();
			crate->Render();
		}


		for(int i = 0; i < NUM_PLAYERS; i++)
		{

			//Draw Character
			PhysXPlayer[i]->actor->getGlobalPose().getColumnMajor44(World);
			character->WorldMatrix = World;
			character->update();
			character->Render();
		
			if(i == currentPlayer)
				lightCam->setTarget(World._41,World._42,World._43);
		}	



	}

	//Fetch simulation results
	gScene->flushStream();
	gScene->fetchResults(NX_RIGID_BODY_FINISHED, true);

	//Draw Scene to depth map Render Target
	if(SUCCEEDED(depthMap->Begin()))
	{
		base->D3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , 
			D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0L);

		base->camera = lightCam;	//Set View/Projection to Light
		base->camera->Render();		//Update Cam
		base->subsetManager->Render(mainEffect,"DepthMap");//Render Scene using DepthMap Technique (for all subsets)

		depthMap->End();
	}
	else
	{
		base->messageBox(base->hWnd,"Failed To Render To Shadow Map");
	}

	//Render To Shadow Map Target
	if(SUCCEEDED(shadowMap->Begin()))
	{
		base->D3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , 
			D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.0f), 1.0f, 0L);

		base->camera = temp;		//Set Camera back to default
		base->camera->Render();    // Update camera
		base->subsetManager->Render(mainEffect,"Recieve"); //Render Scene Using Recieve Technique (for all subsets)

		shadowMap->End();
	}
	else
	{
		base->messageBox(base->hWnd,"Failed To Render To Shadow Map");
	}

	//Render To Scene Map Target
	if(SUCCEEDED(sceneMap->Begin()))
	{
		base->D3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , 
			D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0L);

		base->subsetManager->Render();	//Render normally all colours and shaders
		base->subsetManager->clear();
		sceneMap->End();
	}
	else
	{
		base->messageBox(base->hWnd,"Failed To Render To Shadow Map");
	}

	//Begin Drawing to backbuffer
	if(SUCCEEDED(base->D3dDevice->BeginScene()))
	{

		base->D3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , 
			D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0L);
		
		//Draw the shadowMaps sprite (a sprite with the shadow map render target as its texture)
		shadowMap->sprite->Render();
		base->subsetManager->Render();
		base->subsetManager->clear();

		//Set Render states to multiply next colour by the one currently on the back buffer
		base->D3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA,D3DBLEND_ONE);
		base->D3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA,D3DBLEND_ONE);
		base->D3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
		base->D3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);

		//Draw the sceneMaps sprite (a sprite with the scene map render target as its texture)
		sceneMap->sprite->Render();
		base->subsetManager->Render();
		base->subsetManager->clear();

		//Reset render states
		base->D3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
		base->D3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
		base->D3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA,D3DBLEND_ZERO);
		base->D3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA,D3DBLEND_ZERO);

		base->D3dDevice->EndScene();

		base->D3dDevice->Present(0, 0, 0, 0);


	}else
	{
		base->messageBox(NULL,"Could Not begin base->scene");
	}

	

	return checkExit();
}



Ideally I would do it the other way round so i would render the scene directly to the back buffer then mask it with the shadow map, maybe burn the shadow map into the stencil buffer? I cant work out how to. Anyway the problem at the floor becomes visible through the crates as they interect the "light" areas of the spotlight projected texture. It seems that the alpha is somehow becoming 0 but I cant work out how. Heres my shader code where im implicitly setting all the alphas to 1.
// SECTION FOR RENDERING TO SHADOW MAP

		float4x4 matProj: PROJECTION;
		float4x4 matWorld: WORLD;
		float4x4 matWorldViewProjection : WORLDVIEWPROJECTION;
		float4x4 lightViewProjection;
		
		float4 lightPos;
		float distanceScale = 0.000148f;
		
		
		//Shadow Map Render Target
		texture2D depth_map: RenderColorTarget
		<
    		float2 ViewportRatio = {1.0f, 1.0f};
    		int MIPLEVELS = 0;
    		string format = "A32B32FG32R32F";
		>;
		
		//Shadow Map Sampler State
		sampler DepthRenderTarget = sampler_state
		{
   			Texture = (depth_map);
   			ADDRESSU = CLAMP;
   			ADDRESSV = CLAMP;
   			MAGFILTER =linear;
   			MINFILTER =linear;
   			MIPFILTER =none;
		};
		
		// Shadow Map Vertex Shader Output
		struct VS_OUT
		{
			float4 POS : POSITION;
			float3 LightVec : TEXCOORD0;
		};
		
		/////////////////////////////////////////////////////
		//	Shadow Map Vertex Shader
		/////////////////////////////////////////////////////
		VS_OUT vs_main(float4 inPos : POSITION)
		{
			VS_OUT Out;
			
			Out.POS  = mul(inPos,matWorldViewProjection);
			//Project the object into the lights space
			Out.LightVec = distanceScale * Out.POS;
			
			return Out;
			
		}
		
		/////////////////////////////////////////////////////
		//	Shadow Map Pixel Shader
		/////////////////////////////////////////////////////
		float4 ps_main(float3 lightVec : TEXCOORD0) : COLOR 
		{
			//Return the distance from the light
   			float4 colour = length(lightVec);
   			colour.a = 1.0f;
   			return colour;
		}


//SECTION FOR RENDERING SCENE

		float4x4 matViewProjection: VIEWPROJECTION;
		float4 view_position : CAMERAPOSITION;
	
	
		//Shadow map Texture
		texture2D shadow_map: RenderColorTarget
		<
    		float2 ViewportRatio = {1.0f, 1.0f};
    		int MIPLEVELS = 0;
    		string format = "X8R8G8B8";
		>;
		
		sampler ShadowMap = sampler_state
		{
   			Texture = (shadow_map);
   			ADDRESSU = CLAMP;
   			ADDRESSV = CLAMP;
   			MAGFILTER =linear;
   			MINFILTER =linear;
   			MIPFILTER =none;
		};
		
		
		
		float shadowBias
		<
			string UIName = "Bias";
			string UIWidget = "slider";
			float UIMin = 0;
			float UIMax = 1000;
			float UIStep = 0.0001;
		>  = 0.001f;
	
		float backProjectionCut = 75.0f;	//
	

		// Projected Spotlight Texture
		texture2D spotLight
		<
   			string ResourceName = "cycloneLight.DDS";
   			string UIName = "SpotLightTex";
   			string ResourceType = "2D";
		>;
	
		// Spotlight Sampler
		sampler SpotLight = sampler_state
		{
   			Texture = (spotLight);
   			ADDRESSU = CLAMP;
   			ADDRESSV = CLAMP;
   			MAGFILTER =linear;
   			MINFILTER =linear;
   			MIPFILTER =none;
		};
	
		struct VS_Recieve_OUT
		{
   			float4 Pos 			:	POSITION;
   			float3 norm			:	TEXCOORD0;
   			float3 lightVec 	:	TEXCOORD1;
   			float3 viewVec		:	TEXCOORD2;
   			float4 shadowCrd	:	TEXCOORD3;
		};
	
		/////////////////////////////////////////////////////
		//	Scene Vertex Shader
		/////////////////////////////////////////////////////
		VS_Recieve_OUT vs_recieve_main(float4 inPos : POSITION, float3 norm: NORMAL)
		{
			VS_Recieve_OUT Out;

			inPos  = mul(inPos,matWorld);

			Out.Pos  = mul(inPos,matViewProjection);
			
			//Project the object into the lights space
			Out.norm = norm;
    		Out.lightVec = distanceScale * (lightPos - inPos.xyz);
    		Out.viewVec = view_position - inPos.xyz;
			
   			float4 sPos = mul(inPos,lightViewProjection);
			
			// Use projective texturing to map the position of each fragment
   			// to its corresponding texel in the shadow map.
   			Out.shadowCrd.x = 0.5 * (sPos.z + sPos.x);
   			Out.shadowCrd.y = 0.5 * (sPos.z - sPos.y);
   			Out.shadowCrd.z = 0.0f; 
   			Out.shadowCrd.w = sPos.z;
				
			return Out;
			
		}
		
		/////////////////////////////////////////////////////
		//	Scene Pixel Shader
		/////////////////////////////////////////////////////
		float4 ps_recieve_main(	float3 norm: TEXCOORD0, 
             					float3 lightVec: TEXCOORD1, 
             					float3 viewVec: TEXCOORD2, 
             					float4 shadowCrd: TEXCOORD3) : COLOR 
		{
			norm = normalize(norm);
   			
   			// Radial distance
   			float dep = length(lightVec);
   			// Normalizes light vector
   			lightVec /= dep;
			
   			// Standard lighting
   			float diffuse = saturate(dot(lightVec, norm));
   			float specular = pow(saturate(dot(reflect(-normalize(viewVec), norm), lightVec)), 16);
			
   			// The depth of the fragment closest to the light
   			float shadowMap = tex2Dproj(DepthRenderTarget, shadowCrd).r;
   			// A spot image of the spotlight
   			float spotLight = tex2Dproj(SpotLight, shadowCrd).r;
   			// If the depth is larger than the stored depth, this fragment
   			// is not the closest to the light, that is we are in shadow.
   			// Otherwise, we're lit. Add a bias to avoid precision issues.
   			float shadow = (dep < shadowMap + shadowBias);
   			// Cut back-projection, that is, make sure we don't lit
   			// anything behind the light. Theoretically, you should just
   			// cut at w = 0, but in practice you'll have to cut at a
   			// fairly high positive number to avoid precision issue when
   			// coordinates approaches zero. 
   			shadow *= (shadowCrd.w > backProjectionCut);
   			// Modulate with spotlight image
   			shadow *= spotLight;
			
   			// Shadow any light contribution except ambient
   			float4 colour =  shadow;
   			colour.a = 1.0f;
   			return colour;
		}

//--------------------------------------------------------------//
// Technique Section for Shadow Map
//--------------------------------------------------------------//
technique DepthMap
{
   pass pDepth
   {
   		VertexShader = compile vs_2_0 vs_main();
   		PixelShader	= compile ps_2_0 ps_main();
   }
} 
//--------------------------------------------------------------//
// Technique Section for Scene
//--------------------------------------------------------------//
technique Recieve
{   
   pass pRecieve
   {
   		VertexShader = compile vs_2_0 vs_recieve_main();   
   		PixelShader = compile ps_2_0 ps_recieve_main();
   }
}





Sorry this is such a long post but i'm realy having problems. Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement