Panagiotis Christopoulos Charitos 13 rokov pred
rodič
commit
d63cccf7f1
3 zmenil súbory, kde vykonal 126 pridanie a 28 odobranie
  1. 7 7
      include/anki/renderer/Is.h
  2. 7 4
      shaders/Pack.glsl
  3. 112 17
      src/renderer/Is.cpp

+ 7 - 7
include/anki/renderer/Is.h

@@ -17,9 +17,9 @@ namespace anki {
 
 class PointLight;
 class SpotLight;
-struct ShaderPointLight;
-struct ShaderSpotLight;
-struct ShaderTile;
+struct ShaderPointLights;
+struct ShaderSpotLights;
+struct ShaderTiles;
 
 /// Illumination stage
 class Is: private RenderingPass
@@ -133,18 +133,18 @@ public: // XXX
 		const Mat4& viewMatrix);
 	Bool cullLight(const SpotLight& light, const Tile& tile);
 
-	void writeLightUbo(ShaderPointLight* shaderLights, U32 maxShaderLights,
+	void writeLightUbo(ShaderPointLights& shaderLights, U32 maxShaderLights,
 		PointLight** visibleLights, U32 visibleLightsCount, U start, U end);
-	void writeLightUbo(ShaderSpotLight* shaderLights, U32 maxShaderLights,
+	void writeLightUbo(ShaderSpotLights& shaderLights, U32 maxShaderLights,
 		SpotLight** visibleLights, U32 visibleLightsCount, U start, U end);
 
 	template<typename TLight>
 	void writeTilesUbo(TLight** visibleLights, U32 visibleLightsCount,
-		ShaderTile* shaderTiles, U32 maxLightsPerTile,
+		ShaderTiles& shaderTiles, U32 maxLightsPerTile,
 		U32 start, U32 end);
 
 	void pointLightsPass();
-	void spotLightsPass();
+	void spotLightsPass(Bool shadow);
 };
 
 } // end namespace anki

+ 7 - 4
shaders/Pack.glsl

@@ -22,6 +22,8 @@ vec3 unpackNormal(in vec2 enc)
 #define MAX_SPECULARITY 128.0
 
 /// Pack specular stuff
+/// @param c The specular component. c.x is the color in grayscale and c.y the 
+///          specularity
 float packSpecular(in vec2 c)
 {
 	return round(c[0] * 15.0) * 16.0 / 255.0 
@@ -31,11 +33,12 @@ float packSpecular(in vec2 c)
 /// Unpack specular
 vec2 unpackSpecular(in float f)
 {
-	float r = floor(f * 255.0 / 16.0);
+	float r = floor(f * (255.0 / 16.0));
 
 	return vec2(
 		r / 15.0,
-		f * 255.0 * MAX_SPECULARITY / 15.0 - r * 16.0 * MAX_SPECULARITY / 15.0);
+		f * (255.0 * MAX_SPECULARITY / 15.0) 
+		- r * (16.0 * MAX_SPECULARITY / 15.0));
 }
 
 /// Pack a vec4 to float
@@ -43,8 +46,8 @@ vec2 unpackSpecular(in float f)
 float pack4x8ToFloat(in vec4 v)
 {
 	const vec4 unshift = vec4(
-		1.0 / (256.0f * 256.0 * 256.0), 
-		1.0f / (256.0 * 256.0), 
+		1.0 / (256.0 * 256.0 * 256.0), 
+		1.0 / (256.0 * 256.0), 
 		1.0 / 256.0, 1.0);
 	return dot(v, unshift);
 }

+ 112 - 17
src/renderer/Is.cpp

@@ -48,7 +48,6 @@ struct ShaderTile
 
 struct ShaderTiles
 {
-	//Array<Array<ShaderTile, Is::TILES_X_COUNT>, Is::TILES_Y_COUNT> tiles;
 	Array<ShaderTile, Is::TILES_X_COUNT * Is::TILES_Y_COUNT> tiles;
 };
 
@@ -61,10 +60,12 @@ struct ShaderCommonUniforms
 
 //==============================================================================
 
+// Threading jobs
+
 /// Job to update point lights
 struct WritePointLightsUbo: ThreadJob
 {
-	ShaderPointLight* shaderLights; ///< Mapped UBO
+	ShaderPointLights* shaderLights; ///< Mapped UBO
 	U32 maxShaderLights;
 	PointLight** visibleLights;
 	U32 visibleLightsCount;
@@ -74,7 +75,7 @@ struct WritePointLightsUbo: ThreadJob
 	{
 		U64 start, end;
 		choseStartEnd(threadId, threadsCount, visibleLightsCount, start, end);
-		is->writeLightUbo(shaderLights, maxShaderLights, visibleLights, 
+		is->writeLightUbo(*shaderLights, maxShaderLights, visibleLights, 
 			visibleLightsCount, start, end);
 	}
 };
@@ -82,7 +83,7 @@ struct WritePointLightsUbo: ThreadJob
 /// Job to update spot lights
 struct WriteSpotLightsUbo: ThreadJob
 {
-	ShaderSpotLight* shaderLights; ///< Mapped UBO
+	ShaderSpotLights* shaderLights; ///< Mapped UBO
 	U32 maxShaderLights;
 	SpotLight** visibleLights;
 	U32 visibleLightsCount;
@@ -92,7 +93,7 @@ struct WriteSpotLightsUbo: ThreadJob
 	{
 		U64 start, end;
 		choseStartEnd(threadId, threadsCount, visibleLightsCount, start, end);
-		is->writeLightUbo(shaderLights, maxShaderLights, visibleLights, 
+		is->writeLightUbo(*shaderLights, maxShaderLights, visibleLights, 
 			visibleLightsCount, start, end);
 	}
 };
@@ -103,7 +104,7 @@ struct WriteTilesUboJob: ThreadJob
 {
 	TLight** visibleLights;
 	U32 visibleLightsCount;
-	ShaderTile* shaderTiles;
+	ShaderTiles* shaderTiles;
 	U32 maxLightsPerTile;
 	Is* is;
 
@@ -114,7 +115,7 @@ struct WriteTilesUboJob: ThreadJob
 			Is::TILES_X_COUNT * Is::TILES_Y_COUNT, start, end);
 
 		is->writeTilesUbo(visibleLights, visibleLightsCount,
-			shaderTiles, maxLightsPerTile, start, end);
+			*shaderTiles, maxLightsPerTile, start, end);
 	}
 };
 
@@ -403,7 +404,7 @@ void Is::updateTiles()
 }
 
 //==============================================================================
-void Is::writeLightUbo(ShaderPointLight* shaderLights, U32 maxShaderLights,
+void Is::writeLightUbo(ShaderPointLights& shaderLights, U32 maxShaderLights,
 	PointLight** visibleLights, U32 visibleLightsCount, U start, U end)
 {
 	const Camera& cam = r->getScene().getActiveCamera();
@@ -411,7 +412,7 @@ void Is::writeLightUbo(ShaderPointLight* shaderLights, U32 maxShaderLights,
 	for(U64 i = start; i < end; i++)
 	{
 		ANKI_ASSERT(i < maxShaderLights);
-		ShaderPointLight& pl = shaderLights[i];
+		ShaderPointLight& pl = shaderLights.lights[i];
 		const PointLight& light = *visibleLights[i];
 
 		Vec3 pos = light.getWorldTransform().getOrigin().getTransformed(
@@ -424,7 +425,7 @@ void Is::writeLightUbo(ShaderPointLight* shaderLights, U32 maxShaderLights,
 }
 
 //==============================================================================
-void Is::writeLightUbo(ShaderSpotLight* shaderLights, U32 maxShaderLights,
+void Is::writeLightUbo(ShaderSpotLight& shaderLights, U32 maxShaderLights,
 	SpotLight** visibleLights, U32 visibleLightsCount, U start, U end)
 {
 	const Camera& cam = r->getScene().getActiveCamera();
@@ -432,7 +433,7 @@ void Is::writeLightUbo(ShaderSpotLight* shaderLights, U32 maxShaderLights,
 	for(U64 i = start; i < end; i++)
 	{
 		ANKI_ASSERT(i < maxShaderLights);
-		ShaderSpotLight& slight = shaderLights[i];
+		ShaderSpotLight& slight = shaderLights.lights[i];
 		const SpotLight& light = *visibleLights[i];
 
 		Vec3 pos = light.getWorldTransform().getOrigin().getTransformed(
@@ -453,7 +454,7 @@ void Is::writeLightUbo(ShaderSpotLight* shaderLights, U32 maxShaderLights,
 //==============================================================================
 template<typename TLight>
 void Is::writeTilesUbo(TLight** visibleLights, U32 visibleLightsCount,
-	ShaderTile* shaderTiles, U32 maxLightsPerTile,
+	ShaderTiles& shaderTiles, U32 maxLightsPerTile,
 	U32 start, U32 end)
 {
 	Tile* tiles_ = &tiles[0][0];
@@ -485,10 +486,10 @@ void Is::writeTilesUbo(TLight** visibleLights, U32 visibleLightsCount,
 			ANKI_LOGW("Too many lights per tile: " << lightsInTileCount);
 		}
 #endif
-		shaderTiles[i].lightsCount = lightsInTileCount;
+		shaderTiless.tiles[i].lightsCount = lightsInTileCount;
 
 		memcpy(
-			&(shaderTiles[i].lightIndices[0]),
+			&(shaderTiles.tiles[i].lightIndices[0]),
 			&lightIndices[0],
 			sizeof(U32) * lightsInTileCount);
 	}
@@ -528,7 +529,7 @@ void Is::pointLightsPass()
 	}
 
 	// Map
-	ShaderPointLight* lightsMappedBuff = (ShaderPointLight*)lightsUbo.map(
+	ShaderPointLights* lightsMappedBuff = (ShaderPointLights*)lightsUbo.map(
 		0, 
 		sizeof(ShaderPointLight) * visibleLightsCount,
 		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
@@ -553,7 +554,7 @@ void Is::pointLightsPass()
 	// Update the tiles
 	//
 
-	ShaderTile* stiles = (ShaderTile*)tilesUbo.map(
+	ShaderTiles* stiles = (ShaderTiles*)tilesUbo.map(
 		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
 
 	WriteTilesUboJob<PointLight> tjobs[ThreadPool::MAX_THREADS];
@@ -587,9 +588,99 @@ void Is::pointLightsPass()
 }
 
 //==============================================================================
-void Is::spotLightsPass()
+void Is::spotLightsPass(Bool shadow)
 {
+	Camera& cam = r->getScene().getActiveCamera();
+	VisibilityInfo& vi = cam.getFrustumable()->getVisibilityInfo();
+
+	Array<SpotLight*, MAX_LIGHTS> visibleLights;
+	U visibleLightsCount = 0;
+
+	ThreadPool& threadPool = ThreadPoolSingleton::get();
+
+	// Quickly get the point lights
+	for(auto it = vi.getLightsBegin(); it != vi.getLightsEnd(); ++it)
+	{
+		Light* light = (*it);
+		if(light->getLightType() == Light::LT_SPOT)
+		{
+			SpotLight* slight = static_cast<SpotLight*>(light);
+
+			if(shadow && slight->getShadowEnabled())
+			{
+				// Use % to avoid overflows
+				visibleLights[visibleLightsCount % MAX_LIGHTS] = slight;
+				++visibleLightsCount;
+			}
+		}
+	}
+
+	if(visibleLightsCount > MAX_LIGHTS)
+	{
+		throw ANKI_EXCEPTION("Too many visible lights");
+	}
+
+	//
+	// Write the lightsUbo
+	//
+
+	ShaderSpotLights* lightsMappedBuff = (ShaderSpotLights*)lightsUbo.map(
+		0, 
+		sizeof(ShaderSpotLight) * visibleLightsCount,
+		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+
+	WriteSpotLightsUbo jobs[ThreadPool::MAX_THREADS];
+	for(U i = 0; i < threadPool.getThreadsCount(); i++)
+	{
+		jobs[i].shaderLights = lightsMappedBuff;
+		jobs[i].maxShaderLights = MAX_LIGHTS;
+		jobs[i].visibleLights = &visibleLights[0];
+		jobs[i].visibleLightsCount = visibleLightsCount;
+		jobs[i].is = this;
+
+		threadPool.assignNewJob(i, &jobs[i]);
+	}
+
+	// Done
+	threadPool.waitForAllJobsToFinish();
+	lightsUbo.unmap();
+
+	//
+	// Update the tiles
+	//
+
+	ShaderTiles* stiles = (ShaderTiles*)tilesUbo.map(
+		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+
+	WriteTilesUboJob<SpotLight> tjobs[ThreadPool::MAX_THREADS];
+	for(U i = 0; i < threadPool.getThreadsCount(); i++)
+	{
+		tjobs[i].visibleLights = &visibleLights[0];
+		tjobs[i].visibleLightsCount = visibleLightsCount;
+		tjobs[i].shaderTiles = stiles;
+		tjobs[i].maxLightsPerTile = MAX_LIGHTS_PER_TILE;
+		tjobs[i].is = this;
+
+		threadPool.assignNewJob(i, &tjobs[i]);
+	}
+
+	threadPool.waitForAllJobsToFinish();
+	tilesUbo.unmap();
+	
+	//
+	// Setup shader and draw
+	//
 	
+	// shader prog
+	const ShaderProgram& shader = *lightSProgs[
+		(shadow) ? LST_SPOT_SHADOW : LST_SPOT];
+	shader.bind();
+
+	shader.findUniformVariable("msFai0").set(r->getMs().getFai0());
+	shader.findUniformVariable("msDepthFai").set(
+		r->getMs().getDepthFai());
+
+	r->drawQuadInstanced(TILES_Y_COUNT * TILES_X_COUNT);
 }
 
 //==============================================================================
@@ -629,6 +720,10 @@ void Is::run()
 	GlStateSingleton::get().setViewport(0, 0, r->getWidth(), r->getHeight());
 
 	pointLightsPass();
+
+	GlStateSingleton::get().enable(GL_BLEND);
+	glBlendFunc(GL_ONE, GL_ONE);
+	spotLightsPass(false);
 }
 
 } // end namespace anki