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

Use a dummy directional light when no other light is in the scene

BearishSun 10 лет назад
Родитель
Сommit
7df87c236f
3 измененных файлов с 18 добавлено и 12 удалено
  1. 2 1
      RenderBeast/Include/BsRenderBeast.h
  2. 16 2
      RenderBeast/Source/BsRenderBeast.cpp
  3. 0 9
      TODOExperimentation.txt

+ 2 - 1
RenderBeast/Include/BsRenderBeast.h

@@ -228,7 +228,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Creates data used by the renderer on the core thread.
 		 */
-		void initializeCore();
+		void initializeCore(const SPtr<LightCore>& dummyLight);
 
 		/**
 		 * @brief	Destroys data used by the renderer on the core thread.
@@ -293,6 +293,7 @@ namespace BansheeEngine
 		Vector<LightData> mDirectionalLights; // Core thread
 		Vector<LightData> mPointLights; // Core thread
 		Vector<Sphere> mLightWorldBounds; // Core thread
+		SPtr<LightCore> mDummyDirLight; // Core thread
 
 		SPtr<RenderBeastOptions> mCoreOptions; // Core thread
 

+ 16 - 2
RenderBeast/Source/BsRenderBeast.cpp

@@ -56,7 +56,9 @@ namespace BansheeEngine
 	{
 		CoreRenderer::initialize();
 
-		CoreThread::instance().queueCommand(std::bind(&RenderBeast::initializeCore, this));
+		SPtr<Light> dummyDirLight = Light::create(LightType::Directional);
+
+		CoreThread::instance().queueCommand(std::bind(&RenderBeast::initializeCore, this, dummyDirLight->getCore()));
 	}
 
 	void RenderBeast::destroy()
@@ -67,7 +69,7 @@ namespace BansheeEngine
 		gCoreAccessor().submitToCoreThread(true);
 	}
 
-	void RenderBeast::initializeCore()
+	void RenderBeast::initializeCore(const SPtr<LightCore>& dummyLight)
 	{
 		RendererUtility::startUp();
 
@@ -78,6 +80,8 @@ namespace BansheeEngine
 		mPointLightMat = bs_new<PointLightMat>();
 		mDirLightMat = bs_new<DirectionalLightMat>();
 
+		mDummyDirLight = dummyLight;
+
 		RenderTexturePool::startUp();
 	}
 
@@ -89,6 +93,7 @@ namespace BansheeEngine
 		mRenderTargets.clear();
 		mCameraData.clear();
 		mRenderables.clear();
+		mDummyDirLight = nullptr;
 
 		RenderTexturePool::shutDown();
 
@@ -259,6 +264,9 @@ namespace BansheeEngine
 	{
 		if (light->getType() == LightType::Directional)
 		{
+			if (mDummyDirLight != nullptr && mDummyDirLight.get() != light)
+				mDummyDirLight->setIsActive(false);
+
 			UINT32 lightId = (UINT32)mDirectionalLights.size();
 
 			light->setRendererId(lightId);
@@ -326,6 +334,10 @@ namespace BansheeEngine
 			mPointLights.erase(mPointLights.end() - 1);
 			mLightWorldBounds.erase(mLightWorldBounds.end() - 1);
 		}
+
+		UINT32 numDirLights = (UINT32)mDirectionalLights.size();
+		if (numDirLights == 0 && mDummyDirLight != nullptr) // Enable dummy light because otherwise nothing will get rendered in unlit areas
+			mDummyDirLight->setIsActive(true);
 	}
 
 	void RenderBeast::_notifyCameraAdded(const CameraCore* camera)
@@ -585,6 +597,8 @@ namespace BansheeEngine
 		{
 			// TODO - Need to handle a case when GBuffer has MSAA but scene target has not
 
+			UINT32 numLights = (UINT32)(mDirectionalLights.size() + mPointLights.size());
+
 			SPtr<MaterialCore> dirMaterial = mDirLightMat->getMaterial();
 			SPtr<PassCore> dirPass = dirMaterial->getPass(0);
 

+ 0 - 9
TODOExperimentation.txt

@@ -13,24 +13,15 @@ Assign ViewOrigin, PreViewTranslation, TransViewProj
  - Perhaps do all these modifcations outside of shader (i.e. have the world matrix be pre-transformed)
  - Do this after I have basic rendering working, to avoid additional issues when I'm initially trying to get it to work
  
-Next week:
- - With no light in the scene nothing renders, but it should at least render everything with constant ambient (just for debug until I implement GI)
-  - Perhaps "inject" a dummy directional light when no other light is in the scene?
- - I have removed DefaultNoNormal shader as support deferred rendering with no normals complicates the pipeline too much. I should instead
-   ensure meshes always have dummy normal data. (Right now mesh with no normals/tangents keeps spamming DX11 warnings)
-   - Can I do this in the D3D11RenderAPI? If pieces are missing add new dummy vertex streams with 0 vertex stride and one element
-
 Later:
  - Lights already existing in scene on load don't seem to render (seems they get converted to point lights for some reason)
  - I changed how unsupported texture formats work, I should test if I didn't break OpenGL
-
  - When rendering lights right now I need to bind Gbuffer and light parameters to material, and then bind the material parameters to the pipeline
   - Either unify these two processes by finding a better way, or hide the binding in light material class
  - Too many depth buffers. Main render surface has one, game viewport has one and gbuffer has one
   - Disable main depth buffer by default, disable depth buffer in SceneWindow and GameWindow RT's
   - When rendering to scene target use the gbuffers depth buffer (what if their sizes don't match due to quantization?)
   - Although having an extra depth buffer won't be the worst thing as even at full HD it's only 8MB
-
  - Finish up DefferedPointLightPass by generating cone geometry in shader
  - Modify Light so it generated adequate number of vertices required for cone geometry, without actually creating the cone
  - Think about how to handle post-processing shaders (HDR tone mapping)