Browse Source

WIP: Deferred MSAA
- Indirect lighting shaders now only evaluate a single MSAA sample, as multi-sample quality is unnoticeable with low frequency data output by those shaders

BearishSun 8 years ago
parent
commit
7ba7031e3d

+ 16 - 4
Data/Raw/Engine/Shaders/IrradianceEvaluate.bsl

@@ -9,7 +9,7 @@ technique IrradianceEvaluate
 	mixin SHCommon;
 	mixin GBufferInput;
 	mixin PerCameraData;
-
+	
 	blend
 	{
 		target	
@@ -21,6 +21,10 @@ technique IrradianceEvaluate
 	
 	code
 	{
+		#ifndef MSAA_RESOLVE_0TH
+			#define MSAA_RESOLVE_0TH 0
+		#endif	
+	
 		#if MSAA_COUNT > 1
 			Texture2DMS<uint> gInputTex;
 		#else
@@ -161,7 +165,7 @@ technique IrradianceEvaluate
 		}
 		
 		float3 fsmain(VStoFS input
-			#if MSAA_COUNT > 1
+			#if MSAA_COUNT > 1 && !MSAA_RESOLVE_0TH
 			, uint sampleIdx : SV_SampleIndex
 			#endif
 			) : SV_Target0
@@ -170,7 +174,11 @@ technique IrradianceEvaluate
 		
 			SurfaceData surfaceData;
 			#if MSAA_COUNT > 1
-				surfaceData = getGBufferData(pixelPos, sampleIdx);
+				#if MSAA_RESOLVE_0TH
+					surfaceData = getGBufferData(pixelPos, 0);
+				#else
+					surfaceData = getGBufferData(pixelPos, sampleIdx);
+				#endif
 			#else
 				surfaceData = getGBufferData(pixelPos);
 			#endif		
@@ -181,7 +189,11 @@ technique IrradianceEvaluate
 			#else
 				uint volumeIdx;
 				#if MSAA_COUNT > 1
-					volumeIdx = gInputTex.Load(uint3(pixelPos, 0), sampleIdx).x;
+					#if MSAA_RESOLVE_0TH
+						volumeIdx = gInputTex.Load(uint3(pixelPos, 0), 0).x;
+					#else
+						volumeIdx = gInputTex.Load(uint3(pixelPos, 0), sampleIdx).x;
+					#endif
 				#else
 					volumeIdx = gInputTex.Load(uint3(pixelPos, 0)).x;
 				#endif

+ 11 - 3
Data/Raw/Engine/Shaders/TetrahedraRender.bsl

@@ -13,7 +13,7 @@ technique TetrahedraRender
 	{
 		compare = lte;
 	};
-
+	
 	code
 	{
 		struct VertexInput
@@ -43,6 +43,10 @@ technique TetrahedraRender
 		#ifndef MSAA
 			#define MSAA 0
 		#endif
+		
+		#ifndef MSAA_RESOLVE_0TH
+			#define MSAA_RESOLVE_0TH 0
+		#endif		
 
 		#if MSAA
 		Texture2DMS<float> gDepthBufferTex;
@@ -52,14 +56,18 @@ technique TetrahedraRender
 		#endif		
 		
 		uint fsmain(VStoFS input
-		#if MSAA
+		#if MSAA && !MSAA_RESOLVE_0TH
 			,uint sampleIdx : SV_SampleIndex
 		#endif
 		) : SV_Target0
 		{
 			float sceneDepth;
 			#if MSAA
-				sceneDepth = gDepthBufferTex.Load(trunc(input.position.xy), sampleIdx);
+				#if MSAA_RESOLVE_0TH
+					sceneDepth = gDepthBufferTex.Load(trunc(input.position.xy), 0);
+				#else
+					sceneDepth = gDepthBufferTex.Load(trunc(input.position.xy), sampleIdx);
+				#endif
 			#else
 				float2 ndcPos = input.clipPos.xy / input.clipPos.w;
 				sceneDepth = gDepthBufferTex.Sample(gDepthBufferSamp, NDCToUV(ndcPos));

+ 54 - 16
Source/RenderBeast/BsLightProbes.cpp

@@ -14,12 +14,16 @@
 
 namespace bs { namespace ct 
 {
-	ShaderVariation TetrahedraRenderMat::VAR_NoMSAA = ShaderVariation({
-		ShaderVariation::Param("MSAA", false)
+	ShaderVariation TetrahedraRenderMat::VAR_FullMSAA = ShaderVariation({
+		ShaderVariation::Param("MSAA", true)
 	});
 
-	ShaderVariation TetrahedraRenderMat::VAR_MSAA = ShaderVariation({
-		ShaderVariation::Param("MSAA", true)
+	ShaderVariation TetrahedraRenderMat::VAR_SingleMSAA = ShaderVariation({
+		ShaderVariation::Param("MSAA", true),
+		ShaderVariation::Param("MSAA_RESOLVE_0TH", true)
+	});
+
+	ShaderVariation TetrahedraRenderMat::VAR_NoMSAA = ShaderVariation({
 	});
 
 	TetrahedraRenderMat::TetrahedraRenderMat()
@@ -45,8 +49,9 @@ namespace bs { namespace ct
 
 	void TetrahedraRenderMat::_initVariations(ShaderVariations& variations)
 	{
+		variations.add(VAR_FullMSAA);
+		variations.add(VAR_SingleMSAA);
 		variations.add(VAR_NoMSAA);
-		variations.add(VAR_MSAA);
 	}
 
 	void TetrahedraRenderMat::execute(const RendererView& view, const SPtr<Texture>& sceneDepth, const SPtr<Mesh>& mesh, 
@@ -75,18 +80,31 @@ namespace bs { namespace ct
 		depthDesc = POOLED_RENDER_TEXTURE_DESC::create2D(PF_D32, width, height, TU_DEPTHSTENCIL, numSamples);
 	}
 
-	TetrahedraRenderMat* TetrahedraRenderMat::getVariation(bool msaa)
+	TetrahedraRenderMat* TetrahedraRenderMat::getVariation(bool msaa, bool singleSampleMSAA)
 	{
 		if (msaa)
-			return get(VAR_MSAA);
+		{
+			if (singleSampleMSAA)
+				return get(VAR_SingleMSAA);
+
+			return get(VAR_FullMSAA);
+		}
 
 		return get(VAR_NoMSAA);
 	}
 
 	IrradianceEvaluateParamDef gIrradianceEvaluateParamDef;
 
-	ShaderVariation IrradianceEvaluateMat::VAR_MSAA_Probes = ShaderVariation({
+	ShaderVariation IrradianceEvaluateMat::VAR_FullMSAA_Probes = ShaderVariation({
 		ShaderVariation::Param("MSAA_COUNT", 2),
+		ShaderVariation::Param("MSAA", true),
+		ShaderVariation::Param("SKY_ONLY", false)
+	});
+
+	ShaderVariation IrradianceEvaluateMat::VAR_SingleMSAA_Probes = ShaderVariation({
+		ShaderVariation::Param("MSAA_COUNT", 2),
+		ShaderVariation::Param("MSAA", true),
+		ShaderVariation::Param("MSAA_RESOLVE_0TH", true),
 		ShaderVariation::Param("SKY_ONLY", false)
 	});
 
@@ -95,8 +113,16 @@ namespace bs { namespace ct
 		ShaderVariation::Param("SKY_ONLY", false)
 	});
 
-	ShaderVariation IrradianceEvaluateMat::VAR_MSAA_Sky = ShaderVariation({
+	ShaderVariation IrradianceEvaluateMat::VAR_FullMSAA_Sky = ShaderVariation({
+		ShaderVariation::Param("MSAA_COUNT", 2),
+		ShaderVariation::Param("MSAA", true),
+		ShaderVariation::Param("SKY_ONLY", true)
+	});
+
+	ShaderVariation IrradianceEvaluateMat::VAR_SingleMSAA_Sky = ShaderVariation({
 		ShaderVariation::Param("MSAA_COUNT", 2),
+		ShaderVariation::Param("MSAA", true),
+		ShaderVariation::Param("MSAA_RESOLVE_0TH", true),
 		ShaderVariation::Param("SKY_ONLY", true)
 	});
 
@@ -128,8 +154,10 @@ namespace bs { namespace ct
 
 	void IrradianceEvaluateMat::_initVariations(ShaderVariations& variations)
 	{
-		variations.add(VAR_MSAA_Probes);
-		variations.add(VAR_MSAA_Sky);
+		variations.add(VAR_FullMSAA_Probes);
+		variations.add(VAR_FullMSAA_Sky);
+		variations.add(VAR_SingleMSAA_Probes);
+		variations.add(VAR_SingleMSAA_Sky);
 		variations.add(VAR_NoMSAA_Probes);
 		variations.add(VAR_NoMSAA_Sky);
 	}
@@ -183,19 +211,29 @@ namespace bs { namespace ct
 		rapi.setRenderTarget(nullptr);
 	}
 
-	IrradianceEvaluateMat* IrradianceEvaluateMat::getVariation(UINT32 msaaCount, bool skyOnly)
+	IrradianceEvaluateMat* IrradianceEvaluateMat::getVariation(bool msaa, bool singleSampleMSAA, bool skyOnly)
 	{
 		if(skyOnly)
 		{
-			if (msaaCount > 1)
-				return get(VAR_MSAA_Sky);
+			if (msaa)
+			{
+				if (singleSampleMSAA)
+					return get(VAR_SingleMSAA_Sky);
+
+				return get(VAR_FullMSAA_Sky);
+			}
 
 			return get(VAR_NoMSAA_Sky);
 		}
 		else
 		{
-			if (msaaCount > 1)
-				return get(VAR_MSAA_Probes);
+			if (msaa)
+			{
+				if (singleSampleMSAA)
+					return get(VAR_SingleMSAA_Probes);
+
+				return get(VAR_FullMSAA_Probes);
+			}
 
 			return get(VAR_NoMSAA_Probes);
 		}

+ 22 - 9
Source/RenderBeast/BsLightProbes.h

@@ -51,13 +51,21 @@ namespace bs { namespace ct
 		static void getOutputDesc(const RendererView& view, POOLED_RENDER_TEXTURE_DESC& colorDesc, 
 			POOLED_RENDER_TEXTURE_DESC& depthDesc);
 
-		/** Returns the material variation matching the provided parameters. */
-		static TetrahedraRenderMat* getVariation(bool msaa);
+		/** 
+		 * Returns the material variation matching the provided parameters. 
+		 * 
+		 * @param[in]	msaa				True if the shader will operate on a multisampled surface.
+		 * @param[in]	singleSampleMSAA	Only relevant of @p msaa is true. When enabled only the first sample will be
+		 *									evaluated. Otherwise all samples will be evaluated.
+		 * @return							Requested variation of the material.
+		 */
+		static TetrahedraRenderMat* getVariation(bool msaa, bool singleSampleMSAA);
 	private:
 		GpuParamTexture mDepthBufferTex;
 
+		static ShaderVariation VAR_FullMSAA;
+		static ShaderVariation VAR_SingleMSAA;
 		static ShaderVariation VAR_NoMSAA;
-		static ShaderVariation VAR_MSAA;
 	};
 
 	BS_PARAM_BLOCK_BEGIN(IrradianceEvaluateParamDef)
@@ -95,11 +103,14 @@ namespace bs { namespace ct
 		/** 
 		 * Returns the material variation matching the provided parameters. 
 		 *
-		 * @param[in]	msaaCount	Number of MSAA samples used by the view rendering the material.
-		 * @param[in]	skyOnly		When true, only the sky irradiance will be evaluated. Otherwise light probe irradiance
-		 *							will be evaluated.
+		 * @param[in]	msaa				True if the shader will operate on a multisampled surface.
+		 * @param[in]	singleSampleMSAA	Only relevant of @p msaa is true. When enabled only the first sample will be
+		 *									evaluated. Otherwise all samples will be evaluated.
+		 * @param[in]	skyOnly				When true, only the sky irradiance will be evaluated. Otherwise light probe 
+		 *									irradiance will be evaluated.
+		 * @return							Requested variation of the material.
 		 */
-		static IrradianceEvaluateMat* getVariation(UINT32 msaaCount, bool skyOnly);
+		static IrradianceEvaluateMat* getVariation(bool msaa, bool singleSampleMSAA, bool skyOnly);
 	private:
 		GBufferParams mGBufferParams;
 		SPtr<GpuParamBlockBuffer> mParamBuffer;
@@ -111,9 +122,11 @@ namespace bs { namespace ct
 		GpuParamBuffer mParamTetFacesBuffer;
 		bool mSkyOnly;
 
-		static ShaderVariation VAR_MSAA_Probes;
+		static ShaderVariation VAR_FullMSAA_Probes;
+		static ShaderVariation VAR_SingleMSAA_Probes;
 		static ShaderVariation VAR_NoMSAA_Probes;
-		static ShaderVariation VAR_MSAA_Sky;
+		static ShaderVariation VAR_FullMSAA_Sky;
+		static ShaderVariation VAR_SingleMSAA_Sky;
 		static ShaderVariation VAR_NoMSAA_Sky;
 	};
 

+ 3 - 3
Source/RenderBeast/BsRenderCompositor.cpp

@@ -751,17 +751,17 @@ namespace bs { namespace ct
 			rapi.clearRenderTarget(FBT_DEPTH);
 			gRendererUtility().clear(-1);
 
-			TetrahedraRenderMat* renderTetrahedra = TetrahedraRenderMat::getVariation(viewProps.numSamples > 1);
+			TetrahedraRenderMat* renderTetrahedra = TetrahedraRenderMat::getVariation(viewProps.numSamples > 1, true);
 			renderTetrahedra->execute(inputs.view, sceneDepthNode->depthTex->texture, lpInfo.tetrahedraVolume, rt);
 
 			rt = nullptr;
 			resPool.release(depthTex);
 
-			evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples, false);
+			evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples > 1, true, false);
 		}
 		else // Sky only
 		{
-			evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples, true);
+			evaluateMat = IrradianceEvaluateMat::getVariation(viewProps.numSamples > 1, true, true);
 		}
 
 		GBufferTextures gbuffer;