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

Env. sampling data now bound to tile deferred shader

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

+ 36 - 8
Source/RenderBeast/Include/BsLightRendering.h

@@ -5,6 +5,7 @@
 #include "BsRenderBeastPrerequisites.h"
 #include "BsRendererMaterial.h"
 #include "BsParamBlocks.h"
+#include "BsReflectionProbeSampling.h"
 
 namespace bs { namespace ct
 {
@@ -82,11 +83,18 @@ namespace bs { namespace ct
 		TiledDeferredLighting(const SPtr<Material>& material, const SPtr<GpuParamsSet>& paramsSet, UINT32 sampleCount);
 
 		/** Binds the material for rendering, sets up parameters and executes it. */
-		void execute(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBuffer>& perCamera, bool noLighting);
+		void execute(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBuffer>& perCamera, 
+                     const SPtr<Texture>& preintegratedGF, bool noLighting);
 
 		/** Binds all the active lights. */
 		void setLights(const GPULightData& lightData);
 
+        /** Binds all the active reflection probes. */
+        void setReflectionProbes(const GPUReflProbeData& probeData, const SPtr<Texture>& reflectionCubemaps);
+
+        /** Binds the sky reflection. If no sky reflection set to null. */
+        void setSkyReflections(const SPtr<Texture>& skyReflections);
+
 		/** 
 		 * Generates a 2D 2-channel texture containing a pre-integrated G and F factors of the microfactet BRDF. This is an
 		 * approximation used for image based lighting, so we can avoid sampling environment maps for each light. Works in
@@ -108,12 +116,18 @@ namespace bs { namespace ct
 		GpuParamTexture mGBufferC;
 		GpuParamTexture mGBufferDepth;
 
+        GpuParamTexture mSkyCubemapTexParam;
+        GpuParamTexture mReflectionProbeCubemapsParam;
+        GpuParamTexture mPreintegratedEnvBRDFParam;
+        GpuParamBuffer mReflectionProbesParam;
+
 		Vector3I mLightOffsets;
 		GpuParamBuffer mLightBufferParam;
 		GpuParamLoadStoreTexture mOutputTextureParam;
 		GpuParamBuffer mOutputBufferParam;
 
 		SPtr<GpuParamBlockBuffer> mParamBuffer;
+        SPtr<GpuParamBlockBuffer> mReflectionsParamBuffer;
 	};
 
 	/** Interface implemented by all versions of TTiledDeferredLightingMat<T>. */
@@ -122,11 +136,18 @@ namespace bs { namespace ct
 	public:
 		virtual ~ITiledDeferredLightingMat() {}
 
-		/** Binds the material for rendering, sets up parameters and executes it. */
-		virtual void execute(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBuffer>& perCamera, bool noLighting) = 0;
+        /** @copydoc TiledDeferredLighting::execute() */
+		virtual void execute(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBuffer>& perCamera, 
+                             const SPtr<Texture>& preintegratedGF, bool noLighting) = 0;
 
-		/** Binds all the active lights. */
+        /** @copydoc TiledDeferredLighting::setLights() */
 		virtual void setLights(const GPULightData& lightData) = 0;
+
+        /** @copydoc TiledDeferredLighting::setReflectionProbes() */
+        virtual void setReflectionProbes(const GPUReflProbeData& probeData, const SPtr<Texture>& reflectionCubemaps) = 0;
+
+        /** @copydoc TiledDeferredLighting::setSkyReflections() */
+        virtual void setSkyReflections(const SPtr<Texture>& skyReflections) = 0;
 	};
 
 	/** Shader that performs a lighting pass over data stored in the Gbuffer. */
@@ -138,11 +159,18 @@ namespace bs { namespace ct
 	public:
 		TTiledDeferredLightingMat();
 
-		/** Binds the material for rendering, sets up parameters and executes it. */
-		void execute(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBuffer>& perCamera, bool noLighting) override;
+		/** @copydoc ITiledDeferredLightingMat::execute() */
+		void execute(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBuffer>& perCamera, 
+                     const SPtr<Texture>& preintegratedGF, bool noLighting) override;
 
-		/** Binds all the active lights. */
+        /** @copydoc ITiledDeferredLightingMat::setLights() */
 		void setLights(const GPULightData& lightData) override;
+
+        /** @copydoc ITiledDeferredLightingMat::setReflectionProbes() */
+        void setReflectionProbes(const GPUReflProbeData& probeData, const SPtr<Texture>& reflectionCubemaps) override;
+
+        /** @copydoc ITiledDeferredLightingMat::setSkyReflections() */
+        void setSkyReflections(const SPtr<Texture>& skyReflections) override;
 	private:
 		TiledDeferredLighting mInternal;
 	};
@@ -188,4 +216,4 @@ namespace bs { namespace ct
 	};
 
 	/** @} */
-}}
+}}

+ 2 - 1
Source/RenderBeast/Include/BsRenderBeast.h

@@ -241,7 +241,7 @@ namespace bs
 		Vector<RendererReflectionProbe> mReflProbes;
 		Vector<Sphere> mReflProbeWorldBounds;
 		Vector<bool> mCubemapArrayUsedSlots;
-		SPtr<Texture> mCubemapArrayTex;
+		SPtr<Texture> mReflCubemapArrayTex;
 
 		SPtr<RenderBeastOptions> mCoreOptions;
 
@@ -255,6 +255,7 @@ namespace bs
         SPtr<Texture> mSkyboxTexture;
         SPtr<Texture> mSkyboxFilteredReflections;
 
+        SPtr<Texture> mPreintegratedEnvBRDF;
 		GPULightData* mGPULightData;
 		GPUReflProbeData* mGPUReflProbeData;
 		LightGrid* mLightGrid;

+ 58 - 12
Source/RenderBeast/Source/BsLightRendering.cpp

@@ -114,10 +114,20 @@ namespace bs { namespace ct
 
 		mParamBuffer = gTiledLightingParamDef.createBuffer();
 		mParamsSet->setParamBlockBuffer("Params", mParamBuffer, true);
+
+        // Reflections
+        params->getTextureParam(GPT_COMPUTE_PROGRAM, "gSkyCubemapTex", mSkyCubemapTexParam);
+        params->getTextureParam(GPT_COMPUTE_PROGRAM, "gReflProbeCubmaps", mReflectionProbeCubemapsParam);
+        params->getTextureParam(GPT_COMPUTE_PROGRAM, "gPreintegratedEnvBRDF", mPreintegratedEnvBRDFParam);
+
+        params->getBufferParam(GPT_COMPUTE_PROGRAM, "gReflectionProbes", mReflectionProbesParam);
+
+        mReflectionsParamBuffer = gReflProbeParamsParamDef.createBuffer();
+        mParamsSet->setParamBlockBuffer("ReflProbeParams", mReflectionsParamBuffer);
 	}
 
-	void TiledDeferredLighting::execute(const SPtr<RenderTargets>& gbuffer,
-										const SPtr<GpuParamBlockBuffer>& perCamera, bool noLighting)
+	void TiledDeferredLighting::execute(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBuffer>& perCamera, 
+        const SPtr<Texture>& preintegratedGF, bool noLighting)
 	{
 		Vector2I framebufferSize;
 		framebufferSize[0] = gbuffer->getWidth();
@@ -138,12 +148,15 @@ namespace bs { namespace ct
 			gTiledLightingParamDef.gLightOffsets.set(mParamBuffer, mLightOffsets);
 		}
 		mParamBuffer->flushToGPU();
+        mReflectionsParamBuffer->flushToGPU();
 
 		mGBufferA.set(gbuffer->getTextureA());
 		mGBufferB.set(gbuffer->getTextureB());
 		mGBufferC.set(gbuffer->getTextureC());
 		mGBufferDepth.set(gbuffer->getTextureDepth());
 
+        mPreintegratedEnvBRDFParam.set(preintegratedGF);
+
 		mParamsSet->setParamBlockBuffer("PerCamera", perCamera, true);
 
 		const RenderAPIInfo& rapiInfo = RenderAPI::instance().getAPIInfo();
@@ -179,6 +192,37 @@ namespace bs { namespace ct
 		mLightOffsets[2] = mLightOffsets[1] + lightData.getNumSpotLights();
 	}
 
+    void TiledDeferredLighting::setReflectionProbes(const GPUReflProbeData& probeData, 
+                                                    const SPtr<Texture>& reflectionCubemaps)
+	{
+        mReflectionProbesParam.set(probeData.getProbeBuffer());
+        mReflectionProbeCubemapsParam.set(reflectionCubemaps);
+
+        gReflProbeParamsParamDef.gNumProbes.set(mReflectionsParamBuffer, probeData.getNumProbes());
+
+        UINT32 maxMip = 0;
+        if (reflectionCubemaps != nullptr)
+            maxMip = reflectionCubemaps->getProperties().getNumMipmaps();
+
+        gReflProbeParamsParamDef.gReflCubemapNumMips.set(mReflectionsParamBuffer, maxMip);
+	}
+
+    void TiledDeferredLighting::setSkyReflections(const SPtr<Texture>& skyReflections)
+	{
+        mSkyCubemapTexParam.set(skyReflections);
+
+        UINT32 skyReflectionsAvailable = 0;
+        UINT32 maxMip = 0;
+        if (skyReflections != nullptr)
+        {
+            maxMip = skyReflections->getProperties().getNumMipmaps();
+            skyReflectionsAvailable = 1;
+        }
+
+        gReflProbeParamsParamDef.gSkyCubemapNumMips.set(mReflectionsParamBuffer, maxMip);
+        gReflProbeParamsParamDef.gSkyCubemapAvailable.set(mReflectionsParamBuffer, skyReflectionsAvailable);
+	}
+
 	// Reverse bits functions used for Hammersley sequence
 	float reverseBits(UINT32 bits)
 	{
@@ -329,9 +373,9 @@ namespace bs { namespace ct
 
 	template<int MSAA_COUNT, bool FixedReflColor>
 	void TTiledDeferredLightingMat<MSAA_COUNT, FixedReflColor>::execute(const SPtr<RenderTargets>& gbuffer,
-													const SPtr<GpuParamBlockBuffer>& perCamera, bool noLighting)
+         const SPtr<GpuParamBlockBuffer>& perCamera, const SPtr<Texture>& preintegratedGF, bool noLighting)
 	{
-		mInternal.execute(gbuffer, perCamera, noLighting);
+		mInternal.execute(gbuffer, perCamera, preintegratedGF, noLighting);
 	}
 
 	template<int MSAA_COUNT, bool FixedReflColor>
@@ -340,15 +384,17 @@ namespace bs { namespace ct
 		mInternal.setLights(lightData);
 	}
 
-	template class TTiledDeferredLightingMat<1, false>;
-	template class TTiledDeferredLightingMat<2, false>;
-	template class TTiledDeferredLightingMat<4, false>;
-	template class TTiledDeferredLightingMat<8, false>;
+    template<int MSAA_COUNT, bool FixedReflColor>
+    void TTiledDeferredLightingMat<MSAA_COUNT, FixedReflColor>::setReflectionProbes(const GPUReflProbeData& probeData, const SPtr<Texture>& reflectionCubemaps)
+	{
+        mInternal.setReflectionProbes(probeData, reflectionCubemaps);
+	}
 
-    template class TTiledDeferredLightingMat<1, true>;
-    template class TTiledDeferredLightingMat<2, true>;
-    template class TTiledDeferredLightingMat<4, true>;
-    template class TTiledDeferredLightingMat<8, true>;
+    template<int MSAA_COUNT, bool FixedReflColor>
+    void TTiledDeferredLightingMat<MSAA_COUNT, FixedReflColor>::setSkyReflections(const SPtr<Texture>& skyReflections)
+	{
+        mInternal.setSkyReflections(skyReflections);
+	}
 
     TiledDeferredLightingMaterials::TiledDeferredLightingMaterials()
     {

+ 14 - 8
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -94,6 +94,7 @@ namespace bs { namespace ct
 
 		mTiledDeferredLightingMats = bs_new<TiledDeferredLightingMaterials>();
 
+        mPreintegratedEnvBRDF = TiledDeferredLighting::generatePreintegratedEnvBRDF();
 		mGPULightData = bs_new<GPULightData>();
 		mGPUReflProbeData = bs_new<GPUReflProbeData>();
 		mLightGrid = bs_new<LightGrid>();
@@ -118,7 +119,7 @@ namespace bs { namespace ct
 		mRenderables.clear();
 		mRenderableVisibility.clear();
 
-		mCubemapArrayTex = nullptr;
+		mReflCubemapArrayTex = nullptr;
         mSkyboxTexture = nullptr;
         mSkyboxFilteredReflections = nullptr;
 
@@ -134,6 +135,8 @@ namespace bs { namespace ct
 		bs_delete(mFlatFramebufferToTextureMat);
 		bs_delete(mTiledDeferredLightingMats);
 
+        mPreintegratedEnvBRDF = nullptr;
+
 		RendererUtility::shutDown();
 
 		assert(mSamplerOverrides.empty());
@@ -1032,7 +1035,10 @@ namespace bs { namespace ct
 		ITiledDeferredLightingMat* lightingMat = mTiledDeferredLightingMats->get(numSamples, viewInfo->isRenderingReflections());
 
 		lightingMat->setLights(*mGPULightData);
-		lightingMat->execute(renderTargets, perCameraBuffer, viewInfo->renderWithNoLighting());
+        lightingMat->setReflectionProbes(*mGPUReflProbeData, mReflCubemapArrayTex);
+        lightingMat->setSkyReflections(mSkyboxFilteredReflections);
+
+		lightingMat->execute(renderTargets, perCameraBuffer, mPreintegratedEnvBRDF, viewInfo->renderWithNoLighting());
 
 		const RenderAPIInfo& rapiInfo = RenderAPI::instance().getAPIInfo();
 		bool usingFlattenedFB = numSamples > 1 && !rapiInfo.isFlagSet(RenderAPIFeatureFlag::MSAAImageStores);
@@ -1220,11 +1226,11 @@ namespace bs { namespace ct
 		{		
             UINT32 currentCubeArraySize = 0;
 		    
-            if(mCubemapArrayTex != nullptr)
-		        mCubemapArrayTex->getProperties().getNumArraySlices();
+            if(mReflCubemapArrayTex != nullptr)
+		        mReflCubemapArrayTex->getProperties().getNumArraySlices();
 
 			bool forceArrayUpdate = false;
-			if(mCubemapArrayTex == nullptr || (currentCubeArraySize < numProbes && currentCubeArraySize != MaxReflectionCubemaps))
+			if(mReflCubemapArrayTex == nullptr || (currentCubeArraySize < numProbes && currentCubeArraySize != MaxReflectionCubemaps))
 			{
 				TEXTURE_DESC cubeMapDesc;
 				cubeMapDesc.type = TEX_TYPE_CUBE_MAP;
@@ -1234,12 +1240,12 @@ namespace bs { namespace ct
 				cubeMapDesc.numMips = PixelUtil::getMaxMipmaps(cubeMapDesc.width, cubeMapDesc.height, 1, cubeMapDesc.format);
 				cubeMapDesc.numArraySlices = std::min(MaxReflectionCubemaps, numProbes + 4); // Keep a few empty entries
 
-				mCubemapArrayTex = Texture::create(cubeMapDesc);
+				mReflCubemapArrayTex = Texture::create(cubeMapDesc);
 
 				forceArrayUpdate = true;
 			}
 
-			auto& cubemapArrayProps = mCubemapArrayTex->getProperties();
+			auto& cubemapArrayProps = mReflCubemapArrayTex->getProperties();
 
 			TEXTURE_DESC cubemapDesc;
 			cubemapDesc.type = TEX_TYPE_CUBE_MAP;
@@ -1326,7 +1332,7 @@ namespace bs { namespace ct
 					{
 						for(UINT32 face = 0; face < 6; face++)
 							for(UINT32 mip = 0; mip <= srcProps.getNumMipmaps(); mip++)
-								probeInfo.texture->copy(mCubemapArrayTex, face, mip, probeInfo.arrayIdx * 6 + face, mip);
+								probeInfo.texture->copy(mReflCubemapArrayTex, face, mip, probeInfo.arrayIdx * 6 + face, mip);
 					}
 
 					probeInfo.arrayDirty = false;