Jelajahi Sumber

SSR: HiZ ray marching now functional

BearishSun 8 tahun lalu
induk
melakukan
9aee331bf1

+ 140 - 49
Data/Raw/Engine/Includes/RayMarch.bslinc

@@ -14,8 +14,11 @@ mixin RayMarch
 			#define HI_Z 0
 			#define HI_Z 0
 		#endif
 		#endif
 		
 		
-		#define MAX_HIZ_ITERATIONS 9
-		#define HIZ_START_LEVEL 1
+		// Note this is a very high number of iterations, but it is expected only a small number of pixels will use
+		// this full range. Generally those are pixels that keep having false positives when intersecting a higher
+		// Z level.
+		#define MAX_HIZ_ITERATIONS 64
+		#define HIZ_START_LEVEL 2
 	
 	
 		float3 viewToNDC(float3 view)
 		float3 viewToNDC(float3 view)
 		{
 		{
@@ -61,67 +64,153 @@ mixin RayMarch
 			return false;
 			return false;
 		}
 		}
 		
 		
-		bool hiZSearch(Texture2D depth, SamplerState samp, int2 bufferSize, int maxMipLevel, float3 rayStart, float3 rayDir, inout float t)
-		{
+		// TODO - Debug only
+		bool hiZSearchLinear(Texture2D depth, SamplerState samp, int2 bufferSize, int maxMipLevel, float3 rayPos, float3 rayStep, out float3 hitPos)
+		{		
+			bufferSize >>= 2;
+		
 			float iterationCount = 0.0f;
 			float iterationCount = 0.0f;
-			int mipLevel = HIZ_START_LEVEL;
-			
-			bufferSize >>= mipLevel;
+			float mipLevel = 0.0f;
+		
+			// Get the ray equation, in the form so that t == Z
+			float3 D = rayStep / rayStep.z; // Scale vector so Z is moved into [0, 1] range
+			float3 O = rayPos + D * -rayPos.z; // Get point where Z equals 0 (on near plane)
+			// Our ray is now O + D * t, where t = 0 = near plane, and t = 1 = far plane
 			
 			
-			float3 rayPos = rayStart + rayDir * t;
-			while(mipLevel >= 0 && iterationCount < MAX_HIZ_ITERATIONS)
+			// Avoid division by zero
+			D.x = abs(D.x) < 0.00001f ? 0.00001f : D.x;
+			D.y = abs(D.y) < 0.00001f ? 0.00001f : D.y;
+
+			while(rayPos.z <= 1.0f && iterationCount < 800.0f)
 			{
 			{
-				if(any(rayPos < 0.0f) || any(rayPos > 1.0f))
-					return false; // Reached the end of valid range
+				// Get depth of the current cell
+				float cellZ = depth.SampleLevel(samp, rayPos.xy, mipLevel).r;
+			
+				// Get pixel coordinates of the current cell
+				float2 curCellIdx = trunc(rayPos.xy * bufferSize);
 			
 			
-				// Get position of the ray, relative to the current cell (sub-pixel)
-				float2 subCellPos = frac(rayPos.xy * bufferSize);
+				// Find intersection with the cell floor plane
+				float3 newRay = O + D * max(cellZ, rayPos.z); // max() so we can't hit the ceiling (ray going backwards)
 				
 				
-				// Move subCellPos to [-1,1] range, as it makes the calculation below easier
-				subCellPos *= 2.0f - 1.0f;
+				// Get pixel coordinates of the new ray's cell
+				float2 newCellIdx = trunc(newRay.xy * bufferSize);
 				
 				
-				// Find how much we can move the ray (in "t") before we hit a cell wall
-				//// We want: subCellPos + |rayDir| * t = 1
-				//// Solve for t: t = (1 - subCellPos) / |rayDir|
-				float epsilon = 0.00001f; // Handle div by zero
-				float2 maxXY = (1.0f - subCellPos) / abs(rayDir.xy + epsilon);
-				float maxT = min(maxXY.x, maxXY.y);
+				// If we moved to another cell, no intersection with floor
+				if(any(curCellIdx != newCellIdx))
+				{
+					// Find intersection with neighbor cell
+					float2 cellStart = (curCellIdx / bufferSize);
+					float2 cellEnd = ((curCellIdx + 1) / bufferSize);
+					
+					float2 intersectStart = (cellStart - rayPos.xy) / D.xy;
+					float2 intersectEnd = (cellEnd - rayPos.xy) / D.xy;
+					
+					// Only care about positive t
+					float maxIntersectX = max(intersectStart.x, intersectEnd.x);
+					float maxIntersectY = max(intersectStart.y, intersectEnd.y);
+					
+					// Closest t is the one at the boundary
+					float minIntersect = min(maxIntersectX, maxIntersectY);
 				
 				
+					// Little extra to ensure the boundary is crossed. max() to ensure the value isn't too
+					// small to prevent it ever leaving a cell. Note that this clamping results in a quality loss,
+					// you want to keep the clamp value as low as possible, but not too low to avoid artifacts.
+					minIntersect = max(minIntersect * 1.05f, 1.0f / (bufferSize * 512)); // 1/512th of a pixel
+					
+					// Move the ray past the boundary
+					rayPos = O + D * (rayPos.z + minIntersect);
+				}
+				else // Intersection with floor
+				{
+					hitPos = newRay;
+					return true;
+				}
+
+				++iterationCount;
+			}
+			
+			hitPos = rayPos;			
+			return false;
+		}
+		
+		bool hiZSearch(Texture2D depth, SamplerState samp, int2 bufferSize, int maxMipLevel, float3 rayPos, float3 rayStep, out float3 hitPos, out float iterationCount)
+		{		
+			iterationCount = 0.0f;
+			int mipLevel = HIZ_START_LEVEL;
+			
+			bufferSize >>= mipLevel;
+			
+			// Get the ray equation, in the form so that t == Z
+			float3 D = rayStep / rayStep.z; // Scale vector so Z is moved into [0, 1] range
+			float3 O = rayPos + D * -rayPos.z; // Get point where Z equals 0 (on near plane)
+			// Our ray is now O + D * t, where t = 0 = near plane, and t = 1 = far plane
+			
+			// Avoid division by zero
+			D.x = abs(D.x) < 0.00001f ? 0.00001f : D.x;
+			D.y = abs(D.y) < 0.00001f ? 0.00001f : D.y;
+
+			while(rayPos.z <= 1.0f && iterationCount < MAX_HIZ_ITERATIONS)
+			{
 				// Get depth of the current cell
 				// Get depth of the current cell
 				float cellZ = depth.SampleLevel(samp, rayPos.xy, mipLevel).r;
 				float cellZ = depth.SampleLevel(samp, rayPos.xy, mipLevel).r;
+			
+				// Get pixel coordinates of the current cell
+				float2 curCellIdx = trunc(rayPos.xy * bufferSize);
+			
+				// Find intersection with the cell floor plane
+				float3 newRay = O + D * max(cellZ, rayPos.z); // max() so we can't hit the ceiling (ray going backwards)
 				
 				
-				// Find intersection with the cell
-				//// We want: rayPos.z + rayDir.z * t = cellZ
-				//// Solve for t: t = (cellZ - rayPos.z) / rayDir.z
-				t = (cellZ - rayPos.z) / rayDir.z;
+				// Get pixel coordinates of the new ray's cell
+				float2 newCellIdx = trunc(newRay.xy * bufferSize);
 				
 				
-				// The hit was within the cell walls, meaning we hit the floor of the cell (ray depth is higher than cell depth)
-				float hitBias = 0.002;
-				if(t < (maxT + hitBias))
+				// If we moved to another cell, no intersection with floor
+				if(any(curCellIdx != newCellIdx))
 				{
 				{
-					// We're at the highest detail level, hit found
-					if(mipLevel < 1)
-						return true;
-						
-					// Increase detail level and refine search
-					mipLevel -= 1;
-					bufferSize <<= 1;
+					float2 cellStart = (curCellIdx / bufferSize);
+					float2 cellEnd = ((curCellIdx + 1) / bufferSize);
+					
+					float2 intersectStart = (cellStart - rayPos.xy) / D.xy;
+					float2 intersectEnd = (cellEnd - rayPos.xy) / D.xy;
+					
+					// Only care about positive t
+					float maxIntersectX = max(intersectStart.x, intersectEnd.x);
+					float maxIntersectY = max(intersectStart.y, intersectEnd.y);
+					
+					// Closest t is the one at the boundary
+					float minIntersect = min(maxIntersectX, maxIntersectY);
+				
+					// Little extra to ensure the boundary is crossed. max() to ensure the value isn't too
+					// small to prevent it ever leaving a cell. Note that this clamping results in a quality loss,
+					// you want to keep the clamp value as low as possible, but not too low to avoid artifacts.
+					minIntersect = max(minIntersect * 1.05f, 1.0f / (bufferSize * 512)); // 1/512th of a pixel
+					
+					// Move the ray past the boundary
+					rayPos = O + D * (rayPos.z + minIntersect);
+				
+					if(mipLevel < maxMipLevel)
+					{
+						++mipLevel;
+						bufferSize >>= 1;
+					}
 				}
 				}
-				else
+				else // Intersection with floor, move to higher quality mip
 				{
 				{
-					// We hit the cell wall, meaning we should move to the next cell
-					rayPos = rayStart + rayDir * maxT * 1.04;
+					rayPos = newRay;
+					--mipLevel;
 					
 					
-					// Decrease detail level
-					int oldMipLevel = mipLevel;
+					if(mipLevel < 0)
+					{
+						hitPos = rayPos;
+						return true;
+					}
 					
 					
-					mipLevel = min(maxMipLevel, mipLevel + 1);
-					bufferSize >>= (mipLevel - oldMipLevel);
+					bufferSize <<= 1;
 				}
 				}
-				
-				iterationCount += 1.0f;
+
+				++iterationCount;
 			}
 			}
-						
+			
+			hitPos = rayPos;			
 			return false;
 			return false;
 		}
 		}
 		
 		
@@ -179,14 +268,16 @@ mixin RayMarch
 			
 			
 			// Always do three steps of linear search
 			// Always do three steps of linear search
 			// (HiZ search is more expensive for short runs)
 			// (HiZ search is more expensive for short runs)
-			if(linearSearch(depth, samp, uvStart, uvStep, 3, stepIncrement, compareTolerance, t))
-				return float4(uvStart + uvStep * t, t);
+			//if(linearSearch(depth, samp, uvStart, uvStep, 3, stepIncrement, compareTolerance, t))
+			//	return float4(uvStart + uvStep * t, t);
 			
 			
 			#if HI_Z
 			#if HI_Z
 			
 			
 			// Hierarchical search
 			// Hierarchical search
-			if(hiZSearch(depth, samp, params.bufferSize, params.numMips, uvStart, normalize(uvStep), t))
-				return float4(uvStart + uvStep * t, t);
+			float3 rayPos = uvStart + uvStep * t;
+			float3 hitPos;
+			if(hiZSearch(depth, samp, params.bufferSize, params.numMips, rayPos, uvStep, hitPos, dbg))
+				return float4(NDCToUV((hitPos.xy - params.hiZUVMapping.zw) / params.hiZUVMapping.xy), hitPos.z, 0);
 			#else
 			#else
 			
 			
 			// Plain linear search
 			// Plain linear search

+ 23 - 3
Data/Raw/Engine/Shaders/PPSSRTrace.bsl

@@ -1,6 +1,8 @@
 #include "$ENGINE$\PPBase.bslinc"
 #include "$ENGINE$\PPBase.bslinc"
 #include "$ENGINE$\GBufferInput.bslinc"
 #include "$ENGINE$\GBufferInput.bslinc"
 #include "$ENGINE$\PerCameraData.bslinc"
 #include "$ENGINE$\PerCameraData.bslinc"
+
+#define HI_Z 1
 #include "$ENGINE$\RayMarch.bslinc"
 #include "$ENGINE$\RayMarch.bslinc"
 
 
 technique PPSSRTrace
 technique PPSSRTrace
@@ -30,6 +32,8 @@ technique PPSSRTrace
 		Texture2D gSceneColor;
 		Texture2D gSceneColor;
 		SamplerState gSceneColorSamp;
 		SamplerState gSceneColorSamp;
 		
 		
+		Texture2D gHiZ;
+		
 		float random (float2 st) 
 		float random (float2 st) 
 		{
 		{
 			// From https://thebookofshaders.com/10/
 			// From https://thebookofshaders.com/10/
@@ -87,7 +91,7 @@ technique PPSSRTrace
 			// TODO - Fade based on roughness
 			// TODO - Fade based on roughness
 			
 			
 			float dbg = 0.0f;
 			float dbg = 0.0f;
-			float4 rayHit = rayMarch(gDepthBufferTex, gDepthBufferSamp, rayMarchParams, dbg);
+			float4 rayHit = rayMarch(gHiZ, gDepthBufferSamp, rayMarchParams, dbg);
 			if(rayHit.w < 1.0f) // Hit
 			if(rayHit.w < 1.0f) // Hit
 			{
 			{
 				float4 output = gSceneColor.Sample(gSceneColorSamp, rayHit.xy);
 				float4 output = gSceneColor.Sample(gSceneColorSamp, rayHit.xy);
@@ -97,10 +101,26 @@ technique PPSSRTrace
 				float2 vignette = saturate(abs(rayHitNDC) * 5.0f - 4.0f);
 				float2 vignette = saturate(abs(rayHitNDC) * 5.0f - 4.0f);
 	
 	
 				return output * (1.0f - dot(vignette, vignette));
 				return output * (1.0f - dot(vignette, vignette));
+				
+				// DEBUG ONLY
+				if(dbg < 4.0)
+					return float4(0.0f, 1.0f, 0.0f, 1.0f);
+				else if(dbg < 8.0)
+					return float4(0.0f, 0.66f, 0.0f, 1.0f);
+				else if(dbg < 12.0)
+					return float4(0.0f, 0.33f, 0.0f, 1.0f);
+				else if(dbg < 16.0)
+					return float4(0.33f, 0.33f, 0.0f, 1.0f);
+				else if(dbg < 24.0)
+					return float4(0.5f, 0.0f, 0.0f, 1.0f);
+				else if(dbg < 32.0)
+					return float4(1.0f, 0.0f, 0.0f, 1.0f);
+				else
+					return float4(0.0f, 0.0f, 1.0f, 1.0f);
 			}
 			}
 			
 			
-			if(dbg > 0.5f)
-				return float4(1.0f, 0.0f, 0.0f, 1.0f);
+			//if(dbg > 0.5f)
+			//	return float4(1.0f, 0.0f, 0.0f, 1.0f);
 				
 				
 			return 0.0f;
 			return 0.0f;
 		}	
 		}	

+ 1 - 0
Source/RenderBeast/Include/BsPostProcessing.h

@@ -838,6 +838,7 @@ namespace bs { namespace ct
 		SPtr<GpuParamBlockBuffer> mParamBuffer;
 		SPtr<GpuParamBlockBuffer> mParamBuffer;
 		GBufferParams mGBufferParams;
 		GBufferParams mGBufferParams;
 		GpuParamTexture mSceneColorTexture;
 		GpuParamTexture mSceneColorTexture;
+		GpuParamTexture mHiZTexture;
 	};
 	};
 
 
 	BS_PARAM_BLOCK_BEGIN(TemporalResolveParamDef)
 	BS_PARAM_BLOCK_BEGIN(TemporalResolveParamDef)

+ 45 - 23
Source/RenderBeast/Source/BsPostProcessing.cpp

@@ -1018,29 +1018,50 @@ namespace bs { namespace ct
 
 
 	void BuildHiZ::execute(const RendererViewTargetData& viewInfo, const SPtr<Texture>& source, const SPtr<Texture>& output)
 	void BuildHiZ::execute(const RendererViewTargetData& viewInfo, const SPtr<Texture>& source, const SPtr<Texture>& output)
 	{
 	{
-		GpuResourcePool& pool = GpuResourcePool::instance();
-
-		// First resolve if MSAA if required
-		SPtr<PooledRenderTexture> resolvedDepth;
 		Rect2 srcRect = viewInfo.nrmViewRect;
 		Rect2 srcRect = viewInfo.nrmViewRect;
 
 
+		// If viewport size is odd, adjust UV
+		srcRect.width += (viewInfo.viewRect.width % 2) * (1.0f / viewInfo.viewRect.width);
+		srcRect.height += (viewInfo.viewRect.height % 2) * (1.0f / viewInfo.viewRect.height);
+
 		// Generate first mip
 		// Generate first mip
 		RENDER_TEXTURE_DESC rtDesc;
 		RENDER_TEXTURE_DESC rtDesc;
 		rtDesc.colorSurfaces[0].texture = output;
 		rtDesc.colorSurfaces[0].texture = output;
 		rtDesc.colorSurfaces[0].mipLevel = 0;
 		rtDesc.colorSurfaces[0].mipLevel = 0;
 
 
-		// Make sure that 1 pixel in HiZ maps to a 2x2 block in source
+		SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
 		const TextureProperties& outProps = output->getProperties();
 		const TextureProperties& outProps = output->getProperties();
-		Rect2 destRect(0, 0,
-			Math::ceilToInt(viewInfo.viewRect.width / 2.0f) / (float)outProps.getWidth(),
-			Math::ceilToInt(viewInfo.viewRect.height / 2.0f) / (float)outProps.getHeight());
 
 
-		// If viewport size is odd, adjust UV
-		srcRect.width += (viewInfo.viewRect.width % 2) * (1.0f / viewInfo.viewRect.width);
-		srcRect.height += (viewInfo.viewRect.height % 2) * (1.0f / viewInfo.viewRect.height);
+		Rect2 destRect;
+		bool downsampledFirstMip = false; // Not used currently
+		if (downsampledFirstMip)
+		{
+			// Make sure that 1 pixel in HiZ maps to a 2x2 block in source
+			destRect = Rect2(0, 0,
+				Math::ceilToInt(viewInfo.viewRect.width / 2.0f) / (float)outProps.getWidth(),
+				Math::ceilToInt(viewInfo.viewRect.height / 2.0f) / (float)outProps.getHeight());
 
 
-		SPtr<RenderTexture> rt = RenderTexture::create(rtDesc);
-		mHiZMat.execute(source, 0, srcRect, destRect, rt);
+			mHiZMat.execute(source, 0, srcRect, destRect, rt);
+		}
+		else // First level is just a copy of the depth buffer
+		{
+			destRect = Rect2(0, 0,
+				viewInfo.viewRect.width / (float)outProps.getWidth(),
+				viewInfo.viewRect.height / (float)outProps.getHeight());
+
+			RenderAPI& rapi = RenderAPI::instance();
+			rapi.setRenderTarget(rt);
+			rapi.setViewport(destRect);
+
+			Rect2I srcAreaInt;
+			srcAreaInt.x = (INT32)(srcRect.x * viewInfo.viewRect.width);
+			srcAreaInt.y = (INT32)(srcRect.y * viewInfo.viewRect.height);
+			srcAreaInt.width = (UINT32)(srcRect.width * viewInfo.viewRect.width);
+			srcAreaInt.height = (UINT32)(srcRect.height * viewInfo.viewRect.height);
+
+			gRendererUtility().blit(source, srcAreaInt);			
+			rapi.setViewport(Rect2(0, 0, 1, 1));
+		}
 
 
 		// Generate remaining mip levels
 		// Generate remaining mip levels
 		for(UINT32 i = 1; i <= outProps.getNumMipmaps(); i++)
 		for(UINT32 i = 1; i <= outProps.getNumMipmaps(); i++)
@@ -1050,9 +1071,6 @@ namespace bs { namespace ct
 			rt = RenderTexture::create(rtDesc);
 			rt = RenderTexture::create(rtDesc);
 			mHiZMat.execute(output, i - 1, destRect, destRect, rt);
 			mHiZMat.execute(output, i - 1, destRect, destRect, rt);
 		}
 		}
-
-		if (resolvedDepth)
-			pool.release(resolvedDepth);
 	}
 	}
 
 
 	POOLED_RENDER_TEXTURE_DESC BuildHiZ::getHiZTextureDesc(UINT32 viewWidth, UINT32 viewHeight)
 	POOLED_RENDER_TEXTURE_DESC BuildHiZ::getHiZTextureDesc(UINT32 viewWidth, UINT32 viewHeight)
@@ -1634,6 +1652,7 @@ namespace bs { namespace ct
 
 
 		SPtr<GpuParams> gpuParams = mParamsSet->getGpuParams();
 		SPtr<GpuParams> gpuParams = mParamsSet->getGpuParams();
 		gpuParams->getTextureParam(GPT_FRAGMENT_PROGRAM, "gSceneColor", mSceneColorTexture);
 		gpuParams->getTextureParam(GPT_FRAGMENT_PROGRAM, "gSceneColor", mSceneColorTexture);
+		gpuParams->getTextureParam(GPT_FRAGMENT_PROGRAM, "gHiZ", mHiZTexture);
 
 
 		if(gpuParams->hasParamBlock(GPT_FRAGMENT_PROGRAM, "Input"))
 		if(gpuParams->hasParamBlock(GPT_FRAGMENT_PROGRAM, "Input"))
 			gpuParams->setParamBlockBuffer(GPT_FRAGMENT_PROGRAM, "Input", mParamBuffer);
 			gpuParams->setParamBlockBuffer(GPT_FRAGMENT_PROGRAM, "Input", mParamBuffer);
@@ -1650,11 +1669,12 @@ namespace bs { namespace ct
 		const RendererViewProperties& viewProps = view.getProperties();
 		const RendererViewProperties& viewProps = view.getProperties();
 		RenderTargets& renderTargets = *view.getRenderTargets();
 		RenderTargets& renderTargets = *view.getRenderTargets();
 
 
-		mGBufferParams.bind(renderTargets);
-		mSceneColorTexture.set(renderTargets.get(RTT_ResolvedSceneColor));
-
 		SPtr<Texture> hiZ = renderTargets.get(RTT_HiZ);
 		SPtr<Texture> hiZ = renderTargets.get(RTT_HiZ);
 		const TextureProperties& hiZProps = hiZ->getProperties();
 		const TextureProperties& hiZProps = hiZ->getProperties();
+
+		mGBufferParams.bind(renderTargets);
+		mSceneColorTexture.set(renderTargets.get(RTT_ResolvedSceneColor));
+		mHiZTexture.set(hiZ);
 		
 		
 		Rect2I viewRect = viewProps.viewRect;
 		Rect2I viewRect = viewProps.viewRect;
 
 
@@ -1674,8 +1694,10 @@ namespace bs { namespace ct
 		// Maps from [0, 1] to are of HiZ where depth is stored in
 		// Maps from [0, 1] to are of HiZ where depth is stored in
 		ndcToUVMapping.x *= (float)viewRect.width / hiZProps.getWidth();
 		ndcToUVMapping.x *= (float)viewRect.width / hiZProps.getWidth();
 		ndcToUVMapping.y *= (float)viewRect.height / hiZProps.getHeight();
 		ndcToUVMapping.y *= (float)viewRect.height / hiZProps.getHeight();
+		ndcToUVMapping.z *= (float)viewRect.width / hiZProps.getWidth();
+		ndcToUVMapping.w *= (float)viewRect.height / hiZProps.getHeight();
 		
 		
-		Vector2I bufferSize(hiZProps.getWidth(), hiZProps.getHeight());
+		Vector2I bufferSize(viewRect.width, viewRect.height);
 		gSSRTraceParamDef.gHiZSize.set(mParamBuffer, bufferSize);
 		gSSRTraceParamDef.gHiZSize.set(mParamBuffer, bufferSize);
 		gSSRTraceParamDef.gHiZNumMips.set(mParamBuffer, hiZProps.getNumMipmaps());
 		gSSRTraceParamDef.gHiZNumMips.set(mParamBuffer, hiZProps.getNumMipmaps());
 		gSSRTraceParamDef.gHiZUVMapping.set(mParamBuffer, ndcToUVMapping);
 		gSSRTraceParamDef.gHiZUVMapping.set(mParamBuffer, ndcToUVMapping);
@@ -1919,7 +1941,7 @@ namespace bs { namespace ct
 
 
 
 
 
 
-		//// DEBUG ONLY
+		// DEBUG ONLY
 		//SSRTraceMat ssrTrace;
 		//SSRTraceMat ssrTrace;
 
 
 		//renderTargets->allocate(RTT_ResolvedSceneColorSecondary);
 		//renderTargets->allocate(RTT_ResolvedSceneColorSecondary);
@@ -1943,10 +1965,10 @@ namespace bs { namespace ct
 
 
 		mTonemapping.execute(gammaOnly, autoExposure, msaa, sceneColor, tonemapTarget, viewportRect, ppInfo);
 		mTonemapping.execute(gammaOnly, autoExposure, msaa, sceneColor, tonemapTarget, viewportRect, ppInfo);
 
 
-		//renderTargets->release(RTT_ResolvedSceneColorSecondary);
 
 
 
 
-		//// DEBUG ONLY
+		// DEBUG ONLY
+		//renderTargets->release(RTT_ResolvedSceneColorSecondary);
 		//return;
 		//return;