Pārlūkot izejas kodu

Enabling SSAO and HDR

Panagiotis Christopoulos Charitos 13 gadi atpakaļ
vecāks
revīzija
3a617ee343

+ 1 - 1
include/anki/Config.h.cmake

@@ -26,7 +26,7 @@
 #if defined(NDEBUG)
 #if defined(NDEBUG)
 #	define ANKI_DEBUG !NDEBUG
 #	define ANKI_DEBUG !NDEBUG
 #else
 #else
-#	define ANKI_DEBUG 0
+#	define ANKI_DEBUG 1
 #endif
 #endif
 
 
 #define ANKI_FILE __BASE_FILE__
 #define ANKI_FILE __BASE_FILE__

+ 2 - 2
include/anki/gl/Texture.h

@@ -106,8 +106,8 @@ private:
 		GLuint tex;
 		GLuint tex;
 		
 		
 		/// Born time. The bigger the value the latter the unit has been
 		/// Born time. The bigger the value the latter the unit has been
-		/// accessed. This practicaly means that if the @a born is low the
-		/// unit is a canditate for replacement
+		/// accessed. This practically means that if the @a born is low the
+		/// unit is a candidate for replacement
 		U64 born;
 		U64 born;
 	};
 	};
 
 

+ 22 - 48
include/anki/renderer/Hdr.h

@@ -6,6 +6,8 @@
 #include "anki/resource/TextureResource.h"
 #include "anki/resource/TextureResource.h"
 #include "anki/resource/ShaderProgramResource.h"
 #include "anki/resource/ShaderProgramResource.h"
 #include "anki/resource/Resource.h"
 #include "anki/resource/Resource.h"
+#include "anki/core/Timestamp.h"
+#include "anki/gl/Ubo.h"
 
 
 namespace anki {
 namespace anki {
 
 
@@ -26,55 +28,23 @@ public:
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
-	float getExposure() const
+	F32 getExposure() const
 	{
 	{
 		return exposure;
 		return exposure;
 	}
 	}
-	void setExposure(const float x)
+	void setExposure(const F32 x)
 	{
 	{
 		exposure = x;
 		exposure = x;
-		toneSProg.bind();
-		toneSProg.findUniformVariable("exposure").set(exposure);
+		parameterUpdateTimestamp = Timestamp::getTimestamp();
 	}
 	}
 
 
-	uint getBlurringIterationsNum() const
+	uint getBlurringIterationsCount() const
 	{
 	{
-		return blurringIterationsNum;
+		return blurringIterationsCount;
 	}
 	}
-	void setBlurringIterationsNum(const uint x)
+	void setBlurringIterationsCount(const uint x)
 	{
 	{
-		blurringIterationsNum = x;
-	}
-
-	float getBlurringDistance() const
-	{
-		return blurringDist;
-	}
-	void setBlurringDistance(const float x)
-	{
-		blurringDist = x;
-
-		hblurSProg.bind();
-		hblurSProg.findUniformVariable("blurringDist").set(
-			float(blurringDist / width));
-		vblurSProg.bind();
-		vblurSProg.findUniformVariable("blurringDist").set(
-			float(blurringDist / height));
-	}
-
-	float getRenderingQuality() const
-	{
-		return renderingQuality;
-	}
-
-	const Texture& getToneFai() const
-	{
-		return toneFai;
-	}
-
-	const Texture& getHblurFai() const
-	{
-		return hblurFai;
+		blurringIterationsCount = x;
 	}
 	}
 
 
 	const Texture& getFai() const
 	const Texture& getFai() const
@@ -84,23 +54,27 @@ public:
 	/// @}
 	/// @}
 
 
 private:
 private:
-	uint32_t width;
-	uint32_t height;
-	float exposure = 4.0; ///< How bright is the HDR
-	uint32_t blurringIterationsNum = 2; ///< The blurring iterations of the tone map
-	float blurringDist = 1.0; ///< Distance in blurring
-	float renderingQuality = 0.5;
+	U32 width;
+	U32 height;
+	F32 exposure = 4.0; ///< How bright is the HDR
+	U32 blurringIterationsCount = 2; ///< The blurring iterations of the tone map
+	F32 blurringDist = 1.0; ///< Distance in blurring
+	F32 renderingQuality = 0.5;
 	Fbo toneFbo;
 	Fbo toneFbo;
 	Fbo hblurFbo;
 	Fbo hblurFbo;
 	Fbo vblurFbo;
 	Fbo vblurFbo;
-	ShaderProgramResource toneSProg;
-	ShaderProgramResource hblurSProg;
-	ShaderProgramResource vblurSProg;
+	ShaderProgramResourcePointer toneSProg;
+	ShaderProgramResourcePointer hblurSProg;
+	ShaderProgramResourcePointer vblurSProg;
 	Texture toneFai; ///< Vertical blur pass FAI
 	Texture toneFai; ///< Vertical blur pass FAI
 	Texture hblurFai; ///< pass0Fai with the horizontal blur FAI
 	Texture hblurFai; ///< pass0Fai with the horizontal blur FAI
 	Texture fai; ///< The final FAI
 	Texture fai; ///< The final FAI
+	U32 parameterUpdateTimestamp = Timestamp::getTimestamp();
+	U32 commonUboUpdateTimestamp = Timestamp::getTimestamp();
+	Ubo commonUbo;
 
 
 	void initFbo(Fbo& fbo, Texture& fai);
 	void initFbo(Fbo& fbo, Texture& fai);
+	void initInternal(const RendererInitializer& initializer);
 };
 };
 
 
 } // end namespace
 } // end namespace

+ 8 - 17
include/anki/renderer/Pps.h

@@ -18,12 +18,11 @@ class ShaderProgram;
 class Pps: private RenderingPass
 class Pps: private RenderingPass
 {
 {
 public:
 public:
-	Pps(Renderer* r_);
+	Pps(Renderer* r);
 	~Pps();
 	~Pps();
 
 
 	void init(const RendererInitializer& initializer);
 	void init(const RendererInitializer& initializer);
-	void runPrePass();
-	void runPostPass();
+	void run();
 
 
 	/// @name Accessors
 	/// @name Accessors
 	/// @{
 	/// @{
@@ -50,14 +49,9 @@ public:
 		return bl;
 		return bl;
 	}
 	}
 
 
-	const Texture& getPrePassFai() const
+	const Texture& getFai() const
 	{
 	{
-		return prePassFai;
-	}
-
-	const Texture& getPostPassFai() const
-	{
-		return postPassFai;
+		return fai;
 	}
 	}
 	/// @}
 	/// @}
 
 
@@ -69,14 +63,11 @@ private:
 	Bl bl;
 	Bl bl;
 	/// @}
 	/// @}
 
 
-	Fbo prePassFbo;
-	Fbo postPassFbo;
-
-	ShaderProgramResource prePassSProg;
-	ShaderProgramResource postPassSProg;
+	Fbo fbo;
+	ShaderProgramResourcePointer prog;
+	Texture fai;
 
 
-	Texture prePassFai; ///< FAI #1
-	Texture postPassFai; ///< FAI #2
+	void initInternal(const RendererInitializer& initializer);
 };
 };
 
 
 
 

+ 1 - 1
include/anki/renderer/Renderer.h

@@ -52,7 +52,7 @@ struct RendererInitializer
 			Bool enabled = true;
 			Bool enabled = true;
 			F32 renderingQuality = 0.25;
 			F32 renderingQuality = 0.25;
 			F32 blurringDist = 1.0;
 			F32 blurringDist = 1.0;
-			F32 blurringIterationsNum = 2;
+			F32 blurringIterationsCount = 2;
 			F32 exposure = 4.0;
 			F32 exposure = 4.0;
 		} hdr;
 		} hdr;
 
 

+ 13 - 7
include/anki/renderer/Ssao.h

@@ -7,6 +7,8 @@
 #include "anki/resource/Resource.h"
 #include "anki/resource/Resource.h"
 #include "anki/gl/Fbo.h"
 #include "anki/gl/Fbo.h"
 #include "anki/gl/Texture.h"
 #include "anki/gl/Texture.h"
+#include "anki/gl/Ubo.h"
+#include "anki/core/Timestamp.h"
 
 
 namespace anki {
 namespace anki {
 
 
@@ -15,7 +17,8 @@ namespace anki {
 /// Three passes:
 /// Three passes:
 /// @li Calc ssao factor
 /// @li Calc ssao factor
 /// @li Blur vertically
 /// @li Blur vertically
-/// @li Blur horizontally repeat 2, 3
+/// @li Blur horizontally
+/// @li Repeat from 2
 class Ssao: public SwitchableRenderingPass
 class Ssao: public SwitchableRenderingPass
 {
 {
 public:
 public:
@@ -43,18 +46,21 @@ private:
 	Texture ssaoFai; ///< It contains the unblurred SSAO factor
 	Texture ssaoFai; ///< It contains the unblurred SSAO factor
 	Texture hblurFai;
 	Texture hblurFai;
 	Texture fai;  ///< AKA vblurFai The final FAI
 	Texture fai;  ///< AKA vblurFai The final FAI
-	float renderingQuality;
-	uint32_t blurringIterationsNum;
+	F32 renderingQuality;
+	U32 blurringIterationsCount;
 	Fbo ssaoFbo;
 	Fbo ssaoFbo;
 	Fbo hblurFbo;
 	Fbo hblurFbo;
 	Fbo vblurFbo;
 	Fbo vblurFbo;
 	TextureResourcePointer noiseMap;
 	TextureResourcePointer noiseMap;
-	ShaderProgramResource ssaoSProg;
-	ShaderProgramResource hblurSProg;
-	ShaderProgramResource vblurSProg;
-	uint32_t width, height;
+	ShaderProgramResourcePointer ssaoSProg;
+	ShaderProgramResourcePointer hblurSProg;
+	ShaderProgramResourcePointer vblurSProg;
+	U32 width, height;
+	U32 commonUboUpdateTimestamp = Timestamp::getTimestamp();
+	Ubo commonUbo;
 
 
 	void createFbo(Fbo& fbo, Texture& fai);
 	void createFbo(Fbo& fbo, Texture& fai);
+	void initInternal(const RendererInitializer& initializer);
 };
 };
 
 
 } // end namespace anki
 } // end namespace anki

+ 3 - 10
shaders/Final.glsl

@@ -6,24 +6,17 @@
 
 
 #pragma anki start fragmentShader
 #pragma anki start fragmentShader
 
 
-#if 0
-uniform usampler2D rasterImage;
-#else
 uniform sampler2D rasterImage;
 uniform sampler2D rasterImage;
-#endif
 
 
 in vec2 vTexCoords;
 in vec2 vTexCoords;
 layout(location = 0) out vec3 fFragColor;
 layout(location = 0) out vec3 fFragColor;
 
 
 void main()
 void main()
 {
 {
-#if 0
-	uvec2 a = texture2D(rasterImage, vTexCoords).rg;
-	vec4 diffAndSpec = unpackUnorm4x8(a.x);
-	fFragColor = diffAndSpec.rgb;
-#else
+#if 1
 	vec3 col = texture2D(rasterImage, vTexCoords).rgb;
 	vec3 col = texture2D(rasterImage, vTexCoords).rgb;
 	fFragColor = col;
 	fFragColor = col;
+#else
+	fFragColor = vec3(texture2D(rasterImage, vTexCoords).r);
 #endif
 #endif
-	//fFragColor = texture2D(rasterImage, vTexCoords).rgb;
 }
 }

+ 8 - 5
shaders/GaussianBlurGeneric.glsl

@@ -39,11 +39,14 @@ void main()
 #endif
 #endif
 
 
 uniform sampler2D img; ///< Input FAI
 uniform sampler2D img; ///< Input FAI
-uniform float blurringDist = 0.0;
 
 
 in vec2 vTexCoords;
 in vec2 vTexCoords;
 in vec2 vOffsets;
 in vec2 vOffsets;
 
 
+#if !defined(BLURRING_DIST)
+#	define BLURRING_DIST 0.0
+#endif
+
 // Determine color type
 // Determine color type
 #if defined(COL_RGBA)
 #if defined(COL_RGBA)
 #	define COL_TYPE vec4
 #	define COL_TYPE vec4
@@ -81,18 +84,18 @@ void main()
 	for(int i = 0; i < 2; i++)
 	for(int i = 0; i < 2; i++)
 	{
 	{
 #if defined(HPASS)
 #if defined(HPASS)
-		vec2 tc = vec2(vTexCoords.x + blurringDist + BLURRING_OFFSET[i], 
+		vec2 tc = vec2(vTexCoords.x + BLURRING_DIST + BLURRING_OFFSET[i], 
 			vTexCoords.y);
 			vTexCoords.y);
 		col += texture2D(img, tc).TEX_FETCH * WEIGHTS[i];
 		col += texture2D(img, tc).TEX_FETCH * WEIGHTS[i];
 
 
-		tc.x = vTexCoords.x - blurringDist - BLURRING_OFFSET[i];
+		tc.x = vTexCoords.x - BLURRING_DIST - BLURRING_OFFSET[i];
 		col += texture2D(img, tc).TEX_FETCH * WEIGHTS[i];
 		col += texture2D(img, tc).TEX_FETCH * WEIGHTS[i];
 #elif defined(VPASS)
 #elif defined(VPASS)
 		vec2 tc = vec2(vTexCoords.x, 
 		vec2 tc = vec2(vTexCoords.x, 
-			vTexCoords.y + blurringDist + BLURRING_OFFSET[i]);
+			vTexCoords.y + BLURRING_DIST + BLURRING_OFFSET[i]);
 		col += texture2D(img, tc).TEX_FETCH * WEIGHTS[i];
 		col += texture2D(img, tc).TEX_FETCH * WEIGHTS[i];
 
 
-		tc.y = vTexCoords.y - blurringDist - BLURRING_OFFSET[i];
+		tc.y = vTexCoords.y - BLURRING_DIST - BLURRING_OFFSET[i];
 		col += texture2D(img, tc).TEX_FETCH * WEIGHTS[i];
 		col += texture2D(img, tc).TEX_FETCH * WEIGHTS[i];
 #endif
 #endif
 	}
 	}

+ 16 - 15
shaders/IsLpGeneric.glsl

@@ -12,14 +12,6 @@
 #pragma anki include "shaders/Pack.glsl"
 #pragma anki include "shaders/Pack.glsl"
 #pragma anki include "shaders/LinearDepth.glsl"
 #pragma anki include "shaders/LinearDepth.glsl"
 
 
-#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
-
 #define ATTENUATION_FINE 0
 #define ATTENUATION_FINE 0
 
 
 #define ATTENUATION_BOOST (0.1)
 #define ATTENUATION_BOOST (0.1)
@@ -51,7 +43,7 @@ layout(std140, row_major, binding = 0) uniform commonBlock
 struct Light
 struct Light
 {
 {
 	vec4 posAndRadius; ///< xyz: Light pos in eye space. w: The radius
 	vec4 posAndRadius; ///< xyz: Light pos in eye space. w: The radius
-	vec4 diffuseColor;
+	vec4 diffuseColorShadowmapId;
 	vec4 specularColor;
 	vec4 specularColor;
 };
 };
 
 
@@ -59,6 +51,7 @@ struct SpotLight
 {
 {
 	Light light;
 	Light light;
 	vec4 lightDirection;
 	vec4 lightDirection;
+	vec4 outerCosInnerCos;
 	mat4 texProjectionMat;
 	mat4 texProjectionMat;
 };
 };
 
 
@@ -151,7 +144,7 @@ vec3 calcPhong(in vec3 fragPosVspace, in vec3 diffuse,
 	in vec2 specularAll, in vec3 normal, in Light light, in vec3 rayDir)
 	in vec2 specularAll, in vec3 normal, in Light light, in vec3 rayDir)
 {
 {
 	// Diffuse
 	// Diffuse
-	vec3 difCol = diffuse * light.diffuseColor.rgb;
+	vec3 difCol = diffuse * light.diffuseColorShadowmapId.rgb;
 
 
 	// Specular
 	// Specular
 	vec3 eyeVec = normalize(fragPosVspace);
 	vec3 eyeVec = normalize(fragPosVspace);
@@ -170,8 +163,8 @@ float calcSpotFactor(in SpotLight light, in vec3 fragPosVspace)
 
 
 	float costheta = dot(l, light.lightDirection.xyz);
 	float costheta = dot(l, light.lightDirection.xyz);
 	float spotFactor = smoothstep(
 	float spotFactor = smoothstep(
-		light.light.diffuseColor.w, 
-		light.light.specularColor.w, 
+		light.outerCosInnerCos.x, 
+		light.outerCosInnerCos.y, 
 		costheta);
 		costheta);
 
 
 	return spotFactor;
 	return spotFactor;
@@ -286,8 +279,11 @@ void main()
 
 
 		//if(midFactor > 0.0)
 		//if(midFactor > 0.0)
 		{
 		{
-			float shadow = calcShadowFactor(slights[lightId], fragPosVspace,
-				shadowMaps[i]);
+			const uint shadowmapId = floatBitsToUint(
+					slights[lightId].light.diffuseColorShadowmapId.w);
+
+			const float shadow = calcShadowFactor(slights[lightId], 
+				fragPosVspace, shadowMaps[shadowmapId]);
 
 
 			const vec3 col = calcPhong(fragPosVspace, diffuseAndSpec.rgb, 
 			const vec3 col = calcPhong(fragPosVspace, diffuseAndSpec.rgb, 
 				specularAll, normal, slights[lightId].light, ray);
 				specularAll, normal, slights[lightId].light, ray);
@@ -325,9 +321,14 @@ void main()
 #endif
 #endif
 
 
 #if 0
 #if 0
-	if(tiles[vInstanceId].lightsCount[0] > 0)
+	if(tiles[vInstanceId].lightsCount[2] == 1)
 	{
 	{
 		fColor += vec3(0.0, 0.1, 0.0);
 		fColor += vec3(0.0, 0.1, 0.0);
 	}
 	}
+
+	if(tiles[vInstanceId].lightsCount[2] == 2)
+	{
+		fColor += vec3(0.0, 0.0, 0.1);
+	}
 #endif
 #endif
 }
 }

+ 11 - 14
shaders/PpsPostPass.glsl → shaders/Pps.glsl

@@ -6,16 +6,14 @@
 
 
 #pragma anki include "shaders/photoshop_filters.glsl"
 #pragma anki include "shaders/photoshop_filters.glsl"
 
 
-uniform sampler2D ppsPrePassFai;
+uniform sampler2D isFai;
 uniform sampler2D ppsHdrFai;
 uniform sampler2D ppsHdrFai;
+uniform sampler2D ppsSsaoFai;
 
 
 in vec2 vTexCoords;
 in vec2 vTexCoords;
 
 
-layout(location = 0) out vec3 fFragColor;
+layout(location = 0) out vec3 fColor;
 
 
-
-//==============================================================================
-// GrayScale                                                                   =
 //==============================================================================
 //==============================================================================
 vec3 grayScale(in vec3 col)
 vec3 grayScale(in vec3 col)
 {
 {
@@ -23,9 +21,6 @@ vec3 grayScale(in vec3 col)
 	return vec3(grey);
 	return vec3(grey);
 }
 }
 
 
-
-//==============================================================================
-// saturation                                                                  =
 //==============================================================================
 //==============================================================================
 vec3 saturation(in vec3 col, in float factor)
 vec3 saturation(in vec3 col, in float factor)
 {
 {
@@ -35,13 +30,10 @@ vec3 saturation(in vec3 col, in float factor)
 	return mix(intensity, col, factor);
 	return mix(intensity, col, factor);
 }
 }
 
 
-
-//==============================================================================
-// main                                                                        =
 //==============================================================================
 //==============================================================================
 void main(void)
 void main(void)
 {
 {
-	fFragColor = texture2D(ppsPrePassFai, vTexCoords).rgb;
+	fColor = texture2D(isFai, vTexCoords).rgb;
 
 
 	/*const float gamma = 0.7;
 	/*const float gamma = 0.7;
 	color.r = pow(color.r, 1.0 / gamma);
 	color.r = pow(color.r, 1.0 / gamma);
@@ -50,9 +42,14 @@ void main(void)
 
 
 #if defined(HDR_ENABLED)
 #if defined(HDR_ENABLED)
 	vec3 hdr = texture2D(ppsHdrFai, vTexCoords).rgb;
 	vec3 hdr = texture2D(ppsHdrFai, vTexCoords).rgb;
-	fFragColor += hdr;
+	fColor += hdr;
+#endif
+
+#if defined(SSAO_ENABLED)
+	float ssao = texture2D(ppsSsaoFai, vTexCoords).r;
+	fColor *= ssao;
 #endif
 #endif
 
 
-	fFragColor = BlendHardLight(vec3(0.6, 0.62, 0.4), fFragColor);
+	fColor = BlendHardLight(vec3(0.6, 0.62, 0.4), fColor);
 }
 }
 
 

+ 7 - 1
shaders/PpsHdr.glsl

@@ -5,7 +5,13 @@
 #pragma anki start fragmentShader
 #pragma anki start fragmentShader
 
 
 uniform sampler2D fai; ///< Its the IS FAI
 uniform sampler2D fai; ///< Its the IS FAI
-uniform float exposure;
+
+layout(std140, binding = 0) uniform commonBlock
+{
+	vec4 exposure_;
+};
+
+#define exposure exposure_.x
 
 
 in vec2 vTexCoords;
 in vec2 vTexCoords;
 
 

+ 0 - 23
shaders/PpsPrePass.glsl

@@ -1,23 +0,0 @@
-#pragma anki start vertexShader
-
-#pragma anki include "shaders/SimpleVert.glsl"
-
-#pragma anki start fragmentShader
-
-uniform sampler2D isFai;
-uniform sampler2D ppsSsaoFai;
-
-in vec2 vTexCoords;
-
-layout(location = 0) out vec3 fFragColor;
-
-void main(void)
-{
-	fFragColor = texture2D(isFai, vTexCoords).rgb;
-
-	#if defined(SSAO_ENABLED)
-		float ssaoFactor = texture2D(ppsSsaoFai, vTexCoords).r;
-		fFragColor *= ssaoFactor;
-	#endif
-}
-

+ 46 - 47
shaders/PpsSsao.glsl

@@ -6,21 +6,6 @@
 
 
 #pragma anki include "shaders/Pack.glsl"
 #pragma anki include "shaders/Pack.glsl"
 
 
-/// @name Uniforms
-/// @{
-uniform vec2 planes; ///< for the calculation of frag pos in view space
-uniform vec2 limitsOfNearPlane; ///< for the calculation of frag pos in view space
-uniform vec2 limitsOfNearPlane2; ///< This is an optimization see r403 for the clean one
-uniform float zNear; ///< for the calculation of frag pos in view space
-uniform sampler2D msDepthFai; ///< for the calculation of frag pos in view space
-
-uniform sampler2D noiseMap; /// Used in getRandom
-uniform float noiseMapSize = 0.0; /// Used in getRandom
-uniform vec2 screenSize = vec2(0.0); /// Used in getRandom
-
-uniform sampler2D msNormalFai; /// Used in getNormal
-/// @}
-
 /// @name Varyings
 /// @name Varyings
 /// @{
 /// @{
 in vec2 vTexCoords;
 in vec2 vTexCoords;
@@ -31,31 +16,51 @@ in vec2 vTexCoords;
 layout(location = 0) out float fColor;
 layout(location = 0) out float fColor;
 /// @}
 /// @}
 
 
-/// @name Consts
+
+/// @name Uniforms
 /// @{
 /// @{
-uniform float SAMPLE_RAD = 0.08;  /// Used in main
-uniform float SCALE = 1.0; /// Used in doAmbientOcclusion
-uniform float INTENSITY = 3.0; /// Used in doAmbientOcclusion
-uniform float BIAS = 0.00; /// Used in doAmbientOcclusion
+layout(std140, row_major, binding = 0) uniform commonBlock
+{
+	/// Packs:
+	/// - x: zNear. For the calculation of frag pos in view space
+	/// - zw: Planes. For the calculation of frag pos in view space
+	uniform vec4 nearPlanes;
+
+	/// For the calculation of frag pos in view space. The xy is the 
+	/// limitsOfNearPlane and the zw is an optimization see PpsSsao.glsl and 
+	/// r403 for the clean one
+	uniform vec4 limitsOfNearPlane_;
+};
+
+#define planes nearPlanes.zw
+#define zNear nearPlanes.x
+#define limitsOfNearPlane limitsOfNearPlane_.xy
+#define limitsOfNearPlane2 limitsOfNearPlane_.zw
+
+uniform sampler2D msDepthFai;
+uniform usampler2D msGFai;
+uniform sampler2D noiseMap; 
 /// @}
 /// @}
 
 
+#define SAMPLE_RAD 0.08
+#define SCALE 1.0
+#define INTENSITY 3.0
+#define BIAS 0.00
 
 
-/// globals: msNormalFai
 vec3 getNormal(in vec2 uv)
 vec3 getNormal(in vec2 uv)
 {
 {
-	return unpackNormal(texture2D(msNormalFai, uv).rg);
+	uvec2 msAll = texture(msGFai, uv).rg;
+	vec3 normal = unpackNormal(unpackHalf2x16(msAll[1]));
+	return normal;
 }
 }
 
 
-
-/// globals: noiseMap, screenSize, noiseMapSize
 vec2 getRandom(in vec2 uv)
 vec2 getRandom(in vec2 uv)
 {
 {
-	return normalize(texture2D(noiseMap, screenSize * uv / noiseMapSize).xy * 2.0 - 1.0);
+	vec2 noise = texture2D(noiseMap, 
+		vec2(WIDTH, HEIGHT) * uv / NOISE_MAP_SIZE / 2.0).xy;
+	return normalize(noise * 2.0 - 1.0);
 }
 }
 
 
-
-/// Get frag position in view space
-/// globals: msDepthFai, planes, zNear, limitsOfNearPlane
 vec3 getPosition(in vec2 uv)
 vec3 getPosition(in vec2 uv)
 {
 {
 	float depth = texture2D(msDepthFai, uv).r;
 	float depth = texture2D(msDepthFai, uv).r;
@@ -63,18 +68,15 @@ vec3 getPosition(in vec2 uv)
 	vec3 fragPosVspace;
 	vec3 fragPosVspace;
 	fragPosVspace.z = -planes.y / (planes.x + depth);
 	fragPosVspace.z = -planes.y / (planes.x + depth);
 	
 	
-	// Old: fragPosVspace.xy = (uv * 2.0 - 1.0) * limitsOfNearPlane;
 	fragPosVspace.xy = (uv * limitsOfNearPlane2) - limitsOfNearPlane;
 	fragPosVspace.xy = (uv * limitsOfNearPlane2) - limitsOfNearPlane;
 	
 	
-	float sc = -fragPosVspace.z / zNear;
+	const float sc = -fragPosVspace.z / zNear;
 	fragPosVspace.xy *= sc;
 	fragPosVspace.xy *= sc;
 
 
 	return fragPosVspace;
 	return fragPosVspace;
 }
 }
 
 
-
-/// Calculate the ambient occlusion factor
-float doAmbientOcclusion(in vec2 uv, in vec3 original, in vec3 cnorm)
+float calcAmbientOcclusionFactor(in vec2 uv, in vec3 original, in vec3 cnorm)
 {
 {
 	vec3 newp = getPosition(uv);
 	vec3 newp = getPosition(uv);
 	vec3 diff = newp - original;
 	vec3 diff = newp - original;
@@ -85,20 +87,19 @@ float doAmbientOcclusion(in vec2 uv, in vec3 original, in vec3 cnorm)
 	return ret;
 	return ret;
 }
 }
 
 
+#define KERNEL_SIZE 16
+const vec2 KERNEL[KERNEL_SIZE] = vec2[](
+	vec2(0.53812504, 0.18565957), vec2(0.13790712, 0.24864247), 
+	vec2(0.33715037, 0.56794053), vec2(-0.6999805, -0.04511441),
+	vec2(0.06896307, -0.15983082), vec2(0.056099437, 0.006954967),
+	vec2(-0.014653638, 0.14027752), vec2(0.010019933, -0.1924225),
+	vec2(-0.35775623, -0.5301969), vec2(-0.3169221, 0.106360726),
+	vec2(0.010350345, -0.58698344), vec2(-0.08972908, -0.49408212),
+	vec2(0.7119986, -0.0154690035), vec2(-0.053382345, 0.059675813),
+	vec2(0.035267662, -0.063188605), vec2(-0.47761092, 0.2847911));
 
 
 void main(void)
 void main(void)
 {
 {
-	const int KERNEL_SIZE = 16;
-
-	const vec2 KERNEL[KERNEL_SIZE] = vec2[](vec2(0.53812504, 0.18565957), vec2(0.13790712, 0.24864247), 
-	                                        vec2(0.33715037, 0.56794053), vec2(-0.6999805, -0.04511441),
-	                                        vec2(0.06896307, -0.15983082), vec2(0.056099437, 0.006954967),
-	                                        vec2(-0.014653638, 0.14027752), vec2(0.010019933, -0.1924225),
-	                                        vec2(-0.35775623, -0.5301969), vec2(-0.3169221, 0.106360726),
-	                                        vec2(0.010350345, -0.58698344), vec2(-0.08972908, -0.49408212),
-	                                        vec2(0.7119986, -0.0154690035), vec2(-0.053382345, 0.059675813),
-	                                        vec2(0.035267662, -0.063188605), vec2(-0.47761092, 0.2847911));
-
 	vec3 p = getPosition(vTexCoords);
 	vec3 p = getPosition(vTexCoords);
 	vec3 n = getNormal(vTexCoords);
 	vec3 n = getNormal(vTexCoords);
 	vec2 rand = getRandom(vTexCoords);
 	vec2 rand = getRandom(vTexCoords);
@@ -109,11 +110,9 @@ void main(void)
 	for(int j = 0; j < KERNEL_SIZE; ++j)
 	for(int j = 0; j < KERNEL_SIZE; ++j)
 	{
 	{
 		vec2 coord = reflect(KERNEL[j], rand) * SAMPLE_RAD;
 		vec2 coord = reflect(KERNEL[j], rand) * SAMPLE_RAD;
-		fColor += doAmbientOcclusion(vTexCoords + coord, p, n);
+		fColor += calcAmbientOcclusionFactor(vTexCoords + coord, p, n);
 	}
 	}
 
 
 	fColor = 1.0 - fColor / KERNEL_SIZE;
 	fColor = 1.0 - fColor / KERNEL_SIZE;
-
-	//fColor = fColor - fColor + rand.x;
 }
 }
 
 

+ 5 - 5
src/event/MainRendererPpsHdrEvent.cpp

@@ -18,8 +18,8 @@ MainRendererPpsHdrEvent::MainRendererPpsHdrEvent(float startTime,
 	const Hdr& hdr =
 	const Hdr& hdr =
 		MainRendererSingleton::get().getPps().getHdr();
 		MainRendererSingleton::get().getPps().getHdr();
 	originalData.exposure = hdr.getExposure();
 	originalData.exposure = hdr.getExposure();
-	originalData.blurringIterationsNum = hdr.getBlurringIterationsNum();
-	originalData.blurringDist = hdr.getBlurringDistance();
+	originalData.blurringIterationsNum = hdr.getBlurringIterationsCount();
+	//originalData.blurringDist = hdr.getBlurringDistance();
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -50,12 +50,12 @@ void MainRendererPpsHdrEvent::updateSp(float /*prevUpdateTime*/, float crntTime)
 
 
 	hdr.setExposure(interpolate(originalData.exposure, finalData.exposure, dp));
 	hdr.setExposure(interpolate(originalData.exposure, finalData.exposure, dp));
 
 
-	hdr.setBlurringIterationsNum(
+	hdr.setBlurringIterationsCount(
 		interpolate(originalData.blurringIterationsNum,
 		interpolate(originalData.blurringIterationsNum,
 		finalData.blurringIterationsNum, dp));
 		finalData.blurringIterationsNum, dp));
 
 
-	hdr.setBlurringDistance(interpolate(originalData.blurringDist,
-		finalData.blurringDist, dp));
+	/*hdr.setBlurringDistance(interpolate(originalData.blurringDist,
+		finalData.blurringDist, dp));*/
 }
 }
 
 
 } // end namespace
 } // end namespace

+ 14 - 16
src/gl/ShaderProgram.cpp

@@ -127,8 +127,8 @@ void ShaderProgramUniformVariable::set(const Texture* const texes[],
 	const U32 count) const
 	const U32 count) const
 {
 {
 	doCommonSetCode();
 	doCommonSetCode();
-	ANKI_ASSERT(count > 128);
-	ANKI_ASSERT(count <= size);
+	ANKI_ASSERT(count <= getSize());
+	ANKI_ASSERT(count <= 128);
 	Array<GLint, 128> units;
 	Array<GLint, 128> units;
 
 
 	for(U32 i = 0; i < count; i++)
 	for(U32 i = 0; i < count; i++)
@@ -567,10 +567,9 @@ void ShaderProgram::initUniAndAttribVars()
 
 
 	attribs.resize(attribsCount);
 	attribs.resize(attribsCount);
 	attribs.shrink_to_fit();
 	attribs.shrink_to_fit();
+	attribsCount = 0;
 	for(int i = 0; i < num; i++) // loop all attributes
 	for(int i = 0; i < num; i++) // loop all attributes
 	{
 	{
-		ShaderProgramAttributeVariable& var = attribs[i]; bug /// XXX BUG
-
 		// Name
 		// Name
 		glGetActiveAttrib(glId, i, sizeof(name_), &length,
 		glGetActiveAttrib(glId, i, sizeof(name_), &length,
 			&size, &type, &name_[0]);
 			&size, &type, &name_[0]);
@@ -585,6 +584,8 @@ void ShaderProgram::initUniAndAttribVars()
 			continue;
 			continue;
 		}
 		}
 
 
+		ShaderProgramAttributeVariable& var = attribs[attribsCount++];
+
 		var.loc = loc;
 		var.loc = loc;
 		var.name = &name_[0];
 		var.name = &name_[0];
 		var.glDataType = type;
 		var.glDataType = type;
@@ -599,7 +600,7 @@ void ShaderProgram::initUniAndAttribVars()
 	//
 	//
 	glGetProgramiv(glId, GL_ACTIVE_UNIFORMS, &num);
 	glGetProgramiv(glId, GL_ACTIVE_UNIFORMS, &num);
 	U unisCount = num;
 	U unisCount = num;
-	
+
 	// Count the _useful_ uniforms
 	// Count the _useful_ uniforms
 	for(GLint i = 0; i < num; i++)
 	for(GLint i = 0; i < num; i++)
 	{
 	{
@@ -609,21 +610,17 @@ void ShaderProgram::initUniAndAttribVars()
 
 
 		// See bellow for info
 		// See bellow for info
 		if(strchr(&name_[0], '[') != nullptr 
 		if(strchr(&name_[0], '[') != nullptr 
-			&& strstr(&name_[0], "[0]") != nullptr)
+			&& strstr(&name_[0], "[0]") == nullptr)
 		{
 		{
-			ANKI_ASSERT(size > 1);
-			continue;
+			--unisCount;
 		}
 		}
-
-		--unisCount;
 	}
 	}
 
 
 	unis.resize(unisCount);
 	unis.resize(unisCount);
 	unis.shrink_to_fit();
 	unis.shrink_to_fit();
+	unisCount = 0;
 	for(GLint i = 0; i < num; i++) // loop all uniforms
 	for(GLint i = 0; i < num; i++) // loop all uniforms
 	{
 	{
-		ShaderProgramUniformVariable& var = unis[i]; bug/// XXX BUG
-
 		glGetActiveUniform(glId, i, sizeof(name_), &length,
 		glGetActiveUniform(glId, i, sizeof(name_), &length,
 			&size, &type, &name_[0]);
 			&size, &type, &name_[0]);
 		name_[length] = '\0';
 		name_[length] = '\0';
@@ -631,18 +628,19 @@ void ShaderProgram::initUniAndAttribVars()
 		// In case of uniform arrays some implementations (nVidia) on 
 		// In case of uniform arrays some implementations (nVidia) on 
 		// GL_ACTIVE_UNIFORMS they return the number of uniforms that are inside 
 		// GL_ACTIVE_UNIFORMS they return the number of uniforms that are inside 
 		// that uniform array in addition to the first element (it will count 
 		// that uniform array in addition to the first element (it will count 
-		// for example the floats[1]). Some other implementations don't (Mali 
+		// for example the float_arr[9]). But other implementations don't (Mali
 		// T6xx). Also in some cases with big arrays (IS shader) this will 
 		// T6xx). Also in some cases with big arrays (IS shader) this will 
 		// overpopulate the uniforms vector and hash map. So, to solve this if 
 		// overpopulate the uniforms vector and hash map. So, to solve this if 
 		// the uniform name has something like this "[N]" where N != 0 then 
 		// the uniform name has something like this "[N]" where N != 0 then 
-		// ignore the uniform
+		// ignore the uniform and put it as array
 		if(strchr(&name_[0], '[') != nullptr 
 		if(strchr(&name_[0], '[') != nullptr 
-			&& strstr(&name_[0], "[0]") != nullptr)
+			&& strstr(&name_[0], "[0]") == nullptr)
 		{
 		{
-			ANKI_ASSERT(size > 1);
 			continue;
 			continue;
 		}
 		}
 
 
+		ShaderProgramUniformVariable& var = unis[unisCount++];
+
 		// -1 means in uniform block
 		// -1 means in uniform block
 		GLint loc = glGetUniformLocation(glId, &name_[0]);
 		GLint loc = glGetUniformLocation(glId, &name_[0]);
 
 

+ 25 - 1
src/gl/Texture.cpp

@@ -241,7 +241,31 @@ void Texture::create(const Initializer& init)
 //==============================================================================
 //==============================================================================
 U Texture::bind() const
 U Texture::bind() const
 {
 {
-	return TextureUnitsSingleton::get().bindTexture(*this);
+	U unit = TextureUnitsSingleton::get().bindTexture(*this);
+#if ANKI_DEBUG
+	GLint activeUnit;
+	glGetIntegerv(GL_ACTIVE_TEXTURE, &activeUnit);
+
+	GLint bindingPoint;
+	switch(target)
+	{
+	case GL_TEXTURE_2D:
+		bindingPoint = GL_TEXTURE_BINDING_2D;
+		break;
+	default:
+		ANKI_ASSERT(0 && "Unimplemented");
+		break;
+	}
+
+	GLint texName;
+	glActiveTexture(GL_TEXTURE0 + unit);
+	glGetIntegerv(bindingPoint, &texName);
+
+	ANKI_ASSERT(glId == (GLuint)texName);
+
+	glActiveTexture(activeUnit);
+#endif
+	return unit;
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 6 - 0
src/renderer/Bl.cpp

@@ -7,6 +7,7 @@ namespace anki {
 //==============================================================================
 //==============================================================================
 void Bl::init(const Renderer::Initializer& initializer)
 void Bl::init(const Renderer::Initializer& initializer)
 {
 {
+#if 0
 	enabled = initializer.pps.bl.enabled;
 	enabled = initializer.pps.bl.enabled;
 	blurringIterationsNum = initializer.pps.bl.blurringIterationsNum;
 	blurringIterationsNum = initializer.pps.bl.blurringIterationsNum;
 	sideBlurFactor = initializer.pps.bl.sideBlurFactor;
 	sideBlurFactor = initializer.pps.bl.sideBlurFactor;
@@ -66,11 +67,13 @@ void Bl::init(const Renderer::Initializer& initializer)
 
 
 	sideBlurMap.load("engine-rsrc/side-blur.png");
 	sideBlurMap.load("engine-rsrc/side-blur.png");
 	sideBlurSProg.load("shaders/PpsSideBlur.glsl");
 	sideBlurSProg.load("shaders/PpsSideBlur.glsl");
+#endif
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 void Bl::runSideBlur()
 void Bl::runSideBlur()
 {
 {
+#if 0
 	if(sideBlurFactor == 0.0)
 	if(sideBlurFactor == 0.0)
 	{
 	{
 		return;
 		return;
@@ -87,11 +90,13 @@ void Bl::runSideBlur()
 	sideBlurSProg->findUniformVariable("factor").set(sideBlurFactor);
 	sideBlurSProg->findUniformVariable("factor").set(sideBlurFactor);
 
 
 	r->drawQuad();
 	r->drawQuad();
+#endif
 }
 }
 
 
 //==============================================================================
 //==============================================================================
 void Bl::runBlur()
 void Bl::runBlur()
 {
 {
+#if 0
 	GlStateSingleton::get().disable(GL_BLEND);
 	GlStateSingleton::get().disable(GL_BLEND);
 
 
 	// Setup programs here. Reverse order
 	// Setup programs here. Reverse order
@@ -122,6 +127,7 @@ void Bl::runBlur()
 		vBlurSProg->bind();
 		vBlurSProg->bind();
 		r->drawQuad();
 		r->drawQuad();
 	}
 	}
+#endif
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 2 - 0
src/renderer/Bs.cpp

@@ -11,6 +11,7 @@ Bs::~Bs()
 //==============================================================================
 //==============================================================================
 void Bs::createFbo()
 void Bs::createFbo()
 {
 {
+#if 0
 	try
 	try
 	{
 	{
 		fbo.create();
 		fbo.create();
@@ -23,6 +24,7 @@ void Bs::createFbo()
 	{
 	{
 		throw ANKI_EXCEPTION("Failed to create blending stage FBO") << e;
 		throw ANKI_EXCEPTION("Failed to create blending stage FBO") << e;
 	}
 	}
+#endif
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 63 - 31
src/renderer/Hdr.cpp

@@ -11,23 +11,19 @@ Hdr::~Hdr()
 //==============================================================================
 //==============================================================================
 void Hdr::initFbo(Fbo& fbo, Texture& fai)
 void Hdr::initFbo(Fbo& fbo, Texture& fai)
 {
 {
-	try
-	{
-		Renderer::createFai(width, height, GL_RGB8, GL_RGB, GL_FLOAT, fai);
+	Renderer::createFai(width, height, GL_RGB8, GL_RGB, GL_FLOAT, fai);
 
 
-		// create FBO
-		fbo.create();
-		fbo.setColorAttachments({&fai});
-	}
-	catch(std::exception& e)
+	// create FBO
+	fbo.create();
+	fbo.setColorAttachments({&fai});
+	if(!fbo.isComplete())
 	{
 	{
-		throw ANKI_EXCEPTION("Cannot create deferred shading "
-			"post-processing stage HDR passes FBO") << e;
+		throw ANKI_EXCEPTION("Fbo not complete");
 	}
 	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Hdr::init(const Renderer::Initializer& initializer)
+void Hdr::initInternal(const Renderer::Initializer& initializer)
 {
 {
 	enabled = initializer.pps.hdr.enabled;
 	enabled = initializer.pps.hdr.enabled;
 
 
@@ -40,6 +36,9 @@ void Hdr::init(const Renderer::Initializer& initializer)
 
 
 	width = renderingQuality * r->getWidth();
 	width = renderingQuality * r->getWidth();
 	height = renderingQuality * r->getHeight();
 	height = renderingQuality * r->getHeight();
+	exposure = initializer.pps.hdr.exposure;
+	blurringDist = initializer.pps.hdr.blurringDist;
+	blurringIterationsCount = initializer.pps.hdr.blurringIterationsCount;
 
 
 	initFbo(toneFbo, toneFai);
 	initFbo(toneFbo, toneFai);
 	initFbo(hblurFbo, hblurFai);
 	initFbo(hblurFbo, hblurFai);
@@ -48,22 +47,48 @@ void Hdr::init(const Renderer::Initializer& initializer)
 	fai.setFiltering(Texture::TFT_LINEAR);
 	fai.setFiltering(Texture::TFT_LINEAR);
 
 
 	// init shaders
 	// init shaders
+	Vec4 block(exposure, 0.0, 0.0, 0.0);
+	commonUbo.create(sizeof(Vec4), &block);
+
 	toneSProg.load("shaders/PpsHdr.glsl");
 	toneSProg.load("shaders/PpsHdr.glsl");
 
 
 	const char* SHADER_FILENAME = "shaders/GaussianBlurGeneric.glsl";
 	const char* SHADER_FILENAME = "shaders/GaussianBlurGeneric.glsl";
 
 
-	std::string pps = "#define HPASS\n#define COL_RGB\n#define IMG_DIMENSION "
-		+ std::to_string(width) + ".0\n";
-	hblurSProg.load(SHADER_FILENAME, pps.c_str());
-
-	pps = "#define VPASS\n#define COL_RGB\n#define IMG_DIMENSION "
-		+ std::to_string(height) + ".0\n";
-	vblurSProg.load(SHADER_FILENAME, pps.c_str());
+	F32 blurringDistRealX = F32(blurringDist / width);
+	F32 blurringDistRealY = F32(blurringDist / height);
+
+	std::string pps =
+		"#define HPASS\n"
+		"#define COL_RGB\n"
+		"#define BLURRING_DIST " + std::to_string(blurringDistRealX) + "\n"
+		"#define IMG_DIMENSION " + std::to_string(width) + ".0\n";
+	hblurSProg.load(ShaderProgramResource::createSrcCodeToCache(
+		SHADER_FILENAME, pps.c_str()).c_str());
+
+	pps =
+		"#define VPASS\n"
+		"#define COL_RGB\n"
+		"#define BLURRING_DIST " + std::to_string(blurringDistRealY) + "\n"
+		"#define IMG_DIMENSION " + std::to_string(height) + ".0\n";
+	vblurSProg.load(ShaderProgramResource::createSrcCodeToCache(
+		SHADER_FILENAME, pps.c_str()).c_str());
+
+	// Set timestamps
+	parameterUpdateTimestamp = Timestamp::getTimestamp();
+	commonUboUpdateTimestamp = Timestamp::getTimestamp();
+}
 
 
-	// Set the uniforms
-	setBlurringDistance(initializer.pps.hdr.blurringDist);
-	blurringIterationsNum = initializer.pps.hdr.blurringIterationsNum;
-	setExposure(initializer.pps.hdr.exposure);
+//==============================================================================
+void Hdr::init(const RendererInitializer& initializer)
+{
+	try
+	{
+		initInternal(initializer);
+	}
+	catch(const std::exception& e)
+	{
+		throw ANKI_EXCEPTION("Failed to init PPS HDR") << e;
+	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -81,31 +106,38 @@ void Hdr::run()
 
 
 	// pass 0
 	// pass 0
 	toneFbo.bind();
 	toneFbo.bind();
-	toneSProg.bind();
-	toneSProg.findUniformVariable("fai").set(
-		r->getPps().getPrePassFai());
+	toneSProg->bind();
+
+	if(parameterUpdateTimestamp > commonUboUpdateTimestamp)
+	{
+		Vec4 block(exposure, 0.0, 0.0, 0.0);
+		commonUbo.write(&block);
+		commonUboUpdateTimestamp = Timestamp::getTimestamp();
+	}
+	commonUbo.setBinding(0);
+	toneSProg->findUniformVariable("fai").set(r->getIs().getFai());
 	r->drawQuad();
 	r->drawQuad();
 
 
 	// blurring passes
 	// blurring passes
-	for(uint32_t i = 0; i < blurringIterationsNum; i++)
+	for(U32 i = 0; i < blurringIterationsCount; i++)
 	{
 	{
 		// hpass
 		// hpass
 		hblurFbo.bind();
 		hblurFbo.bind();
-		hblurSProg.bind();
+		hblurSProg->bind();
 		if(i == 0)
 		if(i == 0)
 		{
 		{
-			hblurSProg.findUniformVariable("img").set(toneFai);
+			hblurSProg->findUniformVariable("img").set(toneFai);
 		}
 		}
 		else if(i == 1)
 		else if(i == 1)
 		{
 		{
-			hblurSProg.findUniformVariable("img").set(fai);
+			hblurSProg->findUniformVariable("img").set(fai);
 		}
 		}
 		r->drawQuad();
 		r->drawQuad();
 
 
 		// vpass
 		// vpass
 		vblurFbo.bind();
 		vblurFbo.bind();
-		vblurSProg.bind();
-		vblurSProg.findUniformVariable("img").set(hblurFai);
+		vblurSProg->bind();
+		vblurSProg->findUniformVariable("img").set(hblurFai);
 		r->drawQuad();
 		r->drawQuad();
 	}
 	}
 }
 }

+ 30 - 8
src/renderer/Is.cpp

@@ -14,7 +14,7 @@ namespace anki {
 struct ShaderLight
 struct ShaderLight
 {
 {
 	Vec4 posAndRadius; ///< xyz: Light pos in eye space. w: The radius
 	Vec4 posAndRadius; ///< xyz: Light pos in eye space. w: The radius
-	Vec4 diffuseColor;
+	Vec4 diffuseColorShadowmapId;
 	Vec4 specularColor;
 	Vec4 specularColor;
 };
 };
 
 
@@ -23,7 +23,8 @@ struct ShaderPointLight: ShaderLight
 
 
 struct ShaderSpotLight: ShaderLight
 struct ShaderSpotLight: ShaderLight
 {
 {
-	Vec4 lightDirection;
+	Vec4 lightDirection; ///< xyz: Dir vector
+	Vec4 outerCosInnerCos; ///< x: outer angle cos, y: inner
 	Mat4 texProjectionMat;
 	Mat4 texProjectionMat;
 };
 };
 
 
@@ -88,7 +89,7 @@ struct WritePointLightsUbo: ThreadJob
 				cam->getViewMatrix());
 				cam->getViewMatrix());
 
 
 			pl.posAndRadius = Vec4(pos, light.getRadius());
 			pl.posAndRadius = Vec4(pos, light.getRadius());
-			pl.diffuseColor = light.getDiffuseColor();
+			pl.diffuseColorShadowmapId = light.getDiffuseColor();
 			pl.specularColor = light.getSpecularColor();
 			pl.specularColor = light.getSpecularColor();
 		}
 		}
 	}
 	}
@@ -122,16 +123,18 @@ struct WriteSpotLightsUbo: ThreadJob
 
 
 			slight.posAndRadius = Vec4(pos, light.getDistance());
 			slight.posAndRadius = Vec4(pos, light.getDistance());
 
 
-			slight.diffuseColor = Vec4(light.getDiffuseColor().xyz(),
-				light.getOuterAngleCos());
+			slight.diffuseColorShadowmapId = Vec4(light.getDiffuseColor().xyz(),
+				0);
 
 
-			slight.specularColor = Vec4(light.getSpecularColor().xyz(),
-				light.getInnerAngleCos());
+			slight.specularColor = light.getSpecularColor();
 
 
 			Vec3 lightDir = -light.getWorldTransform().getRotation().getZAxis();
 			Vec3 lightDir = -light.getWorldTransform().getRotation().getZAxis();
 			lightDir = cam->getViewMatrix().getRotationPart() * lightDir;
 			lightDir = cam->getViewMatrix().getRotationPart() * lightDir;
 			slight.lightDirection = Vec4(lightDir, 0.0);
 			slight.lightDirection = Vec4(lightDir, 0.0);
 			
 			
+			slight.outerCosInnerCos = Vec4(light.getOuterAngleCos(),
+				light.getInnerAngleCos(), 1.0, 1.0);
+
 			static const Mat4 biasMat4(
 			static const Mat4 biasMat4(
 				0.5, 0.0, 0.0, 0.5, 
 				0.5, 0.0, 0.0, 0.5, 
 				0.0, 0.5, 0.0, 0.5, 
 				0.0, 0.5, 0.0, 0.5, 
@@ -716,6 +719,24 @@ void Is::lightPass()
 
 
 	// Done
 	// Done
 	threadPool.waitForAllJobsToFinish();
 	threadPool.waitForAllJobsToFinish();
+
+	// Set shadow IDs
+	U32 i = 0;
+	ShaderSpotLight* shaderSpotLight = shaderSpotLights + spotsNoShadowCount;
+	for(; shaderSpotLight != shaderSpotLights + visibleSpotLightsCount;
+		++shaderSpotLight)
+	{
+		union
+		{
+			F32 f;
+			U32 i;
+		} variant;
+
+		variant.i = i;
+		shaderSpotLight->diffuseColorShadowmapId.w() = variant.f;
+		++i;
+	}
+
 	spotLightsUbo.unmap();
 	spotLightsUbo.unmap();
 
 
 	//
 	//
@@ -763,7 +784,8 @@ void Is::lightPass()
 		char str[128];
 		char str[128];
 		sprintf(str, "shadowMaps[%u]", (unsigned int)i);
 		sprintf(str, "shadowMaps[%u]", (unsigned int)i);
 
 
-		lightPassProg->findUniformVariable(str).set(*shadowmaps[i]);
+		//lightPassProg->findUniformVariable(str).set(*shadowmaps[i]);
+		glUniform1i(glGetUniformLocation(lightPassProg->getGlId(), str), shadowmaps[i]->bind());
 	}
 	}
 #endif
 #endif
 
 

+ 5 - 1
src/renderer/MainRenderer.cpp

@@ -95,7 +95,11 @@ void MainRenderer::render(Scene& scene)
 	GlStateSingleton::get().disable(GL_DEPTH_TEST);
 	GlStateSingleton::get().disable(GL_DEPTH_TEST);
 	GlStateSingleton::get().disable(GL_BLEND);
 	GlStateSingleton::get().disable(GL_BLEND);
 	sProg->bind();
 	sProg->bind();
-	const Texture& finalFai = is.getFai();//ms.getFai0();
+#if 0
+	const Texture& finalFai = pps.getHdr().getFai();
+#else
+	const Texture& finalFai = pps.getFai();
+#endif
 	sProg->findUniformVariable("rasterImage").set(finalFai);
 	sProg->findUniformVariable("rasterImage").set(finalFai);
 	drawQuad();
 	drawQuad();
 }
 }

+ 31 - 75
src/renderer/Pps.cpp

@@ -15,28 +15,20 @@ Pps::~Pps()
 {}
 {}
 
 
 //==============================================================================
 //==============================================================================
-void Pps::init(const Renderer::Initializer& initializer)
+void Pps::initInternal(const RendererInitializer& initializer)
 {
 {
 	ssao.init(initializer);
 	ssao.init(initializer);
 	hdr.init(initializer);
 	hdr.init(initializer);
 
 
-	// Init pre pass
-	//
-
 	// FBO
 	// FBO
-	try
-	{
-		Renderer::createFai(r->getWidth(), r->getHeight(), GL_RGB, GL_RGB,
-			GL_FLOAT, prePassFai);
+	Renderer::createFai(r->getWidth(), r->getHeight(), GL_RGB, GL_RGB,
+		GL_FLOAT, fai);
 
 
-		prePassFbo.create();
-		prePassFbo.setColorAttachments({&prePassFai});
-		ANKI_ASSERT(prePassFbo.isComplete());
-	}
-	catch(std::exception& e)
+	fbo.create();
+	fbo.setColorAttachments({&fai});
+	if(!fbo.isComplete())
 	{
 	{
-		throw ANKI_EXCEPTION("Cannot create pre-pass "
-			"post-processing stage FBO") << e;
+		throw ANKI_EXCEPTION("Fbo not complete");
 	}
 	}
 
 
 	// SProg
 	// SProg
@@ -46,97 +38,61 @@ void Pps::init(const Renderer::Initializer& initializer)
 		pps += "#define SSAO_ENABLED\n";
 		pps += "#define SSAO_ENABLED\n";
 	}
 	}
 
 
-	prePassSProg.load("shaders/PpsPrePass.glsl", pps.c_str());
-
-	// Init post pass
-	//
-
-	// FBO
-	try
-	{
-		Renderer::createFai(r->getWidth(), r->getHeight(), GL_RGB, GL_RGB,
-			GL_FLOAT, postPassFai);
-
-		postPassFbo.create();
-		postPassFbo.setColorAttachments({&postPassFai});
-		ANKI_ASSERT(postPassFbo.isComplete());
-	}
-	catch(std::exception& e)
-	{
-		throw ANKI_EXCEPTION("Cannot create post-pass "
-			"post-processing stage FBO") << e;
-	}
-
-	// SProg
-	pps = "";
 	if(hdr.getEnabled())
 	if(hdr.getEnabled())
 	{
 	{
 		pps += "#define HDR_ENABLED\n";
 		pps += "#define HDR_ENABLED\n";
 	}
 	}
 
 
-	postPassSProg.load("shaders/PpsPostPass.glsl", pps.c_str());
-
-	// Init Bl after
-	//
-	bl.init(initializer);
+	prog.load(ShaderProgramResource::createSrcCodeToCache(
+		"shaders/Pps.glsl", pps.c_str()).c_str());
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Pps::runPrePass()
+void Pps::init(const Renderer::Initializer& initializer)
 {
 {
-	if(ssao.getEnabled())
+	try
 	{
 	{
-		ssao.run();
+		initInternal(initializer);
 	}
 	}
-
-	prePassFbo.bind();
-
-	GlStateSingleton::get().enable(GL_DEPTH_TEST, false);
-	GlStateSingleton::get().enable(GL_BLEND, false);
-	GlStateSingleton::get().setViewport(0, 0,
-		r->getWidth(), r->getHeight());
-
-	prePassSProg.bind();
-	prePassSProg.findUniformVariable("isFai").set(r->getIs().getFai());
-
-	if(ssao.getEnabled())
+	catch(const std::exception& e)
 	{
 	{
-		prePassSProg.findUniformVariable("ppsSsaoFai").set(
-			ssao.getFai());
+		throw ANKI_EXCEPTION("Failed to init PPS") << e;
 	}
 	}
-
-	r->drawQuad();
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Pps::runPostPass()
+void Pps::run()
 {
 {
-	// The actual pass
-	//
+	if(ssao.getEnabled())
+	{
+		ssao.run();
+	}
+
 	if(hdr.getEnabled())
 	if(hdr.getEnabled())
 	{
 	{
 		hdr.run();
 		hdr.run();
 	}
 	}
 
 
-	postPassFbo.bind();
+	fbo.bind();
 
 
 	GlStateSingleton::get().enable(GL_DEPTH_TEST, false);
 	GlStateSingleton::get().enable(GL_DEPTH_TEST, false);
 	GlStateSingleton::get().enable(GL_BLEND, false);
 	GlStateSingleton::get().enable(GL_BLEND, false);
-	GlStateSingleton::get().setViewport(0, 0, r->getWidth(), r->getHeight());
+	GlStateSingleton::get().setViewport(0, 0,
+		r->getWidth(), r->getHeight());
 
 
-	postPassSProg.bind();
-	postPassSProg.findUniformVariable("ppsPrePassFai").set(prePassFai);
+	prog->bind();
+	prog->findUniformVariable("isFai").set(r->getIs().getFai());
 
 
+	if(ssao.getEnabled())
+	{
+		prog->findUniformVariable("ppsSsaoFai").set(ssao.getFai());
+	}
 	if(hdr.getEnabled())
 	if(hdr.getEnabled())
 	{
 	{
-		postPassSProg.findUniformVariable("ppsHdrFai").set(hdr.getFai());
+		prog->findUniformVariable("ppsHdrFai").set(hdr.getFai());
 	}
 	}
 
 
 	r->drawQuad();
 	r->drawQuad();
-
-	// Blurring
-	//
-	bl.run();
 }
 }
 
 
-} // end namespace
+} // end namespace anki

+ 2 - 2
src/renderer/Renderer.cpp

@@ -81,8 +81,8 @@ void Renderer::render(Scene& scene_)
 
 
 	ms.run();
 	ms.run();
 	is.run();
 	is.run();
-	/*pps.runPrePass();
-	bs.run();
+	pps.run();
+	/*bs.run();
 	pps.runPostPass();*/
 	pps.runPostPass();*/
 
 
 	++framesNum;
 	++framesNum;

+ 86 - 55
src/renderer/Ssao.cpp

@@ -6,25 +6,30 @@
 
 
 namespace anki {
 namespace anki {
 
 
+//==============================================================================
+struct ShaderCommonUniforms
+{
+	Vec4 nearPlanes;
+	Vec4 limitsOfNearPlane;
+};
+
 //==============================================================================
 //==============================================================================
 void Ssao::createFbo(Fbo& fbo, Texture& fai)
 void Ssao::createFbo(Fbo& fbo, Texture& fai)
 {
 {
-	try
-	{
-		Renderer::createFai(width, height, GL_RED, GL_RED, GL_FLOAT, fai);
 
 
-		fbo.create();
-		fbo.setColorAttachments({&fai});
-	}
-	catch(std::exception& e)
+	Renderer::createFai(width, height, GL_RED, GL_RED, GL_FLOAT, fai);
+
+	fbo.create();
+	fbo.setColorAttachments({&fai});
+
+	if(!fbo.isComplete())
 	{
 	{
-		throw ANKI_EXCEPTION("Cannot create deferred shading post-processing "
-			"stage SSAO blur FBO") << e;
+		throw ANKI_EXCEPTION("Fbo not complete");
 	}
 	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
-void Ssao::init(const RendererInitializer& initializer)
+void Ssao::initInternal(const RendererInitializer& initializer)
 {
 {
 	enabled = initializer.pps.ssao.enabled;
 	enabled = initializer.pps.ssao.enabled;
 
 
@@ -34,36 +39,69 @@ void Ssao::init(const RendererInitializer& initializer)
 	}
 	}
 
 
 	renderingQuality = initializer.pps.ssao.renderingQuality;
 	renderingQuality = initializer.pps.ssao.renderingQuality;
-	blurringIterationsNum = initializer.pps.ssao.blurringIterationsNum;
+	blurringIterationsCount = initializer.pps.ssao.blurringIterationsNum;
 
 
 	width = renderingQuality * r->getWidth();
 	width = renderingQuality * r->getWidth();
 	height = renderingQuality * r->getHeight();
 	height = renderingQuality * r->getHeight();
 
 
+	//
 	// create FBOs
 	// create FBOs
+	//
 	createFbo(ssaoFbo, ssaoFai);
 	createFbo(ssaoFbo, ssaoFai);
 	createFbo(hblurFbo, hblurFai);
 	createFbo(hblurFbo, hblurFai);
 	createFbo(vblurFbo, fai);
 	createFbo(vblurFbo, fai);
 
 
+	//
+	// noise map
+	//
+	noiseMap.load("engine-rsrc/noise.png");
+	noiseMap->setFiltering(Texture::TFT_NEAREST);
+	if(noiseMap->getWidth() != noiseMap->getHeight())
+	{
+		throw ANKI_EXCEPTION("Incorrect noisemap size");
+	}
+
+	//
 	// Shaders
 	// Shaders
 	//
 	//
+	commonUbo.create(sizeof(ShaderCommonUniforms), nullptr);
+
+	std::string pps;
 
 
 	// first pass prog
 	// first pass prog
-	ssaoSProg.load("shaders/PpsSsao.glsl");
+	pps = "#define NOISE_MAP_SIZE " + std::to_string(noiseMap->getWidth())
+		+ "\n#define WIDTH " + std::to_string(width)
+		+ "\n#define HEIGHT " + std::to_string(height) + "\n";
+	ssaoSProg.load(ShaderProgramResource::createSrcCodeToCache(
+		"shaders/PpsSsao.glsl", pps.c_str()).c_str());
 
 
 	// blurring progs
 	// blurring progs
 	const char* SHADER_FILENAME = "shaders/GaussianBlurGeneric.glsl";
 	const char* SHADER_FILENAME = "shaders/GaussianBlurGeneric.glsl";
 
 
-	std::string pps = "#define HPASS\n#define COL_R\n#define IMG_DIMENSION "
-		+ std::to_string(width) + ".0\n";
-	hblurSProg.load(SHADER_FILENAME, pps.c_str());
-
-	pps = "#define VPASS\n#define COL_R\n#define IMG_DIMENSION "
-		+ std::to_string(width) + ".0 \n";
-	vblurSProg.load(SHADER_FILENAME, pps.c_str());
+	pps = "#define HPASS\n"
+		"#define COL_R\n"
+		"#define IMG_DIMENSION " + std::to_string(width) + ".0\n";
+	hblurSProg.load(ShaderProgramResource::createSrcCodeToCache(
+		SHADER_FILENAME, pps.c_str()).c_str());
+
+	pps = "#define VPASS\n"
+		"#define COL_R\n"
+		"#define IMG_DIMENSION " + std::to_string(width) + ".0 \n";
+	vblurSProg.load(ShaderProgramResource::createSrcCodeToCache(
+		SHADER_FILENAME, pps.c_str()).c_str());
+}
 
 
-	// noise map
-	//
-	noiseMap.load("engine-rsrc/noise.png");
+//==============================================================================
+void Ssao::init(const RendererInitializer& initializer)
+{
+	try
+	{
+		initInternal(initializer);
+	}
+	catch(const std::exception& e)
+	{
+		throw ANKI_EXCEPTION("Failed to init PPS SSAO") << e;
+	}
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -84,68 +122,61 @@ void Ssao::run()
 	//
 	//
 	
 	
 	ssaoFbo.bind();
 	ssaoFbo.bind();
-	ssaoSProg.bind();
-	
-	// planes
-	ssaoSProg.findUniformVariable("planes").set(r->getPlanes());
-
-	// limitsOfNearPlane
-	ssaoSProg.findUniformVariable("limitsOfNearPlane").set(
-		r->getLimitsOfNearPlane());
+	ssaoSProg->bind();
+	commonUbo.setBinding(0);
 
 
-	// limitsOfNearPlane2
-	ssaoSProg.findUniformVariable("limitsOfNearPlane2").set(
-		r->getLimitsOfNearPlane2());
-
-	// zNear
-	ssaoSProg.findUniformVariable("zNear").set(cam.getNear());
+	// Write common block
+	if(commonUboUpdateTimestamp < r->getPlanesUpdateTimestamp()
+		|| commonUboUpdateTimestamp == 1)
+	{
+		ShaderCommonUniforms blk;
+		blk.nearPlanes = Vec4(cam.getNear(), 0.0, r->getPlanes().x(),
+			r->getPlanes().y());
+		blk.limitsOfNearPlane = Vec4(r->getLimitsOfNearPlane(),
+			r->getLimitsOfNearPlane2());
+
+		commonUbo.write(&blk);
+		commonUboUpdateTimestamp = Timestamp::getTimestamp();
+	}
 
 
 	// msDepthFai
 	// msDepthFai
-	ssaoSProg.findUniformVariable("msDepthFai").set(
+	ssaoSProg->findUniformVariable("msDepthFai").set(
 		r->getMs().getDepthFai());
 		r->getMs().getDepthFai());
 
 
 	// noiseMap
 	// noiseMap
-	ssaoSProg.findUniformVariable("noiseMap").set(*noiseMap);
-
-	// noiseMapSize
-	ssaoSProg.findUniformVariable("noiseMapSize").set(
-		noiseMap->getWidth());
-
-	// screenSize
-	Vec2 screenSize(width * 2, height * 2);
-	ssaoSProg.findUniformVariable("screenSize").set(screenSize);
+	ssaoSProg->findUniformVariable("noiseMap").set(*noiseMap);
 
 
 	// msNormalFai
 	// msNormalFai
-	ssaoSProg.findUniformVariable("msNormalFai").set(
+	ssaoSProg->findUniformVariable("msGFai").set(
 		r->getMs().getFai0());
 		r->getMs().getFai0());
 
 
 	r->drawQuad();
 	r->drawQuad();
 
 
-	vblurSProg.bind();
-	vblurSProg.findUniformVariable("img").set(hblurFai);
+	vblurSProg->bind();
+	vblurSProg->findUniformVariable("img").set(hblurFai);
 
 
 	// Blurring passes
 	// Blurring passes
 	//
 	//
-	for(uint32_t i = 0; i < blurringIterationsNum; i++)
+	for(U32 i = 0; i < blurringIterationsCount; i++)
 	{
 	{
 		// hpass
 		// hpass
 		hblurFbo.bind();
 		hblurFbo.bind();
-		hblurSProg.bind();
+		hblurSProg->bind();
 		if(i == 0)
 		if(i == 0)
 		{
 		{
-			hblurSProg.findUniformVariable("img").set(ssaoFai);
+			hblurSProg->findUniformVariable("img").set(ssaoFai);
 		}
 		}
 		else if(i == 1)
 		else if(i == 1)
 		{
 		{
-			hblurSProg.findUniformVariable("img").set(fai);
+			hblurSProg->findUniformVariable("img").set(fai);
 		}
 		}
 		r->drawQuad();
 		r->drawQuad();
 
 
 		// vpass
 		// vpass
 		vblurFbo.bind();
 		vblurFbo.bind();
-		vblurSProg.bind();
+		vblurSProg->bind();
 		r->drawQuad();
 		r->drawQuad();
 	}
 	}
 }
 }
 
 
-} // end namespace
+} // end namespace anki

+ 1 - 1
src/scene/Scene.cpp

@@ -8,7 +8,7 @@ namespace anki {
 //==============================================================================
 //==============================================================================
 Scene::Scene()
 Scene::Scene()
 {
 {
-	ambientCol = Vec3(0.1, 0.05, 0.05) * 4;
+	ambientCol = Vec3(0.1, 0.05, 0.05) * 2;
 }
 }
 
 
 //==============================================================================
 //==============================================================================

+ 4 - 5
testapp/Main.cpp

@@ -229,8 +229,7 @@ void mainLoopExtra()
 
 
 	if(in.getKey(KC_P) == 1)
 	if(in.getKey(KC_P) == 1)
 	{
 	{
-		/*SceneSingleton::get().getActiveCamera().
-			getFrustumable()->getFrustum().setFar(250.0);*/
+		MainRendererSingleton::get().getPps().getHdr().setExposure(20);
 	}
 	}
 
 
 	if(in.getKey(KC_UP)) mover->rotateLocalX(ang);
 	if(in.getKey(KC_UP)) mover->rotateLocalX(ang);
@@ -345,9 +344,9 @@ void initSubsystems(int argc, char* argv[])
 	initializer.is.sm.resolution = 512;
 	initializer.is.sm.resolution = 512;
 	initializer.pps.hdr.enabled = true;
 	initializer.pps.hdr.enabled = true;
 	initializer.pps.hdr.renderingQuality = 0.25;
 	initializer.pps.hdr.renderingQuality = 0.25;
-	initializer.pps.hdr.blurringDist = 1.0;
-	initializer.pps.hdr.blurringIterationsNum = 2;
-	initializer.pps.hdr.exposure = 4.0;
+	initializer.pps.hdr.blurringDist = 0.1;
+	initializer.pps.hdr.blurringIterationsCount = 2;
+	initializer.pps.hdr.exposure = 5.0;
 	initializer.pps.ssao.blurringIterationsNum = 4;
 	initializer.pps.ssao.blurringIterationsNum = 4;
 	initializer.pps.ssao.enabled = true;
 	initializer.pps.ssao.enabled = true;
 	initializer.pps.ssao.renderingQuality = 0.3;
 	initializer.pps.ssao.renderingQuality = 0.3;