Jelajahi Sumber

Enabling SSAO and HDR

Panagiotis Christopoulos Charitos 13 tahun lalu
induk
melakukan
3a617ee343

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

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

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

@@ -106,8 +106,8 @@ private:
 		GLuint tex;
 		
 		/// 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;
 	};
 

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

@@ -6,6 +6,8 @@
 #include "anki/resource/TextureResource.h"
 #include "anki/resource/ShaderProgramResource.h"
 #include "anki/resource/Resource.h"
+#include "anki/core/Timestamp.h"
+#include "anki/gl/Ubo.h"
 
 namespace anki {
 
@@ -26,55 +28,23 @@ public:
 
 	/// @name Accessors
 	/// @{
-	float getExposure() const
+	F32 getExposure() const
 	{
 		return exposure;
 	}
-	void setExposure(const float x)
+	void setExposure(const F32 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
@@ -84,23 +54,27 @@ public:
 	/// @}
 
 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 hblurFbo;
 	Fbo vblurFbo;
-	ShaderProgramResource toneSProg;
-	ShaderProgramResource hblurSProg;
-	ShaderProgramResource vblurSProg;
+	ShaderProgramResourcePointer toneSProg;
+	ShaderProgramResourcePointer hblurSProg;
+	ShaderProgramResourcePointer vblurSProg;
 	Texture toneFai; ///< Vertical blur pass FAI
 	Texture hblurFai; ///< pass0Fai with the horizontal blur FAI
 	Texture fai; ///< The final FAI
+	U32 parameterUpdateTimestamp = Timestamp::getTimestamp();
+	U32 commonUboUpdateTimestamp = Timestamp::getTimestamp();
+	Ubo commonUbo;
 
 	void initFbo(Fbo& fbo, Texture& fai);
+	void initInternal(const RendererInitializer& initializer);
 };
 
 } // end namespace

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

@@ -18,12 +18,11 @@ class ShaderProgram;
 class Pps: private RenderingPass
 {
 public:
-	Pps(Renderer* r_);
+	Pps(Renderer* r);
 	~Pps();
 
 	void init(const RendererInitializer& initializer);
-	void runPrePass();
-	void runPostPass();
+	void run();
 
 	/// @name Accessors
 	/// @{
@@ -50,14 +49,9 @@ public:
 		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;
 	/// @}
 
-	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;
 			F32 renderingQuality = 0.25;
 			F32 blurringDist = 1.0;
-			F32 blurringIterationsNum = 2;
+			F32 blurringIterationsCount = 2;
 			F32 exposure = 4.0;
 		} hdr;
 

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

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

+ 3 - 10
shaders/Final.glsl

@@ -6,24 +6,17 @@
 
 #pragma anki start fragmentShader
 
-#if 0
-uniform usampler2D rasterImage;
-#else
 uniform sampler2D rasterImage;
-#endif
 
 in vec2 vTexCoords;
 layout(location = 0) out vec3 fFragColor;
 
 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;
 	fFragColor = col;
+#else
+	fFragColor = vec3(texture2D(rasterImage, vTexCoords).r);
 #endif
-	//fFragColor = texture2D(rasterImage, vTexCoords).rgb;
 }

+ 8 - 5
shaders/GaussianBlurGeneric.glsl

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

+ 16 - 15
shaders/IsLpGeneric.glsl

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

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

@@ -6,16 +6,14 @@
 
 #pragma anki include "shaders/photoshop_filters.glsl"
 
-uniform sampler2D ppsPrePassFai;
+uniform sampler2D isFai;
 uniform sampler2D ppsHdrFai;
+uniform sampler2D ppsSsaoFai;
 
 in vec2 vTexCoords;
 
-layout(location = 0) out vec3 fFragColor;
+layout(location = 0) out vec3 fColor;
 
-
-//==============================================================================
-// GrayScale                                                                   =
 //==============================================================================
 vec3 grayScale(in vec3 col)
 {
@@ -23,9 +21,6 @@ vec3 grayScale(in vec3 col)
 	return vec3(grey);
 }
 
-
-//==============================================================================
-// saturation                                                                  =
 //==============================================================================
 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);
 }
 
-
-//==============================================================================
-// main                                                                        =
 //==============================================================================
 void main(void)
 {
-	fFragColor = texture2D(ppsPrePassFai, vTexCoords).rgb;
+	fColor = texture2D(isFai, vTexCoords).rgb;
 
 	/*const float gamma = 0.7;
 	color.r = pow(color.r, 1.0 / gamma);
@@ -50,9 +42,14 @@ void main(void)
 
 #if defined(HDR_ENABLED)
 	vec3 hdr = texture2D(ppsHdrFai, vTexCoords).rgb;
-	fFragColor += hdr;
+	fColor += hdr;
+#endif
+
+#if defined(SSAO_ENABLED)
+	float ssao = texture2D(ppsSsaoFai, vTexCoords).r;
+	fColor *= ssao;
 #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
 
 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;
 

+ 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"
 
-/// @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
 /// @{
 in vec2 vTexCoords;
@@ -31,31 +16,51 @@ in vec2 vTexCoords;
 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)
 {
-	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)
 {
-	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)
 {
 	float depth = texture2D(msDepthFai, uv).r;
@@ -63,18 +68,15 @@ vec3 getPosition(in vec2 uv)
 	vec3 fragPosVspace;
 	fragPosVspace.z = -planes.y / (planes.x + depth);
 	
-	// Old: fragPosVspace.xy = (uv * 2.0 - 1.0) * limitsOfNearPlane;
 	fragPosVspace.xy = (uv * limitsOfNearPlane2) - limitsOfNearPlane;
 	
-	float sc = -fragPosVspace.z / zNear;
+	const float sc = -fragPosVspace.z / zNear;
 	fragPosVspace.xy *= sc;
 
 	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 diff = newp - original;
@@ -85,20 +87,19 @@ float doAmbientOcclusion(in vec2 uv, in vec3 original, in vec3 cnorm)
 	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)
 {
-	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 n = getNormal(vTexCoords);
 	vec2 rand = getRandom(vTexCoords);
@@ -109,11 +110,9 @@ void main(void)
 	for(int j = 0; j < KERNEL_SIZE; ++j)
 	{
 		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 = fColor - fColor + rand.x;
 }
 

+ 5 - 5
src/event/MainRendererPpsHdrEvent.cpp

@@ -18,8 +18,8 @@ MainRendererPpsHdrEvent::MainRendererPpsHdrEvent(float startTime,
 	const Hdr& hdr =
 		MainRendererSingleton::get().getPps().getHdr();
 	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.setBlurringIterationsNum(
+	hdr.setBlurringIterationsCount(
 		interpolate(originalData.blurringIterationsNum,
 		finalData.blurringIterationsNum, dp));
 
-	hdr.setBlurringDistance(interpolate(originalData.blurringDist,
-		finalData.blurringDist, dp));
+	/*hdr.setBlurringDistance(interpolate(originalData.blurringDist,
+		finalData.blurringDist, dp));*/
 }
 
 } // end namespace

+ 14 - 16
src/gl/ShaderProgram.cpp

@@ -127,8 +127,8 @@ void ShaderProgramUniformVariable::set(const Texture* const texes[],
 	const U32 count) const
 {
 	doCommonSetCode();
-	ANKI_ASSERT(count > 128);
-	ANKI_ASSERT(count <= size);
+	ANKI_ASSERT(count <= getSize());
+	ANKI_ASSERT(count <= 128);
 	Array<GLint, 128> units;
 
 	for(U32 i = 0; i < count; i++)
@@ -567,10 +567,9 @@ void ShaderProgram::initUniAndAttribVars()
 
 	attribs.resize(attribsCount);
 	attribs.shrink_to_fit();
+	attribsCount = 0;
 	for(int i = 0; i < num; i++) // loop all attributes
 	{
-		ShaderProgramAttributeVariable& var = attribs[i]; bug /// XXX BUG
-
 		// Name
 		glGetActiveAttrib(glId, i, sizeof(name_), &length,
 			&size, &type, &name_[0]);
@@ -585,6 +584,8 @@ void ShaderProgram::initUniAndAttribVars()
 			continue;
 		}
 
+		ShaderProgramAttributeVariable& var = attribs[attribsCount++];
+
 		var.loc = loc;
 		var.name = &name_[0];
 		var.glDataType = type;
@@ -599,7 +600,7 @@ void ShaderProgram::initUniAndAttribVars()
 	//
 	glGetProgramiv(glId, GL_ACTIVE_UNIFORMS, &num);
 	U unisCount = num;
-	
+
 	// Count the _useful_ uniforms
 	for(GLint i = 0; i < num; i++)
 	{
@@ -609,21 +610,17 @@ void ShaderProgram::initUniAndAttribVars()
 
 		// See bellow for info
 		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.shrink_to_fit();
+	unisCount = 0;
 	for(GLint i = 0; i < num; i++) // loop all uniforms
 	{
-		ShaderProgramUniformVariable& var = unis[i]; bug/// XXX BUG
-
 		glGetActiveUniform(glId, i, sizeof(name_), &length,
 			&size, &type, &name_[0]);
 		name_[length] = '\0';
@@ -631,18 +628,19 @@ void ShaderProgram::initUniAndAttribVars()
 		// In case of uniform arrays some implementations (nVidia) on 
 		// GL_ACTIVE_UNIFORMS they return the number of uniforms that are inside 
 		// 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 
 		// overpopulate the uniforms vector and hash map. So, to solve this if 
 		// 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 
-			&& strstr(&name_[0], "[0]") != nullptr)
+			&& strstr(&name_[0], "[0]") == nullptr)
 		{
-			ANKI_ASSERT(size > 1);
 			continue;
 		}
 
+		ShaderProgramUniformVariable& var = unis[unisCount++];
+
 		// -1 means in uniform block
 		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
 {
-	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)
 {
+#if 0
 	enabled = initializer.pps.bl.enabled;
 	blurringIterationsNum = initializer.pps.bl.blurringIterationsNum;
 	sideBlurFactor = initializer.pps.bl.sideBlurFactor;
@@ -66,11 +67,13 @@ void Bl::init(const Renderer::Initializer& initializer)
 
 	sideBlurMap.load("engine-rsrc/side-blur.png");
 	sideBlurSProg.load("shaders/PpsSideBlur.glsl");
+#endif
 }
 
 //==============================================================================
 void Bl::runSideBlur()
 {
+#if 0
 	if(sideBlurFactor == 0.0)
 	{
 		return;
@@ -87,11 +90,13 @@ void Bl::runSideBlur()
 	sideBlurSProg->findUniformVariable("factor").set(sideBlurFactor);
 
 	r->drawQuad();
+#endif
 }
 
 //==============================================================================
 void Bl::runBlur()
 {
+#if 0
 	GlStateSingleton::get().disable(GL_BLEND);
 
 	// Setup programs here. Reverse order
@@ -122,6 +127,7 @@ void Bl::runBlur()
 		vBlurSProg->bind();
 		r->drawQuad();
 	}
+#endif
 }
 
 //==============================================================================

+ 2 - 0
src/renderer/Bs.cpp

@@ -11,6 +11,7 @@ Bs::~Bs()
 //==============================================================================
 void Bs::createFbo()
 {
+#if 0
 	try
 	{
 		fbo.create();
@@ -23,6 +24,7 @@ void Bs::createFbo()
 	{
 		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)
 {
-	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;
 
@@ -40,6 +36,9 @@ void Hdr::init(const Renderer::Initializer& initializer)
 
 	width = renderingQuality * r->getWidth();
 	height = renderingQuality * r->getHeight();
+	exposure = initializer.pps.hdr.exposure;
+	blurringDist = initializer.pps.hdr.blurringDist;
+	blurringIterationsCount = initializer.pps.hdr.blurringIterationsCount;
 
 	initFbo(toneFbo, toneFai);
 	initFbo(hblurFbo, hblurFai);
@@ -48,22 +47,48 @@ void Hdr::init(const Renderer::Initializer& initializer)
 	fai.setFiltering(Texture::TFT_LINEAR);
 
 	// init shaders
+	Vec4 block(exposure, 0.0, 0.0, 0.0);
+	commonUbo.create(sizeof(Vec4), &block);
+
 	toneSProg.load("shaders/PpsHdr.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
 	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();
 
 	// blurring passes
-	for(uint32_t i = 0; i < blurringIterationsNum; i++)
+	for(U32 i = 0; i < blurringIterationsCount; i++)
 	{
 		// hpass
 		hblurFbo.bind();
-		hblurSProg.bind();
+		hblurSProg->bind();
 		if(i == 0)
 		{
-			hblurSProg.findUniformVariable("img").set(toneFai);
+			hblurSProg->findUniformVariable("img").set(toneFai);
 		}
 		else if(i == 1)
 		{
-			hblurSProg.findUniformVariable("img").set(fai);
+			hblurSProg->findUniformVariable("img").set(fai);
 		}
 		r->drawQuad();
 
 		// vpass
 		vblurFbo.bind();
-		vblurSProg.bind();
-		vblurSProg.findUniformVariable("img").set(hblurFai);
+		vblurSProg->bind();
+		vblurSProg->findUniformVariable("img").set(hblurFai);
 		r->drawQuad();
 	}
 }

+ 30 - 8
src/renderer/Is.cpp

@@ -14,7 +14,7 @@ namespace anki {
 struct ShaderLight
 {
 	Vec4 posAndRadius; ///< xyz: Light pos in eye space. w: The radius
-	Vec4 diffuseColor;
+	Vec4 diffuseColorShadowmapId;
 	Vec4 specularColor;
 };
 
@@ -23,7 +23,8 @@ struct ShaderPointLight: ShaderLight
 
 struct ShaderSpotLight: ShaderLight
 {
-	Vec4 lightDirection;
+	Vec4 lightDirection; ///< xyz: Dir vector
+	Vec4 outerCosInnerCos; ///< x: outer angle cos, y: inner
 	Mat4 texProjectionMat;
 };
 
@@ -88,7 +89,7 @@ struct WritePointLightsUbo: ThreadJob
 				cam->getViewMatrix());
 
 			pl.posAndRadius = Vec4(pos, light.getRadius());
-			pl.diffuseColor = light.getDiffuseColor();
+			pl.diffuseColorShadowmapId = light.getDiffuseColor();
 			pl.specularColor = light.getSpecularColor();
 		}
 	}
@@ -122,16 +123,18 @@ struct WriteSpotLightsUbo: ThreadJob
 
 			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();
 			lightDir = cam->getViewMatrix().getRotationPart() * lightDir;
 			slight.lightDirection = Vec4(lightDir, 0.0);
 			
+			slight.outerCosInnerCos = Vec4(light.getOuterAngleCos(),
+				light.getInnerAngleCos(), 1.0, 1.0);
+
 			static const Mat4 biasMat4(
 				0.5, 0.0, 0.0, 0.5, 
 				0.0, 0.5, 0.0, 0.5, 
@@ -716,6 +719,24 @@ void Is::lightPass()
 
 	// Done
 	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();
 
 	//
@@ -763,7 +784,8 @@ void Is::lightPass()
 		char str[128];
 		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
 

+ 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_BLEND);
 	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);
 	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);
 	hdr.init(initializer);
 
-	// Init pre pass
-	//
-
 	// 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
@@ -46,97 +38,61 @@ void Pps::init(const Renderer::Initializer& initializer)
 		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())
 	{
 		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())
 	{
 		hdr.run();
 	}
 
-	postPassFbo.bind();
+	fbo.bind();
 
 	GlStateSingleton::get().enable(GL_DEPTH_TEST, 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())
 	{
-		postPassSProg.findUniformVariable("ppsHdrFai").set(hdr.getFai());
+		prog->findUniformVariable("ppsHdrFai").set(hdr.getFai());
 	}
 
 	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();
 	is.run();
-	/*pps.runPrePass();
-	bs.run();
+	pps.run();
+	/*bs.run();
 	pps.runPostPass();*/
 
 	++framesNum;

+ 86 - 55
src/renderer/Ssao.cpp

@@ -6,25 +6,30 @@
 
 namespace anki {
 
+//==============================================================================
+struct ShaderCommonUniforms
+{
+	Vec4 nearPlanes;
+	Vec4 limitsOfNearPlane;
+};
+
 //==============================================================================
 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;
 
@@ -34,36 +39,69 @@ void Ssao::init(const RendererInitializer& initializer)
 	}
 
 	renderingQuality = initializer.pps.ssao.renderingQuality;
-	blurringIterationsNum = initializer.pps.ssao.blurringIterationsNum;
+	blurringIterationsCount = initializer.pps.ssao.blurringIterationsNum;
 
 	width = renderingQuality * r->getWidth();
 	height = renderingQuality * r->getHeight();
 
+	//
 	// create FBOs
+	//
 	createFbo(ssaoFbo, ssaoFai);
 	createFbo(hblurFbo, hblurFai);
 	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
 	//
+	commonUbo.create(sizeof(ShaderCommonUniforms), nullptr);
+
+	std::string pps;
 
 	// 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
 	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();
-	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
-	ssaoSProg.findUniformVariable("msDepthFai").set(
+	ssaoSProg->findUniformVariable("msDepthFai").set(
 		r->getMs().getDepthFai());
 
 	// 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
-	ssaoSProg.findUniformVariable("msNormalFai").set(
+	ssaoSProg->findUniformVariable("msGFai").set(
 		r->getMs().getFai0());
 
 	r->drawQuad();
 
-	vblurSProg.bind();
-	vblurSProg.findUniformVariable("img").set(hblurFai);
+	vblurSProg->bind();
+	vblurSProg->findUniformVariable("img").set(hblurFai);
 
 	// Blurring passes
 	//
-	for(uint32_t i = 0; i < blurringIterationsNum; i++)
+	for(U32 i = 0; i < blurringIterationsCount; i++)
 	{
 		// hpass
 		hblurFbo.bind();
-		hblurSProg.bind();
+		hblurSProg->bind();
 		if(i == 0)
 		{
-			hblurSProg.findUniformVariable("img").set(ssaoFai);
+			hblurSProg->findUniformVariable("img").set(ssaoFai);
 		}
 		else if(i == 1)
 		{
-			hblurSProg.findUniformVariable("img").set(fai);
+			hblurSProg->findUniformVariable("img").set(fai);
 		}
 		r->drawQuad();
 
 		// vpass
 		vblurFbo.bind();
-		vblurSProg.bind();
+		vblurSProg->bind();
 		r->drawQuad();
 	}
 }
 
-} // end namespace
+} // end namespace anki

+ 1 - 1
src/scene/Scene.cpp

@@ -8,7 +8,7 @@ namespace anki {
 //==============================================================================
 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)
 	{
-		/*SceneSingleton::get().getActiveCamera().
-			getFrustumable()->getFrustum().setFar(250.0);*/
+		MainRendererSingleton::get().getPps().getHdr().setExposure(20);
 	}
 
 	if(in.getKey(KC_UP)) mover->rotateLocalX(ang);
@@ -345,9 +344,9 @@ void initSubsystems(int argc, char* argv[])
 	initializer.is.sm.resolution = 512;
 	initializer.pps.hdr.enabled = true;
 	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.enabled = true;
 	initializer.pps.ssao.renderingQuality = 0.3;