Sfoglia il codice sorgente

Camera transform changes no longer cause renderer to completely rebuild relevant camera's resources
- This was causing issue with post-processing as it requires certain resources to persist

BearishSun 9 anni fa
parent
commit
1b1b5f4af5

+ 1 - 0
Documentation/Manuals/Native/renderer.md

@@ -87,6 +87,7 @@ The @ref BansheeEngine::Renderer "Renderer" interface requires you to implement
  - @ref BansheeEngine::CoreRenderer::getName "Renderer::getName" - Returns a unique name of the renderer. This can be used by shader techniques to identify which renderer is active and when they should run, as described in the [material](@ref materials) manual.
  - @ref BansheeEngine::CoreRenderer::renderAll "Renderer::renderAll" - This is a method called from the simulation thread that executes the rendering. It is called once per frame. In this method you should queue your actual rendering method for execution on the core thread.
  - @ref BansheeEngine::CoreRenderer::notifyCameraAdded "Renderer::notifyCameraAdded" - Called on the core thread whenever a new @ref BansheeEngine::Camera "Camera" is created (i.e. when a @ref BansheeEngine::CCamera "CCamera" component is added to the scene). Also called when camera's properties change (camera is removed, then re-added).
+ - @ref BansheeEngine::CoreRenderer::notifyCameraUpdated "Renderer::notifyCameraUpdated" - Called on the core thread whenever a @ref BansheeEngine::Camera "Camera's" position or rotation changes.
  - @ref BansheeEngine::CoreRenderer::notifyCameraRemoved "Renderer::notifyCameraRemoved" - Called on the core thread whenever a @ref BansheeEngine::Camera "Camera" is destroyed. Also called when camera's properties change (camera is removed, then re-added).
  - @ref BansheeEngine::Renderer::notifyRenderableAdded "Renderer::notifyRenderableAdded" - Called on the core thread whenever a new @ref BansheeEngine::Renderable "Renderable" is created (e.g. when a @ref BansheeEngine::CRenderable "CRenderable" component is added to the scene).
  - @ref BansheeEngine::Renderer::notifyRenderableUpdated "Renderer::notifyRenderableUpdated" - Called whenever @ref BansheeEngine::Renderable "Renderable" properties change, e.g. when a scene object a renderable is attached to moves.

+ 7 - 0
Source/BansheeCore/Include/BsCoreRenderer.h

@@ -74,6 +74,13 @@ namespace BansheeEngine
 		 */
 		virtual void notifyCameraAdded(const CameraCore* camera) { }
 
+		/**
+		 * Called whenever a camera's position or rotation is updated.
+		 *
+		 * @note	Core thread.
+		 */
+		virtual void notifyCameraUpdated(const CameraCore* camera, const Vector3& position, const Quaternion& rotation) { }
+
 		/**
 		 * Called whenever a camera is destroyed.
 		 *

+ 9 - 2
Source/BansheeEngine/Include/BsCamera.h

@@ -20,6 +20,13 @@ namespace BansheeEngine
 	 *  @{
 	 */
 
+	/**	Signals which portion of a Camera is dirty. */
+	enum class CameraDirtyFlag
+	{
+		Transform = 0x01,
+		Everything = 0x02
+	};
+
 	/**	Projection type to use by the camera. */
     enum ProjectionType
     {
@@ -420,7 +427,7 @@ namespace BansheeEngine
 		 * Marks the simulation thread object as dirty and notifies the system its data should be synced with its core 
 		 * thread counterpart. 
 		 */
-		virtual void _markCoreDirty() { }
+		virtual void _markCoreDirty(CameraDirtyFlag flag = CameraDirtyFlag::Everything) { }
 
     protected:
 		UINT64 mLayers; /**< Bitfield that can be used for filtering what objects the camera sees. */
@@ -541,7 +548,7 @@ namespace BansheeEngine
 		SPtr<CoreObjectCore> createCore() const override;
 
 		/** @copydoc CameraBase::_markCoreDirty */
-		void _markCoreDirty() override;
+		void _markCoreDirty(CameraDirtyFlag flag = CameraDirtyFlag::Everything) override;
 
 		/** @copydoc CoreObject::syncToCore */
 		CoreSyncData syncToCore(FrameAlloc* allocator) override;

+ 69 - 47
Source/BansheeEngine/Source/BsCamera.cpp

@@ -507,7 +507,7 @@ namespace BansheeEngine
 		mPosition = position;
 
 		mRecalcView = true;
-		_markCoreDirty();
+		_markCoreDirty(CameraDirtyFlag::Transform);
 	}
 
 	void CameraBase::setRotation(const Quaternion& rotation)
@@ -515,7 +515,7 @@ namespace BansheeEngine
 		mRotation = rotation;
 
 		mRecalcView = true;
-		_markCoreDirty();
+		_markCoreDirty(CameraDirtyFlag::Transform);
 	}
 
 	void CameraBase::invalidateFrustum() const
@@ -707,32 +707,42 @@ namespace BansheeEngine
 
 	void CameraCore::syncToCore(const CoreSyncData& data)
 	{
-		RendererManager::instance().getActive()->notifyCameraRemoved(this);
-
 		char* dataPtr = (char*)data.getBuffer();
 
-		dataPtr = rttiReadElem(mLayers, dataPtr);
+		CameraDirtyFlag dirtyFlag;
+		dataPtr = rttiReadElem(dirtyFlag, dataPtr);
 		dataPtr = rttiReadElem(mPosition, dataPtr);
 		dataPtr = rttiReadElem(mRotation, dataPtr);
-		dataPtr = rttiReadElem(mProjType, dataPtr);
-		dataPtr = rttiReadElem(mHorzFOV, dataPtr);
-		dataPtr = rttiReadElem(mFarDist, dataPtr);
-		dataPtr = rttiReadElem(mNearDist, dataPtr);
-		dataPtr = rttiReadElem(mAspect, dataPtr);
-		dataPtr = rttiReadElem(mOrthoHeight, dataPtr);
-		dataPtr = rttiReadElem(mPriority, dataPtr);
-		dataPtr = rttiReadElem(mCustomViewMatrix, dataPtr);
-		dataPtr = rttiReadElem(mCustomProjMatrix, dataPtr);
-		dataPtr = rttiReadElem(mFrustumExtentsManuallySet, dataPtr);
-		dataPtr = rttiReadElem(mCameraFlags, dataPtr);
-		dataPtr = rttiReadElem(mIsActive, dataPtr);
 
 		mRecalcFrustum = true;
 		mRecalcFrustumPlanes = true;
 		mRecalcView = true;
 
-		if(mIsActive)
-			RendererManager::instance().getActive()->notifyCameraAdded(this);
+		if (dirtyFlag == CameraDirtyFlag::Transform)
+		{
+			RendererManager::instance().getActive()->notifyCameraUpdated(this, mPosition, mRotation);
+		}
+		else 
+		{
+			dataPtr = rttiReadElem(mLayers, dataPtr);
+			dataPtr = rttiReadElem(mProjType, dataPtr);
+			dataPtr = rttiReadElem(mHorzFOV, dataPtr);
+			dataPtr = rttiReadElem(mFarDist, dataPtr);
+			dataPtr = rttiReadElem(mNearDist, dataPtr);
+			dataPtr = rttiReadElem(mAspect, dataPtr);
+			dataPtr = rttiReadElem(mOrthoHeight, dataPtr);
+			dataPtr = rttiReadElem(mPriority, dataPtr);
+			dataPtr = rttiReadElem(mCustomViewMatrix, dataPtr);
+			dataPtr = rttiReadElem(mCustomProjMatrix, dataPtr);
+			dataPtr = rttiReadElem(mFrustumExtentsManuallySet, dataPtr);
+			dataPtr = rttiReadElem(mCameraFlags, dataPtr);
+			dataPtr = rttiReadElem(mIsActive, dataPtr);
+
+			RendererManager::instance().getActive()->notifyCameraRemoved(this);
+
+			if (mIsActive)
+				RendererManager::instance().getActive()->notifyCameraAdded(this);
+		}
 	}
 
 	Camera::Camera(SPtr<RenderTarget> target, float left, float top, float width, float height)
@@ -784,41 +794,53 @@ namespace BansheeEngine
 
 	CoreSyncData Camera::syncToCore(FrameAlloc* allocator)
 	{
+		UINT32 dirtyFlag = getCoreDirtyFlags();
+
 		UINT32 size = 0;
-		size += rttiGetElemSize(mLayers);
+		size += rttiGetElemSize(dirtyFlag);
 		size += rttiGetElemSize(mPosition);
 		size += rttiGetElemSize(mRotation);
-		size += rttiGetElemSize(mProjType);
-		size += rttiGetElemSize(mHorzFOV);
-		size += rttiGetElemSize(mFarDist);
-		size += rttiGetElemSize(mNearDist);
-		size += rttiGetElemSize(mAspect);
-		size += rttiGetElemSize(mOrthoHeight);
-		size += rttiGetElemSize(mPriority);
-		size += rttiGetElemSize(mCustomViewMatrix);
-		size += rttiGetElemSize(mCustomProjMatrix);
-		size += rttiGetElemSize(mFrustumExtentsManuallySet);
-		size += rttiGetElemSize(mCameraFlags);
-		size += rttiGetElemSize(mIsActive);
+
+		if (dirtyFlag != (UINT32)CameraDirtyFlag::Transform)
+		{
+			size += rttiGetElemSize(mLayers);
+			size += rttiGetElemSize(mProjType);
+			size += rttiGetElemSize(mHorzFOV);
+			size += rttiGetElemSize(mFarDist);
+			size += rttiGetElemSize(mNearDist);
+			size += rttiGetElemSize(mAspect);
+			size += rttiGetElemSize(mOrthoHeight);
+			size += rttiGetElemSize(mPriority);
+			size += rttiGetElemSize(mCustomViewMatrix);
+			size += rttiGetElemSize(mCustomProjMatrix);
+			size += rttiGetElemSize(mFrustumExtentsManuallySet);
+			size += rttiGetElemSize(mCameraFlags);
+			size += rttiGetElemSize(mIsActive);
+		}
 
 		UINT8* buffer = allocator->alloc(size);
 
 		char* dataPtr = (char*)buffer;
-		dataPtr = rttiWriteElem(mLayers, dataPtr);
+		dataPtr = rttiWriteElem(dirtyFlag, dataPtr);
 		dataPtr = rttiWriteElem(mPosition, dataPtr);
 		dataPtr = rttiWriteElem(mRotation, dataPtr);
-		dataPtr = rttiWriteElem(mProjType, dataPtr);
-		dataPtr = rttiWriteElem(mHorzFOV, dataPtr);
-		dataPtr = rttiWriteElem(mFarDist, dataPtr);
-		dataPtr = rttiWriteElem(mNearDist, dataPtr);
-		dataPtr = rttiWriteElem(mAspect, dataPtr);
-		dataPtr = rttiWriteElem(mOrthoHeight, dataPtr);
-		dataPtr = rttiWriteElem(mPriority, dataPtr);
-		dataPtr = rttiWriteElem(mCustomViewMatrix, dataPtr);
-		dataPtr = rttiWriteElem(mCustomProjMatrix, dataPtr);
-		dataPtr = rttiWriteElem(mFrustumExtentsManuallySet, dataPtr);
-		dataPtr = rttiWriteElem(mCameraFlags, dataPtr);
-		dataPtr = rttiWriteElem(mIsActive, dataPtr);
+
+		if (dirtyFlag != (UINT32)CameraDirtyFlag::Transform)
+		{
+			dataPtr = rttiWriteElem(mLayers, dataPtr);
+			dataPtr = rttiWriteElem(mProjType, dataPtr);
+			dataPtr = rttiWriteElem(mHorzFOV, dataPtr);
+			dataPtr = rttiWriteElem(mFarDist, dataPtr);
+			dataPtr = rttiWriteElem(mNearDist, dataPtr);
+			dataPtr = rttiWriteElem(mAspect, dataPtr);
+			dataPtr = rttiWriteElem(mOrthoHeight, dataPtr);
+			dataPtr = rttiWriteElem(mPriority, dataPtr);
+			dataPtr = rttiWriteElem(mCustomViewMatrix, dataPtr);
+			dataPtr = rttiWriteElem(mCustomProjMatrix, dataPtr);
+			dataPtr = rttiWriteElem(mFrustumExtentsManuallySet, dataPtr);
+			dataPtr = rttiWriteElem(mCameraFlags, dataPtr);
+			dataPtr = rttiWriteElem(mIsActive, dataPtr);
+		}
 
 		return CoreSyncData(buffer, size);
 	}
@@ -828,9 +850,9 @@ namespace BansheeEngine
 		dependencies.push_back(mViewport.get());
 	}
 
-	void Camera::_markCoreDirty()
+	void Camera::_markCoreDirty(CameraDirtyFlag flag)
 	{
-		markCoreDirty();
+		markCoreDirty((UINT32)flag);
 	}
 
 	RTTITypeBase* Camera::getRTTIStatic()

+ 11 - 8
Source/RenderBeast/Include/BsRenderBeast.h

@@ -132,28 +132,31 @@ namespace BansheeEngine
 		virtual void destroy() override;
 
 	private:
-		/** @copydoc Renderer::_notifyCameraAdded */
+		/** @copydoc Renderer::notifyCameraAdded */
 		void notifyCameraAdded(const CameraCore* camera) override;
 
-		/** @copydocRenderer::_notifyCameraRemoved */
+		/** @copydoc Renderer::notifyCameraUpdated */
+		void notifyCameraUpdated(const CameraCore* camera, const Vector3& position, const Quaternion& rotation) override;
+
+		/** @copydocRenderer::notifyCameraRemoved */
 		void notifyCameraRemoved(const CameraCore* camera) override;
 
-		/** @copydoc Renderer::_notifyLightAdded */
+		/** @copydoc Renderer::notifyLightAdded */
 		void notifyLightAdded(LightCore* light) override;
 
-		/** @copydoc Renderer::_notifyLightUpdated */
+		/** @copydoc Renderer::notifyLightUpdated */
 		void notifyLightUpdated(LightCore* light) override;
 
-		/** @copydoc Renderer::_notifyLightRemoved */
+		/** @copydoc Renderer::notifyLightRemoved */
 		void notifyLightRemoved(LightCore* light) override;
 
-		/** @copydoc Renderer::_notifyRenderableAdded */
+		/** @copydoc Renderer::notifyRenderableAdded */
 		void notifyRenderableAdded(RenderableCore* renderable) override;
 
-		/** @copydoc Renderer::_notifyRenderableUpdated */
+		/** @copydoc Renderer::notifyRenderableUpdated */
 		void notifyRenderableUpdated(RenderableCore* renderable) override;
 
-		/** @copydoc Renderer::_notifyRenderableRemoved */
+		/** @copydoc Renderer::notifyRenderableRemoved */
 		void notifyRenderableRemoved(RenderableCore* renderable) override;
 
 		/**

+ 1 - 1
Source/RenderBeast/Source/BsPostProcessing.cpp

@@ -10,7 +10,7 @@ namespace BansheeEngine
 {
 	PostProcessSettings::PostProcessSettings()
 		: histogramLog2Min(-8.0f), histogramLog2Max(4.0f), histogramPctLow(0.8f), histogramPctHigh(0.985f)
-		, minEyeAdaptation(0.03f), maxEyeAdaptation(2.0f), exposureScale(0.0f), eyeAdaptationSpeedUp(3.0f)
+		, minEyeAdaptation(0.5f), maxEyeAdaptation(2.0f), exposureScale(0.0f), eyeAdaptationSpeedUp(3.0f)
 		, eyeAdaptationSpeedDown(3.0f)
 	{ }
 

+ 5 - 0
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -372,6 +372,11 @@ namespace BansheeEngine
 		}
 	}
 
+	void RenderBeast::notifyCameraUpdated(const CameraCore* camera, const Vector3& position, const Quaternion& rotation)
+	{
+		/* Do nothing, we poll position/rotation every frame anyway. */
+	}
+
 	void RenderBeast::notifyCameraRemoved(const CameraCore* camera)
 	{
 		mCameraData.erase(camera);