Просмотр исходного кода

Feature: Deferred MSAA
- MSAA using deferred rendering now fully functional. Uses a coverage mask texture & stencil to ensure all materials only operate on a per-sample basis where necessary to avoid wasting performance.

BearishSun 8 лет назад
Родитель
Сommit
b1f8ff1a17

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

@@ -18,6 +18,10 @@ technique PPSSRStencil
 	
 	code
 	{
+		#ifndef MSAA_RESOLVE_0TH
+			#define MSAA_RESOLVE_0TH 0
+		#endif	
+	
 		[internal]
 		cbuffer Input
 		{
@@ -25,15 +29,19 @@ technique PPSSRStencil
 		}
 		
 		float fsmain(VStoFS input			
-		#if MSAA_COUNT > 1 
+		#if MSAA_COUNT > 1 && !MSAA_RESOLVE_0TH
 			, uint sampleIdx : SV_SampleIndex
 		#endif
 		) : SV_Target0
 		{
 			#if MSAA_COUNT > 1 
-			SurfaceData surfData = getGBufferData(trunc(input.position.xy), sampleIdx);
+				#if MSAA_RESOLVE_0TH
+					SurfaceData surfData = getGBufferData(trunc(input.position.xy), 0);
+				#else
+					SurfaceData surfData = getGBufferData(trunc(input.position.xy), sampleIdx);
+				#endif
 			#else
-			SurfaceData surfData = getGBufferData(input.uv0);
+				SurfaceData surfData = getGBufferData(input.uv0);
 			#endif
 			
 			// Surfaces that are too rough fall back to refl. probes

+ 3 - 0
Data/Raw/Engine/Shaders/PPTonemapping.bsl

@@ -83,6 +83,9 @@ technique PPTonemapping
 		{
 			float4 sceneColor = 0;
 			#if MSAA
+				// Note: Ideally I'd want to use the MSAA coverage texture here, so I can only average samples for pixels
+				// that really need it. But because forward rendering doesn't write to MSAA coverage I can't do it as I
+				// don't have up-to-date coverage information. It might be good to find a way around this.
 				for(uint i = 0; i < gNumSamples; ++i)
 					sceneColor.rgb += tonemapSample(gInputTex.Load(trunc(input.uv0), i).rgb, input.exposureScale);
 			

+ 18 - 7
Source/RenderBeast/BsPostProcessing.cpp

@@ -1358,12 +1358,17 @@ namespace bs { namespace ct
 
 	SSRStencilParamDef gSSRStencilParamDef;
 
-	ShaderVariation SSRStencilMat::VAR_NoMSAA = ShaderVariation({
-		ShaderVariation::Param("MSAA_COUNT", 1)
+	ShaderVariation SSRStencilMat::VAR_FullMSAA = ShaderVariation({
+		ShaderVariation::Param("MSAA_COUNT", 2)
 	});
 
-	ShaderVariation SSRStencilMat::VAR_MSAA = ShaderVariation({
-		ShaderVariation::Param("MSAA_COUNT", 2)
+	ShaderVariation SSRStencilMat::VAR_SingleMSAA = ShaderVariation({
+		ShaderVariation::Param("MSAA_COUNT", 2),
+		ShaderVariation::Param("MSAA_RESOLVE_0TH", true)
+	});
+
+	ShaderVariation SSRStencilMat::VAR_NoMSAA = ShaderVariation({
+		ShaderVariation::Param("MSAA_COUNT", 1)
 	});
 
 	SSRStencilMat::SSRStencilMat()
@@ -1375,7 +1380,8 @@ namespace bs { namespace ct
 
 	void SSRStencilMat::_initVariations(ShaderVariations& variations)
 	{
-		variations.add(VAR_MSAA);
+		variations.add(VAR_FullMSAA);
+		variations.add(VAR_SingleMSAA);
 		variations.add(VAR_NoMSAA);
 	}
 
@@ -1395,10 +1401,15 @@ namespace bs { namespace ct
 		gRendererUtility().drawScreenQuad();
 	}
 
-	SSRStencilMat* SSRStencilMat::getVariation(bool msaa)
+	SSRStencilMat* SSRStencilMat::getVariation(bool msaa, bool singleSampleMSAA)
 	{
 		if (msaa)
-			return get(VAR_MSAA);
+		{
+			if (singleSampleMSAA)
+				return get(VAR_SingleMSAA);
+
+			return get(VAR_FullMSAA);
+		}
 		else
 			return get(VAR_NoMSAA);
 	}

+ 11 - 3
Source/RenderBeast/BsPostProcessing.h

@@ -636,14 +636,22 @@ namespace bs { namespace ct
 		 */
 		void execute(const RendererView& view, GBufferTextures gbuffer, const ScreenSpaceReflectionsSettings& settings);
 
-		/** Returns the material variation matching the provided parameters. */
-		static SSRStencilMat* 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 SSRStencilMat* getVariation(bool msaa, bool singleSampleMSAA);
 	private:
 		SPtr<GpuParamBlockBuffer> mParamBuffer;
 		GBufferParams mGBufferParams;
 
+		static ShaderVariation VAR_FullMSAA;
+		static ShaderVariation VAR_SingleMSAA;
 		static ShaderVariation VAR_NoMSAA;
-		static ShaderVariation VAR_MSAA;
 	};
 
 	BS_PARAM_BLOCK_BEGIN(SSRTraceParamDef)

+ 2 - 2
Source/RenderBeast/BsRenderCompositor.cpp

@@ -1837,7 +1837,7 @@ namespace bs { namespace ct
 			gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
 			gbuffer.depth = sceneDepthNode->depthTex->texture;
 
-			SSRStencilMat* stencilMat = SSRStencilMat::getVariation(viewProps.numSamples > 1);
+			SSRStencilMat* stencilMat = SSRStencilMat::getVariation(viewProps.numSamples > 1, true);
 
 			// Note: Making the assumption that the stencil buffer is clear at this point
 			rapi.setRenderTarget(resolvedSceneDepthNode->output->renderTexture);
@@ -1855,7 +1855,7 @@ namespace bs { namespace ct
 			rapi.setRenderTarget(traceRt);
 			rapi.clearRenderTarget(FBT_COLOR);
 
-			SSRTraceMat* traceMat = SSRTraceMat::getVariation(settings.quality, viewProps.numSamples > 1);
+			SSRTraceMat* traceMat = SSRTraceMat::getVariation(settings.quality, viewProps.numSamples > 1, true);
 			traceMat->execute(inputs.view, gbuffer, sceneColor, hiZ, settings, traceRt);
 
 			if (resolvedSceneColor)