瀏覽代碼

WIP: Deferred MSAA

BearishSun 8 年之前
父節點
當前提交
c84241e674

+ 4 - 0
Data/Raw/Engine/DataList.json

@@ -369,6 +369,10 @@
         {
             "Path": "PPEncodeDepth.bsl",
             "UUID": "8bbf989a-9f8d-4864-8332-7f8c499685ba"
+        },
+        {
+            "Path": "MSAACoverage.bsl",
+            "UUID": "151465e1-e123-475d-97f5-77bc04bc15ce"
         }
     ],
     "Skin": [

+ 44 - 0
Data/Raw/Engine/Shaders/MSAACoverage.bsl

@@ -0,0 +1,44 @@
+#include "$ENGINE$\PPBase.bslinc"
+#include "$ENGINE$\GBufferInput.bslinc"
+#include "$ENGINE$\PerCameraData.bslinc"
+
+technique MSAACoverage
+{
+	mixin PPBase;
+	mixin GBufferInput;
+	mixin PerCameraData;
+
+	code
+	{	
+		float fsmain(VStoFS input) : SV_Target0
+		{
+			SurfaceData surfaceData[MSAA_COUNT];
+
+			[unroll]
+			for(uint i = 0; i < MSAA_COUNT; ++i)
+				surfaceData[i] = getGBufferData((int2)input.position.xy, i);
+
+			float3 albedo = surfaceData[0].albedo.xyz;
+			float3 normal = surfaceData[0].worldNormal.xyz;
+			float depth = surfaceData[0].depth;
+
+			[unroll]
+			for(int i = 1; i < MSAA_COUNT; i++)
+			{
+				float3 otherAlbedo = surfaceData[i].albedo.xyz;
+				float3 otherNormal = surfaceData[i].worldNormal.xyz;
+				float otherDepth = surfaceData[i].depth;
+
+				[branch]
+				if((abs(depth - otherDepth) > 0.01f) || 
+				   (dot(normal, otherNormal) < 0.99f) || 
+				   (abs(dot(albedo - otherAlbedo, float3(1, 1, 1))) > 0.01f))
+				{
+					return 1.0f;
+				}
+			}
+			
+			return 0.0f;			
+		}	
+	};
+};

+ 49 - 0
Source/RenderBeast/BsPostProcessing.cpp

@@ -1789,4 +1789,53 @@ namespace bs { namespace ct
 		gRendererUtility().setPassParams(mParamsSet);
 		gRendererUtility().drawScreenQuad();
 	}
+
+	ShaderVariation MSAACoverageMat::VAR_2x = ShaderVariation({
+		ShaderVariation::Param("MSAA_COUNT", 2)
+	});
+
+	ShaderVariation MSAACoverageMat::VAR_4x = ShaderVariation({
+		ShaderVariation::Param("MSAA_COUNT", 4)
+	});
+
+	ShaderVariation MSAACoverageMat::VAR_8x = ShaderVariation({
+		ShaderVariation::Param("MSAA_COUNT", 8)
+	});
+
+	MSAACoverageMat::MSAACoverageMat()
+		:mGBufferParams(mMaterial, mParamsSet)
+	{ }
+
+	void MSAACoverageMat::_initVariations(ShaderVariations& variations)
+	{
+		variations.add(VAR_2x);
+		variations.add(VAR_4x);
+		variations.add(VAR_8x);
+	}
+
+	void MSAACoverageMat::execute(const RendererView& view, GBufferTextures gbuffer) 
+	{
+		mGBufferParams.bind(gbuffer);
+
+		SPtr<GpuParamBlockBuffer> perView = view.getPerViewBuffer();
+		mParamsSet->setParamBlockBuffer("PerCamera", perView);
+
+		gRendererUtility().setPass(mMaterial);
+		gRendererUtility().setPassParams(mParamsSet);
+		gRendererUtility().drawScreenQuad();
+	}
+
+	MSAACoverageMat* MSAACoverageMat::getVariation(UINT32 msaaCount)
+	{
+		switch(msaaCount)
+		{
+		case 2:
+			return get(VAR_2x);
+		case 4:
+			return get(VAR_4x);
+		case 8:
+		default:
+			return get(VAR_8x);
+		}
+	}
 }}

+ 29 - 0
Source/RenderBeast/BsPostProcessing.h

@@ -821,5 +821,34 @@ namespace bs { namespace ct
 		GpuParamTexture mInputTexture;
 	};
 
+	/** 
+	 * Shader that outputs a texture that determines which pixels require per-sample evaluation. Only relevant when 
+	 * rendering with MSAA enabled.
+	 */
+	class MSAACoverageMat : public RendererMaterial<MSAACoverageMat>
+	{
+		RMAT_DEF("MSAACoverage.bsl");
+
+	public:
+		MSAACoverageMat();
+
+		/** 
+		 * Renders the effect with the provided parameters, using the currently bound render target. 
+		 * 
+		 * @param[in]	view			Information about the view we're rendering from.
+		 * @param[in]	gbuffer			GBuffer textures.
+		 */
+		void execute(const RendererView& view, GBufferTextures gbuffer);
+
+		/** Returns the material variation matching the provided parameters. */
+		static MSAACoverageMat* getVariation(UINT32 msaaCount);
+	private:
+		GBufferParams mGBufferParams;
+
+		static ShaderVariation VAR_2x;
+		static ShaderVariation VAR_4x;
+		static ShaderVariation VAR_8x;
+	};
+
 	/** @} */
 }}

+ 1 - 0
Source/RenderBeast/BsRenderBeast.cpp

@@ -97,6 +97,7 @@ namespace bs { namespace ct
 		RenderCompositor::registerNodeType<RCNodeClusteredForward>();
 		RenderCompositor::registerNodeType<RCNodeIndirectLighting>();
 		RenderCompositor::registerNodeType<RCNodeSSR>();
+		RenderCompositor::registerNodeType<RCNodeMSAACoverage>();
 	}
 
 	void RenderBeast::destroyCore()

+ 36 - 0
Source/RenderBeast/BsRenderCompositor.cpp

@@ -405,6 +405,42 @@ namespace bs { namespace ct
 		return { RCNodeSceneDepth::getNodeId() };
 	}
 
+	void RCNodeMSAACoverage::render(const RenderCompositorNodeInputs& inputs)
+	{
+		GpuResourcePool& resPool = GpuResourcePool::instance();
+		const RendererViewProperties& viewProps = inputs.view.getProperties();
+
+		UINT32 width = viewProps.viewRect.width;
+		UINT32 height = viewProps.viewRect.height;
+
+		output = resPool.get(POOLED_RENDER_TEXTURE_DESC::create2D(PF_R8, width, height, TU_RENDERTARGET));
+
+		RCNodeGBuffer* gbufferNode = static_cast<RCNodeGBuffer*>(inputs.inputNodes[0]);
+		RCNodeSceneDepth* sceneDepthNode = static_cast<RCNodeSceneDepth*>(inputs.inputNodes[1]);
+
+		GBufferTextures gbuffer;
+		gbuffer.albedo = gbufferNode->albedoTex->texture;
+		gbuffer.normals = gbufferNode->normalTex->texture;
+		gbuffer.roughMetal = gbufferNode->roughMetalTex->texture;
+		gbuffer.depth = sceneDepthNode->depthTex->texture;
+
+		MSAACoverageMat* mat = MSAACoverageMat::getVariation(viewProps.numSamples);
+
+		RenderAPI::instance().setRenderTarget(output->renderTexture);
+		mat->execute(inputs.view, gbuffer);
+	}
+
+	void RCNodeMSAACoverage::clear()
+	{
+		GpuResourcePool& resPool = GpuResourcePool::instance();
+		resPool.release(output);
+	}
+
+	SmallVector<StringID, 4> RCNodeMSAACoverage::getDependencies(const RendererView& view)
+	{
+		return { RCNodeGBuffer::getNodeId(), RCNodeSceneDepth::getNodeId() };
+	}
+
 	void RCNodeLightAccumulation::render(const RenderCompositorNodeInputs& inputs)
 	{
 		GpuResourcePool& resPool = GpuResourcePool::instance();

+ 21 - 0
Source/RenderBeast/BsRenderCompositor.h

@@ -239,6 +239,27 @@ namespace ct
 		void clear() override;
 	};
 
+	/**
+	 * Determines which samples in the GBuffer require per-sample shading and outputs a texture with the coverage (for use
+	 * in compute shaders) and populates the primary stencil buffer as well (for use in non-compute shaders). Only relevant
+	 * when rendering with MSAA enabled.
+	 */
+	class RCNodeMSAACoverage : public RenderCompositorNode
+	{
+	public:
+		// Outputs
+		SPtr<PooledRenderTexture> output;
+
+		static StringID getNodeId() { return "MSAACoverage"; }
+		static SmallVector<StringID, 4> getDependencies(const RendererView& view);
+	protected:
+		/** @copydoc RenderCompositorNode::render */
+		void render(const RenderCompositorNodeInputs& inputs) override;
+
+		/** @copydoc RenderCompositorNode::clear */
+		void clear() override;
+	};
+
 	/************************************************************************/
 	/* 							LIGHTING NODES                     			*/
 	/************************************************************************/