소스 검색

Finished code for rendering a full-screen quad
Added a way to bind the gbuffer to the light rendering shaders

BearishSun 10 년 전
부모
커밋
6487e23cb7

+ 1 - 1
BansheeCore/Include/BsRendererUtility.h

@@ -39,7 +39,7 @@ namespace BansheeEngine
 		 * 			
 		 * @note	Core thread.
 		 */
-		void drawScreenQuad(const CameraCore& camera);
+		void drawScreenQuad(const ViewportCore& viewport);
 
 	private:
 		SPtr<MeshCore> mFullScreenQuadMesh;

+ 15 - 3
BansheeCore/Source/BsRendererUtility.cpp

@@ -158,18 +158,30 @@ namespace BansheeEngine
 		mesh->_notifyUsedOnGPU();
 	}
 
-	void RendererUtility::drawScreenQuad(const CameraCore& camera)
+	void RendererUtility::drawScreenQuad(const ViewportCore& viewport)
 	{
 		// Note: Consider drawing the quad using a single large triangle for possibly better performance
 		Vector3 vertices[4];
 
-		// TODO - Set up vertices
+		Rect2I viewArea = viewport.getArea();
 
+		vertices[0] = Vector3((float)viewArea.x, (float)viewArea.y, 0.0f);
+		vertices[1] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y, 0.0f);
+		vertices[2] = Vector3((float)viewArea.x, (float)viewArea.y + (float)viewArea.height, 0.0f);
+		vertices[3] = Vector3((float)viewArea.x + (float)viewArea.width, (float)viewArea.y + (float)viewArea.width, 0.0f);
+
+		auto targetProps = viewport.getTarget()->getProperties();;
+
+		RenderAPICore& rapi = RenderAPICore::instance();
+		for (int i = 0; i < 4; i++)
+		{
+			vertices[i].x = -1.0f + 2.0f * (vertices[i].x + rapi.getHorizontalTexelOffset()) / targetProps.getWidth();
+			vertices[i].y = 1.0f - 2.0f * (vertices[i].y + rapi.getVerticalTexelOffset()) / targetProps.getHeight();
+		}
 
 		SPtr<VertexBufferCore> vb = mFullScreenQuadMesh->getVertexData()->getBuffer(0);
 		vb->writeData(0, sizeof(vertices), vertices, BufferWriteType::Discard);
 
-		RenderAPICore& rapi = RenderAPICore::instance();
 		draw(mFullScreenQuadMesh, mFullScreenQuadMesh->getProperties().getSubMesh());
 	}
 

+ 16 - 0
RenderBeast/Include/BsLightRendering.h

@@ -43,12 +43,20 @@ namespace BansheeEngine
 	public:
 		DirectionalLightMat();
 
+		/**
+		 * Binds the gbuffer used for rendering the light.
+		 */
+		void setGBuffer(const SPtr<RenderTargets>& gbuffer);
+
 		/**
 		 * Updates the parameter buffers used by the material.
 		 */
 		void setParameters(const LightCore* light);
 	private:
 		PerLightParams mParams; // Note: Should this buffer be shared between both point and directional lights?
+		MaterialParamTextureCore mGBufferA;
+		MaterialParamTextureCore mGBufferB;
+		MaterialParamTextureCore mGBufferDepth;
 	};
 
 	/**
@@ -61,11 +69,19 @@ namespace BansheeEngine
 	public:
 		PointLightMat();
 
+		/**
+		 * Binds the gbuffer used for rendering the light.
+		 */
+		void setGBuffer(const SPtr<RenderTargets>& gbuffer);
+
 		/**
 		 * Updates the parameter buffers used by the material.
 		 */
 		void setParameters(const LightCore* light);
 	private:
 		PerLightParams mParams; // Note: Should this buffer be shared between both point and directional lights?
+		MaterialParamTextureCore mGBufferA;
+		MaterialParamTextureCore mGBufferB;
+		MaterialParamTextureCore mGBufferDepth;
 	};
 }

+ 3 - 1
RenderBeast/Include/BsRenderBeast.h

@@ -16,7 +16,9 @@ namespace BansheeEngine
 	 * Semantics that may be used for signaling the renderer
 	 * for what is a certain shader parameter used for.
 	 */
-	static StringID RPS_Time = "Time";
+	static StringID RPS_GBufferA = "GBufferA";
+	static StringID RPS_GBufferB = "GBufferB";
+	static StringID RPS_GBufferDepth = "GBufferDepth";
 
 	/** Basic shader that is used when no other is available. */
 	class DefaultMaterial : public RendererMaterial<DefaultMaterial> { RMAT_DEF("Default.bsl"); };

+ 15 - 0
RenderBeast/Include/BsRenderTargets.h

@@ -39,6 +39,21 @@ namespace BansheeEngine
 		 */
 		void unbind();
 
+		/**
+		 * @brief	Returns the first color texture of the gbuffer as a bindable texture.
+		 */
+		SPtr<TextureCore> getTextureA() const;
+
+		/**
+		* @brief	Returns the second color texture of the gbuffer as a bindable texture.
+		*/
+		SPtr<TextureCore> getTextureB() const;
+
+		/**
+		 * @brief	Returns the depth texture of the gbuffer as a bindable texture.
+		 */
+		SPtr<TextureCore> getTextureDepth() const;
+
 		/**
 		 * @brief	Checks if the targets support HDR rendering.
 		 */

+ 39 - 1
RenderBeast/Source/BsLightRendering.cpp

@@ -1,9 +1,11 @@
 #include "BsLightRendering.h"
 #include "BsMaterial.h"
+#include "BsShader.h"
+#include "BsRenderBeast.h"
+#include "BsRenderTargets.h"
 #include "BsGpuParams.h"
 #include "BsLight.h"
 
-
 namespace BansheeEngine
 {
 	void PerLightParams::setParameters(const LightCore* light)
@@ -62,6 +64,24 @@ namespace BansheeEngine
 	DirectionalLightMat::DirectionalLightMat()
 	{
 		mMaterial->setParamBlockBuffer("PerLight", mParams.getBuffer());
+
+		auto& texParams = mMaterial->getShader()->getTextureParams();
+		for (auto& entry : texParams)
+		{
+			if (entry.second.rendererSemantic == RPS_GBufferA)
+				mGBufferA = mMaterial->getParamTexture(entry.second.name);
+			else if (entry.second.rendererSemantic == RPS_GBufferB)
+				mGBufferB = mMaterial->getParamTexture(entry.second.name);
+			else if (entry.second.rendererSemantic == RPS_GBufferDepth)
+				mGBufferDepth = mMaterial->getParamTexture(entry.second.name);
+		}
+	}
+
+	void DirectionalLightMat::setGBuffer(const SPtr<RenderTargets>& gbuffer)
+	{
+		mGBufferA.set(gbuffer->getTextureA());
+		mGBufferB.set(gbuffer->getTextureB());
+		mGBufferDepth.set(gbuffer->getTextureDepth());
 	}
 
 	void DirectionalLightMat::setParameters(const LightCore* light)
@@ -72,6 +92,24 @@ namespace BansheeEngine
 	PointLightMat::PointLightMat()
 	{
 		mMaterial->setParamBlockBuffer("PerLight", mParams.getBuffer());
+
+		auto& texParams = mMaterial->getShader()->getTextureParams();
+		for (auto& entry : texParams)
+		{
+			if (entry.second.rendererSemantic == RPS_GBufferA)
+				mGBufferA = mMaterial->getParamTexture(entry.second.name);
+			else if (entry.second.rendererSemantic == RPS_GBufferB)
+				mGBufferB = mMaterial->getParamTexture(entry.second.name);
+			else if (entry.second.rendererSemantic == RPS_GBufferDepth)
+				mGBufferDepth = mMaterial->getParamTexture(entry.second.name);
+		}
+	}
+
+	void PointLightMat::setGBuffer(const SPtr<RenderTargets>& gbuffer)
+	{
+		mGBufferA.set(gbuffer->getTextureA());
+		mGBufferB.set(gbuffer->getTextureB());
+		mGBufferDepth.set(gbuffer->getTextureDepth());
 	}
 
 	void PointLightMat::setParameters(const LightCore* light)

+ 14 - 7
RenderBeast/Source/BsRenderBeast.cpp

@@ -551,6 +551,8 @@ namespace BansheeEngine
 
 				gRendererUtility().draw(iter->renderElem->mesh, iter->renderElem->subMesh);
 			}
+
+			camData.gbuffer->unbind();
 		}
 		else
 			camData.gbuffer = nullptr;
@@ -558,7 +560,7 @@ namespace BansheeEngine
 		// Prepare final render target
 		SPtr<RenderTargetCore> target = rtData.target;
 
-		// If first camera in render target, prepare the RT
+		// If first camera in render target, prepare the render target
 		if (camIdx == 0)
 		{
 			RenderAPICore::instance().setRenderTarget(target);
@@ -594,10 +596,13 @@ namespace BansheeEngine
 		// Render lights and resolve gbuffer if there is one
 		if (hasGBuffer)
 		{
+			// TODO - Need to handle a case when GBuffer has MSAA but scene target has not
+
 			SPtr<MaterialCore> dirMaterial = mDirLightMat->getMaterial();
 			SPtr<PassCore> dirPass = dirMaterial->getPass(0);
 
 			setPass(dirPass);
+			mDirLightMat->setGBuffer(camData.gbuffer);
 
 			for (auto& light : mDirectionalLights)
 			{
@@ -605,11 +610,15 @@ namespace BansheeEngine
 					continue;
 
 				mDirLightMat->setParameters(light.internal);
-
-				SPtr<MeshCore> mesh = nullptr; // TODO - Get full screen quad
-				gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
+				gRendererUtility().drawScreenQuad(*viewport);
 			}
 
+			SPtr<MaterialCore> pointMaterial = mPointLightMat->getMaterial();
+			SPtr<PassCore> pointPass = pointMaterial->getPass(0);
+
+			setPass(pointPass);
+			mPointLightMat->setGBuffer(camData.gbuffer);
+
 			// TODO - Cull lights based on visibility, right now I just iterate over all of them. 
 			for (auto& light : mPointLights)
 			{
@@ -622,9 +631,7 @@ namespace BansheeEngine
 				gRendererUtility().draw(mesh, mesh->getProperties().getSubMesh(0));
 			}
 
-			// TODO - Resolve to render target (Later: Manual resolve during deferred light pass?)
-			
-			camData.gbuffer->unbind();
+			// TODO - Resolve to render target if it was MSAA (Later: Manual resolve during deferred light pass?)
 		}
 
 		// Render transparent objects (TODO - No lighting yet)

+ 15 - 0
RenderBeast/Source/BsRenderTargets.cpp

@@ -75,4 +75,19 @@ namespace BansheeEngine
 		texPool.release(mNormalRT);
 		texPool.release(mDepthRT);
 	}
+
+	SPtr<TextureCore> RenderTargets::getTextureA() const
+	{
+		return mDiffuseRT->texture;
+	}
+
+	SPtr<TextureCore> RenderTargets::getTextureB() const
+	{
+		return mNormalRT->texture;
+	}
+
+	SPtr<TextureCore> RenderTargets::getTextureDepth() const
+	{
+		return mDepthRT->texture;
+	}
 }