Bläddra i källkod

IS and fixing bug in ShaderProgramResource

Panagiotis Christopoulos Charitos 13 år sedan
förälder
incheckning
ca9b7513d3
5 ändrade filer med 185 tillägg och 203 borttagningar
  1. 17 11
      include/anki/renderer/Is.h
  2. 19 11
      shaders/IsLpGeneric.glsl
  3. 0 2
      shaders/IsMinMax.glsl
  4. 147 178
      src/renderer/Is.cpp
  5. 2 1
      src/resource/ShaderProgramResource.cpp

+ 17 - 11
include/anki/renderer/Is.h

@@ -26,8 +26,6 @@ class Is: private RenderingPass
 {
 	friend struct WritePointLightsUbo;
 	friend struct WriteSpotLightsUbo;
-
-	template<typename TLight>
 	friend struct WriteTilesUboJob;
 
 public:
@@ -38,7 +36,8 @@ public:
 
 	static const U MAX_LIGHTS_PER_TILE = 32;
 
-	static const U MAX_LIGHTS = 512;
+	static const U MAX_POINT_LIGHTS = 512;
+	static const U MAX_SPOT_LIGHTS = 8;
 
 	Is(Renderer* r);
 
@@ -60,7 +59,7 @@ public:
 	}
 	/// @}
 
-public: // XXX
+private:
 	enum LightSubType
 	{
 		LST_POINT,
@@ -79,6 +78,11 @@ public: // XXX
 		Array<Plane, 6> planes;
 	};
 
+	static const U COMMON_UNIFORMS_BLOCK_BINDING = 0;
+	static const U POINT_LIGHTS_BLOCK_BINDING = 1;
+	static const U SPOT_LIGHTS_BLOCK_BINDING = 2;
+	static const U TILES_BLOCK_BINDING = 3;
+
 	U32 planesUpdateTimestamp = Timestamp::getTimestamp();
 
 	/// @note The [0][0] is the bottom left tile
@@ -103,8 +107,9 @@ public: // XXX
 	/// Track the updates of commonUbo
 	U32 commonUboUpdateTimestamp = Timestamp::getTimestamp();
 
-	/// Contains info of all the lights
-	Ubo lightsUbo;
+	/// Contains info of for lights
+	Ubo pointLightsUbo;
+	Ubo spotLightsUbo;
 
 	/// Contains the indices of lights per tile
 	Ubo tilesUbo;
@@ -113,7 +118,7 @@ public: // XXX
 	ShaderProgramResourcePointer minMaxPassSprog;
 
 	/// Light shaders
-	Array<ShaderProgramResourcePointer, LST_COUNT> lightSProgs;
+	ShaderProgramResourcePointer lightPassProg;
 
 	Sm sm;
 
@@ -131,20 +136,21 @@ public: // XXX
 	/// See if the light is inside the tile
 	static Bool cullLight(const PointLight& light, const Tile& tile, 
 		const Mat4& viewMatrix);
-	Bool cullLight(const SpotLight& light, const Tile& tile);
+	static Bool cullLight(const SpotLight& light, const Tile& tile,
+		const Mat4& viewMatrix);
 
 	void writeLightUbo(ShaderPointLights& shaderLights, U32 maxShaderLights,
 		PointLight** visibleLights, U32 visibleLightsCount, U start, U end);
 	void writeLightUbo(ShaderSpotLights& shaderLights, U32 maxShaderLights,
 		SpotLight** visibleLights, U32 visibleLightsCount, U start, U end);
 
-	template<typename TLight>
-	void writeTilesUbo(TLight** visibleLights, U32 visibleLightsCount,
+	void writeTilesUbo(
+		PointLight* visiblePointLights[], U32 visiblePointLightsCount,
+		SpotLight* visibleSpotLights[], U32 visibleSpotLightsCount,
 		ShaderTiles& shaderTiles, U32 maxLightsPerTile,
 		U32 start, U32 end);
 
 	void pointLightsPass();
-	void spotLightsPass(Bool shadow);
 };
 
 } // end namespace anki

+ 19 - 11
shaders/IsLpGeneric.glsl

@@ -13,7 +13,11 @@
 
 #define DISCARD 0
 
-#if !MAX_LIGHTS_PER_TILE || !TILES_X_COUNT || !TILES_Y_COUNT || !TILES_COUNT
+#if !MAX_LIGHTS_PER_TILE || !TILES_X_COUNT || !TILES_Y_COUNT
+#	error "See file"
+#endif
+
+#if !MAX_POINT_LIGHTS || !MAX_SPOT_LIGHTS
 #	error "See file"
 #endif
 
@@ -46,14 +50,22 @@ struct Light
 	vec4 posAndRadius; ///< xyz: Light pos in eye space. w: The radius
 	vec4 diffuseColor;
 	vec4 specularColor;
-#if SPOT_LIGHT
+};
+
+struct SpotLight
+{
+	Light light;
 	mat4 texProjectionMat;
-#endif
 };
 
-layout(std140, row_major, binding = 1) uniform lightsBlock
+layout(std140, row_major, binding = 1) uniform pointLightsBlock
+{
+	Light plights[MAX_POINT_LIGHTS];
+};
+
+layout(std140, row_major, binding = 2) uniform spotLightsBlock
 {
-	Light lights[MAX_LIGHTS];
+	SpotLight slights[MAX_SPOT_LIGHTS];
 };
 
 struct Tile
@@ -62,7 +74,7 @@ struct Tile
 	uvec4 lightIndices[MAX_LIGHTS_PER_TILE / 4];
 };
 
-layout(std140, row_major, binding = 2) uniform tilesBlock
+layout(std140, row_major, binding = 3) uniform tilesBlock
 {
 	Tile tiles[TILES_X_COUNT * TILES_Y_COUNT];
 };
@@ -175,12 +187,8 @@ void main()
 	{
 		uint lightId = tiles[vInstanceId].lightIndices[i / 4][i % 4];
 
-#if 1
 		fColor += doPhong(fragPosVspace, normal, diffuseAndSpec.rgb, 
-			specularAll, lights[lightId]);
-#else
-		fColor += lights[lightId].diffuseColor.rgb;
-#endif
+			specularAll, plights[lightId]);
 	}
 
 #if 0

+ 0 - 2
shaders/IsMinMax.glsl

@@ -4,8 +4,6 @@
 
 #pragma anki start fragmentShader
 
-#pragma anki include "shaders/LinearDepth.glsl"
-
 #if !defined(TILES_X_COUNT) || !defined(TILES_Y_COUNT) || !defined(RENDERER_WIDTH) || !defined(RENDERER_HEIGHT)
 #	error "See file"
 #endif

+ 147 - 178
src/renderer/Is.cpp

@@ -30,18 +30,18 @@ struct ShaderSpotLight: ShaderLight
 
 struct ShaderPointLights
 {
-	ShaderPointLight lights[Is::MAX_LIGHTS];
+	ShaderPointLight lights[Is::MAX_POINT_LIGHTS];
 };
 
 struct ShaderSpotLights
 {
-	ShaderSpotLight lights[Is::MAX_LIGHTS];
+	ShaderSpotLight lights[Is::MAX_SPOT_LIGHTS];
 };
 
 struct ShaderTile
 {
-	U32 lightsCount;
-	U32 padding[3];
+	U32 lightsCount[2];
+	U32 padding[2];
 	// When change this change the writeTilesUbo as well
 	Array<U32, Is::MAX_LIGHTS_PER_TILE> lightIndices; 
 };
@@ -99,11 +99,12 @@ struct WriteSpotLightsUbo: ThreadJob
 };
 
 /// A job to write the tiles UBO
-template<typename TLight>
 struct WriteTilesUboJob: ThreadJob
 {
-	TLight** visibleLights;
-	U32 visibleLightsCount;
+	PointLight** visiblePointLights;
+	U32 visiblePointLightsCount;
+	SpotLight** visibleSpotLights;
+	U32 visibleSpotLightsCount;
 	ShaderTiles* shaderTiles;
 	U32 maxLightsPerTile;
 	Is* is;
@@ -114,7 +115,9 @@ struct WriteTilesUboJob: ThreadJob
 		choseStartEnd(threadId, threadsCount, 
 			Is::TILES_X_COUNT * Is::TILES_Y_COUNT, start, end);
 
-		is->writeTilesUbo(visibleLights, visibleLightsCount,
+		is->writeTilesUbo(
+			visiblePointLights, visiblePointLightsCount,
+			visibleSpotLights, visibleSpotLightsCount,
 			*shaderTiles, maxLightsPerTile, start, end);
 	}
 };
@@ -159,36 +162,16 @@ void Is::initInternal(const RendererInitializer& initializer)
 		"#define RENDERER_HEIGHT " + std::to_string(r->getHeight()) + "\n"
 		"#define MAX_LIGHTS_PER_TILE " + std::to_string(MAX_LIGHTS_PER_TILE)
 		+ "\n"
-		"#define TILES_COUNT " + std::to_string(TILES_X_COUNT * TILES_Y_COUNT)
-		+ "\n"
-		"#define MAX_LIGHTS " + std::to_string(MAX_LIGHTS) + "\n";
+		"#define MAX_POINT_LIGHTS " + std::to_string(MAX_POINT_LIGHTS) + "\n"
+		"#define MAX_SPOT_LIGHTS " + std::to_string(MAX_SPOT_LIGHTS) + "\n";
 
 	// point light
-	lightSProgs[LST_POINT].load(ShaderProgramResource::createSrcCodeToCache(
-		"shaders/IsLpGeneric.glsl",
-		(pps + "#define POINT_LIGHT 1\n").c_str()).c_str());
-
-	// spot light no shadow
-	lightSProgs[LST_SPOT].load(ShaderProgramResource::createSrcCodeToCache(
-		"shaders/IsLpGeneric.glsl",
-		(pps + "#define SPOT_LIGHT 1\n").c_str()).c_str());
-
-	// spot light w/t shadow
-	std::string pps2 = pps + "#define SPOT_LIGHT 1\n"
-		"#define SHADOW 1\n";
-	if(/*sm.isPcfEnabled()*/ 1) // XXX
-	{
-		pps2 += "#define PCF 1\n";
-	}
-	lightSProgs[LST_SPOT_SHADOW].load(
-		ShaderProgramResource::createSrcCodeToCache(
-		"shaders/IsLpGeneric.glsl", pps2.c_str()).c_str());
+	lightPassProg.load(ShaderProgramResource::createSrcCodeToCache(
+		"shaders/IsLpGeneric.glsl", pps.c_str()).c_str());
 
 	// Min max
-	std::string filename = ShaderProgramResource::createSrcCodeToCache(
-		"shaders/IsMinMax.glsl",
-		pps.c_str());
-	minMaxPassSprog.load(filename.c_str());
+	minMaxPassSprog.load(ShaderProgramResource::createSrcCodeToCache(
+		"shaders/IsMinMax.glsl", pps.c_str()).c_str());
 
 	//
 	// Create FBOs
@@ -221,40 +204,49 @@ void Is::initInternal(const RendererInitializer& initializer)
 	//
 
 	// Common UBO
-	/*const ShaderProgramUniformBlock& block =
-		lightSProgs[LST_POINT]->findUniformBlock("commonBlock");*/
-
 	commonUbo.create(sizeof(ShaderCommonUniforms), nullptr);
-	commonUbo.setBinding(0);
 
 	// lights UBO
-	lightsUbo.create(sizeof(ShaderSpotLights), nullptr);
-	lightsUbo.setBinding(1);
+	pointLightsUbo.create(sizeof(ShaderPointLights), nullptr);
+	spotLightsUbo.create(sizeof(ShaderSpotLights), nullptr);
 
 	// lightIndices UBO
 	tilesUbo.create(sizeof(ShaderTiles), nullptr);
-	tilesUbo.setBinding(2);
 
 	// Sanity checks
 	const ShaderProgramUniformBlock* ublock;
 
-	ublock = &lightSProgs[LST_POINT]->findUniformBlock("commonBlock");
+	ublock = &lightPassProg->findUniformBlock("commonBlock");
 	if(ublock->getSize() != sizeof(ShaderCommonUniforms)
-		|| ublock->getBindingPoint() != 0)
+		|| ublock->getBindingPoint() != COMMON_UNIFORMS_BLOCK_BINDING)
 	{
 		throw ANKI_EXCEPTION("Problem with the commonBlock");
 	}
 
-	ublock = &lightSProgs[LST_POINT]->findUniformBlock("lightsBlock");
+	ublock = &lightPassProg->findUniformBlock("pointLightsBlock");
 	if(ublock->getSize() != sizeof(ShaderPointLights)
-		|| ublock->getBindingPoint() != 1)
+		|| ublock->getBindingPoint() != POINT_LIGHTS_BLOCK_BINDING)
 	{
-		throw ANKI_EXCEPTION("Problem with the lightsBlock");
+		throw ANKI_EXCEPTION("Problem with the pointLightsBlock");
 	}
 
-	ublock = &lightSProgs[LST_POINT]->findUniformBlock("tilesBlock");
+	ublock = &lightPassProg->findUniformBlock("spotLightsBlock");
+	if(ublock->getSize() != sizeof(ShaderSpotLights)
+		|| ublock->getBindingPoint() != SPOT_LIGHTS_BLOCK_BINDING)
+	{
+		throw ANKI_EXCEPTION("Problem with the spotLightsBlock");
+	}
+
+	ublock = &lightPassProg->findUniformBlock("spotLightsBlock");
+	if(ublock->getSize() != sizeof(ShaderSpotLights)
+		|| ublock->getBindingPoint() != SPOT_LIGHTS_BLOCK_BINDING)
+	{
+		throw ANKI_EXCEPTION("Problem with the spotLightsBlock");
+	}
+
+	ublock = &lightPassProg->findUniformBlock("tilesBlock");
 	if(ublock->getSize() != sizeof(ShaderTiles)
-		|| ublock->getBindingPoint() != 2)
+		|| ublock->getBindingPoint() != TILES_BLOCK_BINDING)
 	{
 		throw ANKI_EXCEPTION("Problem with the tilesBlock");
 	}
@@ -278,6 +270,14 @@ Bool Is::cullLight(const PointLight& plight, const Tile& tile,
 	return true;
 }
 
+//==============================================================================
+Bool Is::cullLight(const SpotLight& light, const Tile& tile, 
+	const Mat4& viewMatrix)
+{
+	/// XXX
+	return false;
+}
+
 //==============================================================================
 void Is::updateAllTilesPlanesInternal(const PerspectiveCamera& cam)
 {
@@ -393,11 +393,11 @@ void Is::updateTiles()
 
 			/// Calculate as you do in the vertex position inside the shaders
 			F32 minZ =
-				-r->getPlanes().y() / (r->getPlanes().x() + pixels[j][i][0]);
+				r->getPlanes().y() / (r->getPlanes().x() + pixels[j][i][0]);
 			F32 maxZ =
 				-r->getPlanes().y() / (r->getPlanes().x() + pixels[j][i][1]);
 
-			tile.planes[Frustum::FP_NEAR] = Plane(Vec3(0.0, 0.0, -1.0), -minZ);
+			tile.planes[Frustum::FP_NEAR] = Plane(Vec3(0.0, 0.0, -1.0), minZ);
 			tile.planes[Frustum::FP_FAR] = Plane(Vec3(0.0, 0.0, 1.0), maxZ);
 		}
 	}
@@ -425,7 +425,7 @@ void Is::writeLightUbo(ShaderPointLights& shaderLights, U32 maxShaderLights,
 }
 
 //==============================================================================
-void Is::writeLightUbo(ShaderSpotLight& shaderLights, U32 maxShaderLights,
+void Is::writeLightUbo(ShaderSpotLights& shaderLights, U32 maxShaderLights,
 	SpotLight** visibleLights, U32 visibleLightsCount, U start, U end)
 {
 	const Camera& cam = r->getScene().getActiveCamera();
@@ -452,8 +452,9 @@ void Is::writeLightUbo(ShaderSpotLight& shaderLights, U32 maxShaderLights,
 }
 
 //==============================================================================
-template<typename TLight>
-void Is::writeTilesUbo(TLight** visibleLights, U32 visibleLightsCount,
+void Is::writeTilesUbo(
+	PointLight* visiblePointLights[], U32 visiblePointLightsCount,
+	SpotLight* visibleSpotLights[], U32 visibleSpotLightsCount,
 	ShaderTiles& shaderTiles, U32 maxLightsPerTile,
 	U32 start, U32 end)
 {
@@ -467,80 +468,125 @@ void Is::writeTilesUbo(TLight** visibleLights, U32 visibleLightsCount,
 
 		Tile& tile = tiles_[i];
 		Array<U32, MAX_LIGHTS_PER_TILE> lightIndices;
-		U lightsInTileCount = 0;
 
-		for(U j = 0; j < visibleLightsCount; j++)
+		// Point lights
+		//
+
+		U pointLightsInTileCount = 0;
+		for(U j = 0; j < visiblePointLightsCount; j++)
 		{
-			const TLight& light = *visibleLights[j];
+			const PointLight& light = *visiblePointLights[j];
 
 			if(cullLight(light, tile, cam.getViewMatrix()))
 			{
 				// Use % to avoid overflows
-				lightIndices[lightsInTileCount % maxLightsPerTile] = j;
-				++lightsInTileCount;
+				lightIndices[pointLightsInTileCount % maxLightsPerTile] = j;
+				++pointLightsInTileCount;
 			}
 		}
+
+		shaderTiles.tiles[i].lightsCount[0] = pointLightsInTileCount;
+
+		// Spot ligths
+		//
+
+		U spotLightsInTileCount = 0;
+		for(U j = 0; j < visibleSpotLightsCount; j++)
+		{
+			const SpotLight& light = *visibleSpotLights[j];
+
+			if(cullLight(light, tile, cam.getViewMatrix()))
+			{
+				U id = (pointLightsInTileCount + spotLightsInTileCount) 
+					% maxLightsPerTile;
+				// Use % to avoid overflows
+				lightIndices[id] = j;
+				++spotLightsInTileCount;
+			}
+		}
+
+		shaderTiles.tiles[i].lightsCount[1] = spotLightsInTileCount;
+
 #if 0
-		if(lightsInTileCount > maxLightsPerTile)
+		if(pointLightsInTileCount + spotLightsInTileCount > maxLightsPerTile)
 		{
 			ANKI_LOGW("Too many lights per tile: " << lightsInTileCount);
 		}
 #endif
-		shaderTiless.tiles[i].lightsCount = lightsInTileCount;
+		
+		U totalLightsInTileCount = std::min(
+			pointLightsInTileCount + spotLightsInTileCount,
+			(U)maxLightsPerTile);
 
 		memcpy(
 			&(shaderTiles.tiles[i].lightIndices[0]),
 			&lightIndices[0],
-			sizeof(U32) * lightsInTileCount);
+			sizeof(U32) * totalLightsInTileCount);
 	}
 }
 
 //==============================================================================
 void Is::pointLightsPass()
 {
+	ThreadPool& threadPool = ThreadPoolSingleton::get();
 	Camera& cam = r->getScene().getActiveCamera();
 	VisibilityInfo& vi = cam.getFrustumable()->getVisibilityInfo();
 
-	Array<PointLight*, MAX_LIGHTS> visibleLights;
-	U visibleLightsCount = 0;
-
-	ThreadPool& threadPool = ThreadPoolSingleton::get();
+	Array<PointLight*, MAX_POINT_LIGHTS> visiblePointLights;
+	U visiblePointLightsCount = 0;
+	Array<SpotLight*, MAX_SPOT_LIGHTS> visibleSpotLights;
+	U visibleSpotLightsCount = 0;
 
 	//
-	// Write the lightsUbo
+	// Quickly get the lights
 	//
 
-	// Quickly get the point lights
 	for(auto it = vi.getLightsBegin(); it != vi.getLightsEnd(); ++it)
 	{
 		Light* light = (*it);
-		if(light->getLightType() == Light::LT_POINT)
+		switch(light->getLightType())
 		{
+		case Light::LT_POINT:
 			// Use % to avoid overflows
-			visibleLights[visibleLightsCount % MAX_LIGHTS] = 
+			visiblePointLights[visiblePointLightsCount % MAX_POINT_LIGHTS] = 
 				static_cast<PointLight*>(light);
-			++visibleLightsCount;
+			++visiblePointLightsCount;
+			break;
+		case Light::LT_SPOT:
+			// Use % to avoid overflows
+			visibleSpotLights[visibleSpotLightsCount % MAX_SPOT_LIGHTS] = 
+				static_cast<SpotLight*>(light);
+			++visibleSpotLightsCount;
+			break;
+		case Light::LT_NUM:
+			break;
 		}
 	}
 
-	if(visibleLightsCount > MAX_LIGHTS)
+	if(visiblePointLightsCount > MAX_POINT_LIGHTS 
+		|| visibleSpotLightsCount > MAX_SPOT_LIGHTS)
 	{
 		throw ANKI_EXCEPTION("Too many visible lights");
 	}
 
+	//
+	// Write the lights UBO
+	//
+
 	// Map
-	ShaderPointLights* lightsMappedBuff = (ShaderPointLights*)lightsUbo.map(
+	ShaderPointLights* lightsMappedBuff = 
+		(ShaderPointLights*)pointLightsUbo.map(
 		0, 
-		sizeof(ShaderPointLight) * visibleLightsCount,
+		sizeof(ShaderPointLight) * visiblePointLightsCount,
 		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
 
 	WritePointLightsUbo 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].maxShaderLights = MAX_POINT_LIGHTS;
+		jobs[i].visibleLights = &visiblePointLights[0];
+		jobs[i].visibleLightsCount = visiblePointLightsCount;
 		jobs[i].is = this;
 
 		threadPool.assignNewJob(i, &jobs[i]);
@@ -548,102 +594,29 @@ void Is::pointLightsPass()
 
 	// Done
 	threadPool.waitForAllJobsToFinish();
-	lightsUbo.unmap();
+	pointLightsUbo.unmap();
 
-	//
-	// Update the tiles
-	//
-
-	ShaderTiles* stiles = (ShaderTiles*)tilesUbo.map(
-		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
-
-	WriteTilesUboJob<PointLight> 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[LST_POINT];
-	shader.bind();
-
-	shader.findUniformVariable("msFai0").set(r->getMs().getFai0());
-	shader.findUniformVariable("msDepthFai").set(
-		r->getMs().getDepthFai());
-
-	r->drawQuadInstanced(TILES_Y_COUNT * TILES_X_COUNT);
-}
-
-//==============================================================================
-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,
+	// Map
+	ShaderSpotLights* shaderSpotLights = (ShaderSpotLights*)spotLightsUbo.map(
+		0,
+		sizeof(ShaderSpotLights) * visibleSpotLightsCount,
 		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
 
-	WriteSpotLightsUbo jobs[ThreadPool::MAX_THREADS];
+	WriteSpotLightsUbo jobs2[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;
+		jobs2[i].shaderLights = shaderSpotLights;
+		jobs2[i].maxShaderLights = MAX_SPOT_LIGHTS;
+		jobs2[i].visibleLights = &visibleSpotLights[0];
+		jobs2[i].visibleLightsCount = visibleSpotLightsCount;
+		jobs2[i].is = this;
 
-		threadPool.assignNewJob(i, &jobs[i]);
+		threadPool.assignNewJob(i, &jobs2[i]);
 	}
 
 	// Done
 	threadPool.waitForAllJobsToFinish();
-	lightsUbo.unmap();
+	spotLightsUbo.unmap();
 
 	//
 	// Update the tiles
@@ -652,11 +625,13 @@ void Is::spotLightsPass(Bool shadow)
 	ShaderTiles* stiles = (ShaderTiles*)tilesUbo.map(
 		GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
 
-	WriteTilesUboJob<SpotLight> tjobs[ThreadPool::MAX_THREADS];
+	WriteTilesUboJob tjobs[ThreadPool::MAX_THREADS];
 	for(U i = 0; i < threadPool.getThreadsCount(); i++)
 	{
-		tjobs[i].visibleLights = &visibleLights[0];
-		tjobs[i].visibleLightsCount = visibleLightsCount;
+		tjobs[i].visiblePointLights = &visiblePointLights[0];
+		tjobs[i].visiblePointLightsCount = visiblePointLightsCount;
+		tjobs[i].visibleSpotLights = &visibleSpotLights[0];
+		tjobs[i].visibleSpotLightsCount = visibleSpotLightsCount;
 		tjobs[i].shaderTiles = stiles;
 		tjobs[i].maxLightsPerTile = MAX_LIGHTS_PER_TILE;
 		tjobs[i].is = this;
@@ -666,18 +641,16 @@ void Is::spotLightsPass(Bool shadow)
 
 	threadPool.waitForAllJobsToFinish();
 	tilesUbo.unmap();
-	
+
 	//
 	// Setup shader and draw
 	//
 	
 	// shader prog
-	const ShaderProgram& shader = *lightSProgs[
-		(shadow) ? LST_SPOT_SHADOW : LST_SPOT];
-	shader.bind();
+	lightPassProg->bind();
 
-	shader.findUniformVariable("msFai0").set(r->getMs().getFai0());
-	shader.findUniformVariable("msDepthFai").set(
+	lightPassProg->findUniformVariable("msFai0").set(r->getMs().getFai0());
+	lightPassProg->findUniformVariable("msDepthFai").set(
 		r->getMs().getDepthFai());
 
 	r->drawQuadInstanced(TILES_Y_COUNT * TILES_X_COUNT);
@@ -708,9 +681,9 @@ void Is::run()
 		commonUboUpdateTimestamp = Timestamp::getTimestamp();
 	}
 
-	commonUbo.setBinding(0);
-	lightsUbo.setBinding(1);
-	tilesUbo.setBinding(2);
+	commonUbo.setBinding(COMMON_UNIFORMS_BLOCK_BINDING);
+	pointLightsUbo.setBinding(POINT_LIGHTS_BLOCK_BINDING);
+	tilesUbo.setBinding(TILES_BLOCK_BINDING);
 
 	// Update tiles
 	updateTiles();
@@ -720,10 +693,6 @@ 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

+ 2 - 1
src/resource/ShaderProgramResource.cpp

@@ -53,7 +53,8 @@ std::string ShaderProgramResource::createSrcCodeToCache(
 
 	// Create suffix
 	std::hash<std::string> stringHash;
-	std::size_t h = stringHash(preAppendedSrcCode);
+	std::size_t h = stringHash(std::string(sProgFPathName) 
+		+ preAppendedSrcCode);
 	std::string suffix = std::to_string(h);
 
 	//