Browse Source

Global resource groups

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
00a696980a

+ 42 - 42
include/anki/math/Mat4.h

@@ -35,7 +35,7 @@ public:
 /// row major. SSE optimized
 /// @note TMat4*TMat4: 64 muls 48 adds
 template<typename T>
-class alignas(16) TMat4: public TMat<T, 4, 4, typename TMat4Simd<T>::Type, 
+class alignas(16) TMat4: public TMat<T, 4, 4, typename TMat4Simd<T>::Type,
 	  TMat4<T>, TVec4<T>, TVec4<T>>
 {
 	/// @name Friends
@@ -51,7 +51,7 @@ class alignas(16) TMat4: public TMat<T, 4, 4, typename TMat4Simd<T>::Type,
 	/// @}
 
 public:
-	using Base = TMat<T, 4, 4, typename TMat4Simd<T>::Type, 
+	using Base = TMat<T, 4, 4, typename TMat4Simd<T>::Type,
 	  TMat4<T>, TVec4<T>, TVec4<T>>;
 
 	using Base::getTranslationPart;
@@ -62,14 +62,14 @@ public:
 	/// @name Constructors
 	/// @{
 	explicit TMat4()
-	:	Base()
+		: Base()
 	{}
 
 	TMat4(const TMat4& b)
-	:	Base(b)
+		: Base(b)
 	{}
 
-	explicit TMat4(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, 
+	explicit TMat4(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13,
 		T m20, T m21, T m22, T m23, T m30, T m31, T m32, T m33)
 	{
 		TMat4& m = *this;
@@ -184,9 +184,9 @@ public:
 	}
 
 	explicit TMat4(const TTransform<T>& t)
-	:	TMat4(TVec4<T>(t.getOrigin().xyz(), 1.0), 
-		t.getRotation().getRotationPart(), 
-		t.getScale())
+		: TMat4(TVec4<T>(t.getOrigin().xyz(), 1.0)
+		, t.getRotation().getRotationPart()
+		, t.getScale())
 	{}
 	/// @}
 
@@ -195,29 +195,29 @@ public:
 	T getDet() const
 	{
 		const TMat4& t = *this;
-		return t(0, 3) * t(1, 2) * t(2, 1) * t(3, 0) 
-			- t(0, 2) * t(1, 3) * t(2, 1) * t(3, 0) 
-			- t(0, 3) * t(1, 1) * t(2, 2) * t(3, 0) 
+		return t(0, 3) * t(1, 2) * t(2, 1) * t(3, 0)
+			- t(0, 2) * t(1, 3) * t(2, 1) * t(3, 0)
+			- t(0, 3) * t(1, 1) * t(2, 2) * t(3, 0)
 			+ t(0, 1) * t(1, 3) * t(2, 2) * t(3, 0)
-			+ t(0, 2) * t(1, 1) * t(2, 3) * t(3, 0) 
-			- t(0, 1) * t(1, 2) * t(2, 3) * t(3, 0) 
-			- t(0, 3) * t(1, 2) * t(2, 0) * t(3, 1) 
-			+ t(0, 2) * t(1, 3) * t(2, 0) * t(3, 1) 
-			+ t(0, 3) * t(1, 0) * t(2, 2) * t(3, 1) 
+			+ t(0, 2) * t(1, 1) * t(2, 3) * t(3, 0)
+			- t(0, 1) * t(1, 2) * t(2, 3) * t(3, 0)
+			- t(0, 3) * t(1, 2) * t(2, 0) * t(3, 1)
+			+ t(0, 2) * t(1, 3) * t(2, 0) * t(3, 1)
+			+ t(0, 3) * t(1, 0) * t(2, 2) * t(3, 1)
 			- t(0, 0) * t(1, 3) * t(2, 2) * t(3, 1)
-			- t(0, 2) * t(1, 0) * t(2, 3) * t(3, 1) 
-			+ t(0, 0) * t(1, 2) * t(2, 3) * t(3, 1) 
-			+ t(0, 3) * t(1, 1) * t(2, 0) * t(3, 2) 
+			- t(0, 2) * t(1, 0) * t(2, 3) * t(3, 1)
+			+ t(0, 0) * t(1, 2) * t(2, 3) * t(3, 1)
+			+ t(0, 3) * t(1, 1) * t(2, 0) * t(3, 2)
 			- t(0, 1) * t(1, 3) * t(2, 0) * t(3, 2)
 			- t(0, 3) * t(1, 0) * t(2, 1) * t(3, 2)
-			+ t(0, 0) * t(1, 3) * t(2, 1) * t(3, 2) 
+			+ t(0, 0) * t(1, 3) * t(2, 1) * t(3, 2)
 			+ t(0, 1) * t(1, 0) * t(2, 3) * t(3, 2)
 			- t(0, 0) * t(1, 1) * t(2, 3) * t(3, 2)
 			- t(0, 2) * t(1, 1) * t(2, 0) * t(3, 3)
 			+ t(0, 1) * t(1, 2) * t(2, 0) * t(3, 3)
 			+ t(0, 2) * t(1, 0) * t(2, 1) * t(3, 3)
-			- t(0, 0) * t(1, 2) * t(2, 1) * t(3, 3) 
-			- t(0, 1) * t(1, 0) * t(2, 2) * t(3, 3) 
+			- t(0, 0) * t(1, 2) * t(2, 1) * t(3, 3)
+			- t(0, 1) * t(1, 0) * t(2, 2) * t(3, 3)
 			+ t(0, 0) * t(1, 1) * t(2, 2) * t(3, 3);
 	}
 
@@ -288,7 +288,7 @@ public:
 		m4(3, 3) =  tmp[10] * in(2, 2) + tmp[4] * in(0, 2) + tmp[9] * in(1, 2);
 		m4(3, 3) -= tmp[8] * in(1, 2) + tmp[11] * in(2, 2) + tmp[5] * in(0, 2);
 
-		T det = in(0, 0) * m4(0, 0) + in(1, 0) * m4(0, 1) 
+		T det = in(0, 0) * m4(0, 0) + in(1, 0) * m4(0, 1)
 			+ in(2, 0) * m4(0, 2) + in(3, 0) * m4(0, 3);
 
 		ANKI_ASSERT(!isZero<T>(det)); // Cannot invert, det == 0
@@ -308,9 +308,9 @@ public:
 	TMat4 getInverseTransformation() const
 	{
 		TMat3<T> invertedRot = getRotationPart().getTransposed();
-		TVec3<T> invertedTsl = getTranslationPart();
+		TVec3<T> invertedTsl = getTranslationPart().xyz();
 		invertedTsl = -(invertedRot * invertedTsl);
-		return TMat4(invertedTsl, invertedRot);
+		return TMat4(invertedTsl.xyz0(), invertedRot);
 	}
 
 	void setIdentity()
@@ -321,9 +321,9 @@ public:
 	static const TMat4& getIdentity()
 	{
 		static const TMat4 ident(
-			1.0, 0.0, 0.0, 0.0, 
-			0.0, 1.0, 0.0, 0.0, 
-			0.0, 0.0, 1.0, 0.0, 
+			1.0, 0.0, 0.0, 0.0,
+			0.0, 1.0, 0.0, 0.0,
+			0.0, 0.0, 1.0, 0.0,
 			0.0, 0.0, 0.0, 1.0);
 		return ident;
 	}
@@ -340,32 +340,32 @@ public:
 
 		TMat4 m4;
 
-		m4(0, 0) = 
+		m4(0, 0) =
 			m0(0, 0) * m1(0, 0) + m0(0, 1) * m1(1, 0) + m0(0, 2) * m1(2, 0);
-		m4(0, 1) = 
+		m4(0, 1) =
 			m0(0, 0) * m1(0, 1) + m0(0, 1) * m1(1, 1) + m0(0, 2) * m1(2, 1);
-		m4(0, 2) = 
+		m4(0, 2) =
 			m0(0, 0) * m1(0, 2) + m0(0, 1) * m1(1, 2) + m0(0, 2) * m1(2, 2);
-		m4(1, 0) = 
+		m4(1, 0) =
 			m0(1, 0) * m1(0, 0) + m0(1, 1) * m1(1, 0) + m0(1, 2) * m1(2, 0);
-		m4(1, 1) = 
+		m4(1, 1) =
 			m0(1, 0) * m1(0, 1) + m0(1, 1) * m1(1, 1) + m0(1, 2) * m1(2, 1);
-		m4(1, 2) = 
+		m4(1, 2) =
 			m0(1, 0) * m1(0, 2) + m0(1, 1) * m1(1, 2) + m0(1, 2) * m1(2, 2);
 		m4(2, 0) =
 			m0(2, 0) * m1(0, 0) + m0(2, 1) * m1(1, 0) + m0(2, 2) * m1(2, 0);
-		m4(2, 1) = 
+		m4(2, 1) =
 			m0(2, 0) * m1(0, 1) + m0(2, 1) * m1(1, 1) + m0(2, 2) * m1(2, 1);
 		m4(2, 2) =
 			m0(2, 0) * m1(0, 2) + m0(2, 1) * m1(1, 2) + m0(2, 2) * m1(2, 2);
 
-		m4(0, 3) = m0(0, 0) * m1(0, 3) + m0(0, 1) * m1(1, 3) 
+		m4(0, 3) = m0(0, 0) * m1(0, 3) + m0(0, 1) * m1(1, 3)
 			+ m0(0, 2) * m1(2, 3) + m0(0, 3);
 
-		m4(1, 3) = m0(1, 0) * m1(0, 3) + m0(1, 1) * m1(1, 3) 
+		m4(1, 3) = m0(1, 0) * m1(0, 3) + m0(1, 1) * m1(1, 3)
 			+ m0(1, 2) * m1(2, 3) + m0(1, 3);
 
-		m4(2, 3) = m0(2, 0) * m1(0, 3) + m0(2, 1) * m1(1, 3) 
+		m4(2, 3) = m0(2, 0) * m1(0, 3) + m0(2, 1) * m1(1, 3)
 			+ m0(2, 2) * m1(2, 3) + m0(2, 3);
 
 		m4(3, 0) = m4(3, 1) = m4(3, 2) = 0.0;
@@ -380,11 +380,11 @@ public:
 		const TMat4& m = *this;
 
 		return TVec3<T>(
-			m(0, 0) * v.x() + m(0, 1) * v.y() 
+			m(0, 0) * v.x() + m(0, 1) * v.y()
 			+ m(0, 2) * v.z() + m(0, 3),
-			m(1, 0) * v.x() + m(1, 1) * v.y() 
+			m(1, 0) * v.x() + m(1, 1) * v.y()
 			+ m(1, 2) * v.z() + m(1, 3),
-			m(2, 0) * v.x() + m(2, 1) * v.y() 
+			m(2, 0) * v.x() + m(2, 1) * v.y()
 			+ m(2, 2) * v.z() + m(2, 3));
 	}
 	/// @}
@@ -422,7 +422,7 @@ template<>
 TVec4<F32> TMat4<F32>::Base::operator*(const TVec4<F32>& b) const;
 
 template<>
-void TMat4<F32>::Base::setRows(const TVec4<F32>& a, const TVec4<F32>& b, 
+void TMat4<F32>::Base::setRows(const TVec4<F32>& a, const TVec4<F32>& b,
 	const TVec4<F32>& c, const TVec4<F32>& d);
 
 template<>

+ 2 - 0
include/anki/renderer/Fs.h

@@ -27,6 +27,8 @@ anki_internal:
 
 private:
 	FramebufferPtr m_fb;
+
+	Array<ResourceGroupPtr, MAX_FRAMES_IN_FLIGHT> m_globalResources;
 };
 /// @}
 

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

@@ -67,17 +67,37 @@ anki_internal:
 		m_ambientColor = color;
 	}
 
-private:
-	enum
+	Sm& getSm()
+	{
+		return m_sm;
+	}
+
+	BufferPtr getCommonVarsBuffer(U idx) const
+	{
+		return m_commonVarsBuffs[idx];
+	}
+
+	BufferPtr getPointLightsBuffer(U idx) const
+	{
+		return m_pLightsBuffs[idx];
+	}
+
+	BufferPtr getSpotLightsBuffer(U idx) const
 	{
-		COMMON_UNIFORMS_BLOCK_BINDING = 0,
-		POINT_LIGHTS_BLOCK_BINDING = 1,
-		SPOT_LIGHTS_BLOCK_BINDING = 2,
-		SPOT_TEX_LIGHTS_BLOCK_BINDING = 3,
-		TILES_BLOCK_BINDING = 4,
-		LIGHT_IDS_BLOCK_BINDING = 5
-	};
+		return m_sLightsBuffs[idx];
+	}
+
+	BufferPtr getClusterBuffer(U idx) const
+	{
+		return m_clusterBuffers[idx];
+	}
 
+	BufferPtr getLightIndicesBuffer(U idx) const
+	{
+		return m_lightIdsBuffers[idx];
+	}
+
+private:
 	U32 m_currentFrame = 0; ///< Cache value.
 
 	/// The IS render target
@@ -89,8 +109,8 @@ private:
 	/// @name GPU buffers
 	/// @{
 
-	/// Track the updates of commonUbo
-	Timestamp m_commonBuffUpdateTimestamp = 0;
+	/// Contains some variables.
+	Array<BufferPtr, MAX_FRAMES_IN_FLIGHT> m_commonVarsBuffs;
 
 	/// Contains all the point lights
 	Array<BufferPtr, MAX_FRAMES_IN_FLIGHT> m_pLightsBuffs;

+ 12 - 5
shaders/BsCommonFrag.glsl

@@ -8,12 +8,19 @@
 #pragma anki include "shaders/MsBsCommon.glsl"
 #pragma anki include "shaders/LinearDepth.glsl"
 
+// Global resources
+layout(TEX_BINDING(1, 0)) uniform sampler2D anki_u_msDepthRt;
+#define LIGHT_SET 1
+#define LIGHT_SS_BINDING 0
+#define LIGHT_TEX_BINDING 1
+#pragma anki include "shaders/LightResources.glsl"
+#undef LIGHT_SET
+#undef LIGHT_SS_BINDING
+#undef LIGHT_TEX_BINDING
+
 layout(location = 1) flat in float inAlpha;
 
-#if PASS == COLOR
-layout(location = 0) out vec4 outColor;
-#	define outColor_DEFINED
-#endif
+layout(location = 0) out vec4 out_color;
 
 #if PASS == COLOR
 #	define texture_DEFINED
@@ -35,7 +42,7 @@ float getAlpha()
 #	define writeGBuffer_DEFINED
 void writeGBuffer(in vec4 color)
 {
-	outColor = color;
+	out_color = color;
 }
 #endif
 

+ 4 - 2
shaders/Common.glsl

@@ -21,14 +21,16 @@
 precision DEFAULT_FLOAT_PRECISION float;
 precision DEFAULT_FLOAT_PRECISION int;
 
-#define EPSILON (0.000001)
+const float EPSILON = 0.000001;
+const float PI = 3.14159265358979323846;
 
 // Read from a render target texture
 //#define textureRt(tex_, texc_) texture(tex_, texc_)
 #define textureRt(tex_, texc_) textureLod(tex_, texc_, 0.0)
 
 // Binding
-#define BINDING(slot_, binding_) binding = slot_ * 8 + binding_
+#define SS_BINDING(slot_, binding_) binding = slot_ * 8 + binding_
+#define TEX_BINDING(slot_, binding_) binding = slot_ * 8 + binding_
 
 // Common locations
 #define POSITION_LOCATION 0

+ 1 - 1
shaders/IsCommon.glsl

@@ -8,7 +8,7 @@
 #pragma anki include "shaders/Common.glsl"
 
 // Common uniforms between lights
-layout(std140, row_major, binding = 0) uniform _0
+layout(std140, row_major, binding = 0) readonly buffer _s0
 {
 	vec4 u_projectionParams;
 	vec4 u_sceneAmbientColor;

+ 19 - 242
shaders/IsLp.frag.glsl

@@ -4,67 +4,20 @@
 // http://www.anki3d.org/LICENSE
 
 #pragma anki type frag
-#pragma anki include "shaders/IsCommon.glsl"
 #pragma anki include "shaders/Pack.glsl"
 
-#define PI 3.1415926535
-
-#define ATTENUATION_FINE 0
-#define ATTENUATION_BOOST (0.05)
-
-#ifndef BRDF
-#	define BRDF 1
-#endif
-
-const uint CLUSTER_COUNT_Z = CLUSTER_COUNT / (TILES_X_COUNT * TILES_Y_COUNT);
-const uint TILE_COUNT = TILES_X_COUNT * TILES_Y_COUNT;
-
-// The base of all lights
-struct Light
-{
-	vec4 posRadius; // xyz: Light pos in eye space. w: The -1/radius
-	vec4 diffuseColorShadowmapId; // xyz: diff color, w: shadowmap tex ID
-	vec4 specularColorTexId; // xyz: spec color, w: diffuse tex ID
-};
-
-// Point light
-#define PointLight Light
-
-// Spot light
-struct SpotLight
-{
-	Light base;
-	vec4 lightDir;
-	vec4 outerCosInnerCos;
-	mat4 texProjectionMat;
-};
-
-layout(std140, binding = 0) readonly buffer _s0
-{
-	PointLight u_pointLights[MAX_POINT_LIGHTS];
-};
-
-layout(std140, binding = 1) readonly buffer _s1
-{
-	SpotLight u_spotLights[MAX_SPOT_LIGHTS];
-};
-
-layout(std430, binding = 2) readonly buffer _s3
-{
-	uint u_clusters[CLUSTER_COUNT];
-};
-
-layout(std430, binding = 3) readonly buffer _s5
-{
-	uint u_lightIndices[MAX_LIGHT_INDICES];
-};
+#define LIGHT_SET 0
+#define LIGHT_SS_BINDING 0
+#define LIGHT_TEX_BINDING 4
+#pragma anki include "shaders/LightResources.glsl"
+#undef LIGHT_SET
+#undef LIGHT_SS_BINDING
+#undef LIGHT_TEX_BINDING
 
 layout(binding = 0) uniform sampler2D u_msRt0;
 layout(binding = 1) uniform sampler2D u_msRt1;
 layout(binding = 2) uniform sampler2D u_msRt2;
 layout(binding = 3) uniform sampler2D u_msDepthRt;
-layout(binding = 4) uniform highp sampler2DArrayShadow u_spotMapArr;
-layout(binding = 5) uniform highp samplerCubeArrayShadow u_omniMapArr;
 
 layout(location = 0) in vec2 in_texCoord;
 layout(location = 1) flat in int in_instanceId;
@@ -72,6 +25,8 @@ layout(location = 2) in vec2 in_projectionParams;
 
 layout(location = 0) out vec3 out_color;
 
+#pragma anki include "shaders/LightFunctions.glsl"
+
 //==============================================================================
 // Return frag pos in view space
 vec3 getFragPosVSpace()
@@ -85,193 +40,20 @@ vec3 getFragPosVSpace()
 	return fragPos;
 }
 
-//==============================================================================
-/// Calculate the cluster split
-uint calcK(float zVspace)
-{
-	zVspace = -zVspace;
-	float fk = sqrt((zVspace - u_clustererParams.x) / u_clustererParams.y);
-	uint k = uint(fk);
-	k = min(k, CLUSTER_COUNT_Z);
-	return k;
-}
-
-//==============================================================================
-float computeAttenuationFactor(
-	in float lightRadius,
-	in vec3 frag2Light)
-{
-	float fragLightDist = length(frag2Light);
-
-	float att = (fragLightDist * lightRadius) + (1.0 + ATTENUATION_BOOST);
-	att = max(0.0, att);
-	att *= att;
-
-	return att;
-}
-
-//==============================================================================
-// Performs phong specular lighting
-vec3 computeSpecularColor(
-	in vec3 v,
-	in vec3 l,
-	in vec3 n,
-	in float specCol,
-	in float specPower,
-	in vec3 lightSpecCol)
-{
-	vec3 h = normalize(l + v);
-	float specIntensity = pow(max(0.0, dot(n, h)), specPower);
-	vec3 outSpecCol = lightSpecCol * (specIntensity * specCol);
-
-	return outSpecCol;
-}
-
-//==============================================================================
-// Performs BRDF specular lighting
-vec3 computeSpecularColorBrdf(
-	in vec3 v,
-	in vec3 l,
-	in vec3 n,
-	in vec3 specCol,
-	in float specPower,
-	in vec3 lightSpecCol,
-	in float a2, // rougness^2
-	in float nol) // N dot L
-{
-	vec3 h = normalize(l + v);
-
-	// Fresnel (Schlick)
-	float loh = max(EPSILON, dot(l, h));
-	vec3 f = specCol + (1.0 - specCol) * pow((1.0 + EPSILON - loh), 5.0);
-	//float f = specColor + (1.0 - specColor)
-	//	* pow(2.0, (-5.55473 * loh - 6.98316) * loh);
-
-	// NDF: GGX Trowbridge-Reitz
-	float noh = max(EPSILON, dot(n, h));
-	float d = a2 / (PI * pow(noh * noh * (a2 - 1.0) + 1.0, 2.0));
-
-	// Visibility term: Geometric shadowing devided by BRDF denominator
-	float nov = max(EPSILON, dot(n, v));
-	float vv = nov + sqrt((nov - nov * a2) * nov + a2);
-	float vl = nol + sqrt((nol - nol * a2) * nol + a2);
-	float vis = 1.0 / (vv * vl);
-
-	return f * (vis * d) * lightSpecCol;
-}
-
-//==============================================================================
-vec3 computeDiffuseColor(in vec3 diffCol, in vec3 lightDiffCol)
-{
-	return diffCol * lightDiffCol;
-}
-
-//==============================================================================
-float computeSpotFactor(
-	in vec3 l,
-	in float outerCos,
-	in float innerCos,
-	in vec3 spotDir)
-{
-	float costheta = -dot(l, spotDir);
-	float spotFactor = smoothstep(outerCos, innerCos, costheta);
-	return spotFactor;
-}
-
-//==============================================================================
-float computeShadowFactor(
-	in mat4 lightProjectionMat,
-	in vec3 fragPos,
-	in highp sampler2DArrayShadow shadowMapArr,
-	in float layer)
-{
-	vec4 texCoords4 = lightProjectionMat * vec4(fragPos, 1.0);
-	vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
-
-#if POISSON == 1
-	const vec2 poissonDisk[4] = vec2[](
-		vec2(-0.94201624, -0.39906216),
-		vec2(0.94558609, -0.76890725),
-		vec2(-0.094184101, -0.92938870),
-		vec2(0.34495938, 0.29387760));
-
-	float shadowFactor = 0.0;
-
-	vec2 cordpart0 = vec2(layer, texCoords3.z);
-
-	for(int i = 0; i < 4; i++)
-	{
-		vec2 cordpart1 = texCoords3.xy + poissonDisk[i] / (300.0);
-		vec4 tcoord = vec4(cordpart1, cordpart0);
-
-		shadowFactor += texture(u_spotMapArr, tcoord);
-	}
-
-	return shadowFactor / 4.0;
-#else
-	vec4 tcoord = vec4(texCoords3.x, texCoords3.y, layer, texCoords3.z);
-	float shadowFactor = texture(shadowMapArr, tcoord);
-
-	return shadowFactor;
-#endif
-}
-
-//==============================================================================
-float computeShadowFactorOmni(in vec3 frag2Light, in float layer,
-	in float radius)
-{
-	vec3 dir = (u_viewMat * vec4(-frag2Light, 1.0)).xyz;
-	vec3 dirabs = abs(dir);
-	float dist = -max(dirabs.x, max(dirabs.y, dirabs.z));
-	dir = normalize(dir);
-
-	const float near = OMNI_LIGHT_FRUSTUM_NEAR_PLANE;
-	const float far = radius;
-
-	// Original code:
-	// float g = near - far;
-	// float z = (far + near) / g * dist + (2.0 * far * near) / g;
-	// float w = -dist;
-	// z /= w;
-	// z = z * 0.5 + 0.5;
-	// Optimized:
-	float z = (far * (dist + near)) / (dist * (far - near));
-
-	float shadowFactor = texture(u_omniMapArr, vec4(dir, layer), z).r;
-	return shadowFactor;
-}
-
 //==============================================================================
 // Common code for lighting
 
-#define LIGHTING_COMMON_PHONG() \
-	vec3 frag2Light = light.posRadius.xyz - fragPos; \
-	vec3 l = normalize(frag2Light); \
-	float nol = max(0.0, dot(normal, l)); \
-	vec3 specC = computeSpecularColor( \
-		viewDir, l, normal, specCol, specPower, light.specularColorTexId.rgb); \
-	vec3 diffC = computeDiffuseColor( \
-		diffCol, light.diffuseColorShadowmapId.rgb); \
-	float att = computeAttenuationFactor(light.posRadius.w, frag2Light); \
-	float lambert = nol;
-
 #define LIGHTING_COMMON_BRDF() \
 	vec3 frag2Light = light.posRadius.xyz - fragPos; \
 	vec3 l = normalize(frag2Light); \
 	float nol = max(0.0, dot(normal, l)); \
 	vec3 specC = computeSpecularColorBrdf(viewDir, l, normal, specCol, \
-		specPower, light.specularColorTexId.rgb, a2, nol); \
+		light.specularColorTexId.rgb, a2, nol); \
 	vec3 diffC = computeDiffuseColor( \
 		diffCol, light.diffuseColorShadowmapId.rgb); \
 	float att = computeAttenuationFactor(light.posRadius.w, frag2Light); \
 	float lambert = nol;
 
-#if BRDF
-#	define LIGHTING_COMMON LIGHTING_COMMON_BRDF
-#else
-#	define LIGHTING_COMMON LIGHTING_COMMON_PHONG
-#endif
-
 //==============================================================================
 void debugIncorrectColor(inout vec3 c)
 {
@@ -300,17 +82,13 @@ void main()
 		u_msRt0, u_msRt1, u_msRt2,
 		in_texCoord, diffCol, normal, specCol, specPower);
 
-#if BRDF
 	float a2 = pow(max(EPSILON, specPower), 2.0);
-#else
-	specPower = max(EPSILON, specPower) * 128.0;
-#endif
 
 	// Ambient color
 	out_color = diffCol * u_sceneAmbientColor.rgb;
 
 	// Get counts and offsets
-	uint k = calcK(fragPos.z);
+	uint k = calcClusterSplit(fragPos.z);
 	uint cluster = u_clusters[in_instanceId + k * TILE_COUNT];
 	uint lightOffset = cluster >> 16u;
 	uint pointLightsCount = (cluster >> 8u) & 0xFFu;
@@ -322,7 +100,7 @@ void main()
 		uint lightId = u_lightIndices[lightOffset++];
 		PointLight light = u_pointLights[lightId];
 
-		LIGHTING_COMMON();
+		LIGHTING_COMMON_BRDF();
 
 		float shadow = 1.0;
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
@@ -340,22 +118,21 @@ void main()
 	for(uint i = 0U; i < spotLightsCount; ++i)
 	{
 		uint lightId = u_lightIndices[lightOffset++];
-		SpotLight slight = u_spotLights[lightId];
-		Light light = slight.base;
+		SpotLight light = u_spotLights[lightId];
 
-		LIGHTING_COMMON();
+		LIGHTING_COMMON_BRDF();
 
 		float spot = computeSpotFactor(
-			l, slight.outerCosInnerCos.x,
-			slight.outerCosInnerCos.y,
-			slight.lightDir.xyz);
+			l, light.outerCosInnerCos.x,
+			light.outerCosInnerCos.y,
+			light.lightDir.xyz);
 
 		float shadow = 1.0;
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		if(shadowmapLayerIdx < 128.0)
 		{
-			shadow = computeShadowFactor(slight.texProjectionMat,
-				fragPos, u_spotMapArr, shadowmapLayerIdx);
+			shadow = computeShadowFactorSpot(light.texProjectionMat,
+				fragPos, shadowmapLayerIdx);
 		}
 
 		out_color += (diffC + specC)

+ 3 - 3
shaders/IsLp.vert.glsl

@@ -20,13 +20,13 @@ void main()
 	float instIdF = float(gl_InstanceID);
 
 	vec2 ij = vec2(
-		mod(instIdF, float(TILES_X_COUNT)),
-		floor(instIdF / float(TILES_X_COUNT)));
+		mod(instIdF, float(TILES_COUNT_X)),
+		floor(instIdF / float(TILES_COUNT_X)));
 
 	out_instanceId = int(gl_InstanceID);
 
 	const vec2 SIZES =
-		vec2(1.0 / float(TILES_X_COUNT), 1.0 / float(TILES_Y_COUNT));
+		vec2(1.0 / float(TILES_COUNT_X), 1.0 / float(TILES_COUNT_Y));
 
 	const vec2 UVS[4] = vec2[](
 		vec2(0.0, 0.0) * SIZES,

+ 15 - 14
shaders/MsCommonFrag.glsl

@@ -19,22 +19,23 @@ layout(early_fragment_tests) in;
 //
 // Input
 //
-layout(location = 0) in mediump vec2 inTexCoord;
+layout(location = 0) in mediump vec2 in_uv;
 #if PASS == COLOR
-layout(location = 1) in mediump vec3 inNormal;
-layout(location = 2) in mediump vec4 inTangent;
-layout(location = 3) in mediump vec3 inVertPosViewSpace;
+layout(location = 1) in mediump vec3 in_normal;
+layout(location = 2) in mediump vec4 in_tangent;
+layout(location = 3) in mediump vec3 in_vertPosViewSpace;
 #endif
 
 //
 // Output
 //
 #if PASS == COLOR
-layout(location = 0) out vec4 outMsRt0;
-layout(location = 1) out vec4 outMsRt1;
-layout(location = 2) out vec4 outMsRt2;
-#	define outMsRt0_DEFINED
-#	define outMsRt1_DEFINED
+layout(location = 0) out vec4 out_msRt0;
+layout(location = 1) out vec4 out_msRt1;
+layout(location = 2) out vec4 out_msRt2;
+#	define out_msRt0_DEFINED
+#	define out_msRt1_DEFINED
+#	define out_msRt2_DEFINED
 #endif
 
 //==============================================================================
@@ -46,7 +47,7 @@ layout(location = 2) out vec4 outMsRt2;
 #	define getNormal_DEFINED
 vec3 getNormal()
 {
-	return normalize(inNormal);
+	return normalize(in_normal);
 }
 #endif
 
@@ -55,7 +56,7 @@ vec3 getNormal()
 #	define getTangent_DEFINED
 vec4 getTangent()
 {
-	return inTangent;
+	return in_tangent;
 }
 #endif
 
@@ -63,7 +64,7 @@ vec4 getTangent()
 #define getTextureCoord_DEFINED
 vec2 getTextureCoord()
 {
-	return inTexCoord;
+	return in_uv;
 }
 
 // Getter
@@ -74,7 +75,7 @@ vec3 getPositionViewSpace()
 #if TESSELLATION
 	return vec3(0.0);
 #else
-	return inVertPosViewSpace;
+	return in_vertPosViewSpace;
 #endif
 }
 #endif
@@ -218,6 +219,6 @@ void writeRts(
 	in float blurring)
 {
 	writeGBuffer(diffColor, normal, specularColor, specularPower,
-		outMsRt0, outMsRt1, outMsRt2);
+		out_msRt0, out_msRt1, out_msRt2);
 }
 #endif

+ 0 - 1
shaders/PpsSslr.frag.glsl

@@ -9,7 +9,6 @@
 #pragma anki include "shaders/LinearDepth.glsl"
 #pragma anki include "shaders/Pack.glsl"
 
-const float PI = 3.14159265358979323846;
 const float ONE = 0.9;
 
 layout(location = 0) in vec2 in_texCoords;

+ 9 - 2
src/gr/gl/ShaderImpl.cpp

@@ -42,6 +42,10 @@ Error ShaderImpl::create(ShaderType type, const CString& source)
 		GL_TESS_CONTROL_SHADER, GL_TESS_EVALUATION_SHADER, GL_GEOMETRY_SHADER,
 		GL_FRAGMENT_SHADER, GL_COMPUTE_SHADER}};
 
+	static const Array<const char*, 6> shaderName = {{"VERTEX_SHADER",
+		"TESSELATION_CONTROL_SHADER", "TESSELATION_EVALUATION_SHADER",
+		"GEOMETRY_SHADER", "FRAGMENT_SHADER", "COMPUTE_SHADER"}};
+
 	m_type = type;
 	m_glType = gltype[U(type)];
 
@@ -58,11 +62,14 @@ Error ShaderImpl::create(ShaderType type, const CString& source)
 	auto alloc = getAllocator();
 	StringAuto fullSrc(alloc);
 #if ANKI_GL == ANKI_GL_DESKTOP
-	fullSrc.sprintf("#version %d core\n%s\n", version, &source[0]);
+	static const char* versionType = "core";
 #else
-	fullSrc.sprintf("#version %d es\n%s\n", version, &source[0]);
+	static const char* versionType = "es";
 #endif
 
+	fullSrc.sprintf("#version %d %s\n#define %s\n%s\n", version, versionType,
+		shaderName[U(type)], &source[0]);
+
 	// 2) Gen name, create, compile and link
 	//
 	const char* sourceStrs[1] = {nullptr};

+ 25 - 0
src/renderer/Fs.cpp

@@ -29,6 +29,29 @@ Error Fs::init(const ConfigSet&)
 		AttachmentLoadOperation::LOAD;
 	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
 
+	// Init the global resources
+	for(U i = 0; i < m_globalResources.getSize(); ++i)
+	{
+		ResourceGroupInitializer init;
+		init.m_textures[0].m_texture = m_r->getMs().getDepthRt();
+		init.m_textures[1].m_texture =
+			m_r->getIs().getSm().getSpotTextureArray();
+		init.m_textures[2].m_texture =
+			m_r->getIs().getSm().getOmniTextureArray();
+
+		init.m_storageBuffers[0].m_buffer =
+			m_r->getIs().getCommonVarsBuffer(i);
+		init.m_storageBuffers[1].m_buffer =
+			m_r->getIs().getPointLightsBuffer(i);
+		init.m_storageBuffers[2].m_buffer =
+			m_r->getIs().getSpotLightsBuffer(i);
+		init.m_storageBuffers[3].m_buffer = m_r->getIs().getClusterBuffer(i);
+		init.m_storageBuffers[4].m_buffer =
+			m_r->getIs().getLightIndicesBuffer(i);
+
+		m_globalResources[i] = getGrManager().newInstance<ResourceGroup>(init);
+	}
+
 	return ErrorCode::NONE;
 }
 
@@ -40,6 +63,8 @@ Error Fs::run(CommandBufferPtr& cmdb)
 	SceneNode& cam = m_r->getActiveCamera();
 	FrustumComponent& camFr = cam.getComponent<FrustumComponent>();
 
+	cmdb->bindResourceGroup(m_globalResources[getGlobalTimestamp() % 3], 1);
+
 	SArray<CommandBufferPtr> cmdbs(&cmdb, 1);
 	ANKI_CHECK(m_r->getSceneDrawer().render(
 		camFr, RenderingStage::BLEND, Pass::MS_FS, cmdbs));

+ 19 - 8
src/renderer/Is.cpp

@@ -235,8 +235,8 @@ Error Is::initInternal(const ConfigSet& config)
 	StringAuto pps(getAllocator());
 
 	pps.sprintf(
-		"\n#define TILES_X_COUNT %u\n"
-		"#define TILES_Y_COUNT %u\n"
+		"\n#define TILES_COUNT_X %u\n"
+		"#define TILES_COUNT_Y %u\n"
 		"#define CLUSTER_COUNT %u\n"
 		"#define RENDERER_WIDTH %u\n"
 		"#define RENDERER_HEIGHT %u\n"
@@ -298,6 +298,11 @@ Error Is::initInternal(const ConfigSet& config)
 
 	for(U i = 0; i < m_pLightsBuffs.getSize(); ++i)
 	{
+		// Common variables
+		m_commonVarsBuffs[i] = getGrManager().newInstance<Buffer>(
+			sizeof(ShaderCommonUniforms), BufferUsageBit::STORAGE,
+			BufferAccessBit::CLIENT_MAP_WRITE);
+
 		// Point lights
 		m_pLightsBuffs[i] = getGrManager().newInstance<Buffer>(
 			m_pLightsBuffSize, BufferUsageBit::STORAGE,
@@ -332,10 +337,11 @@ Error Is::initInternal(const ConfigSet& config)
 		init.m_textures[4].m_texture = m_sm.getSpotTextureArray();
 		init.m_textures[5].m_texture = m_sm.getOmniTextureArray();
 
-		init.m_storageBuffers[0].m_buffer = m_pLightsBuffs[i];
-		init.m_storageBuffers[1].m_buffer = m_sLightsBuffs[i];
-		init.m_storageBuffers[2].m_buffer = m_clusterBuffers[i];
-		init.m_storageBuffers[3].m_buffer = m_lightIdsBuffers[i];
+		init.m_storageBuffers[0].m_buffer = m_commonVarsBuffs[i];
+		init.m_storageBuffers[1].m_buffer = m_pLightsBuffs[i];
+		init.m_storageBuffers[2].m_buffer = m_sLightsBuffs[i];
+		init.m_storageBuffers[3].m_buffer = m_clusterBuffers[i];
+		init.m_storageBuffers[4].m_buffer = m_lightIdsBuffers[i];
 
 		m_rcGroups[i] = getGrManager().newInstance<ResourceGroup>(init);
 	}
@@ -786,8 +792,11 @@ Error Is::run(CommandBufferPtr& cmdBuff)
 //==============================================================================
 void Is::updateCommonBlock(CommandBufferPtr& cmdb, FrustumComponent& fr)
 {
-	ShaderCommonUniforms* blk;
-	cmdb->updateDynamicUniforms(sizeof(*blk), blk);
+	ShaderCommonUniforms* blk =
+		static_cast<ShaderCommonUniforms*>(
+			m_commonVarsBuffs[m_currentFrame]->map(
+			0, sizeof(ShaderCommonUniforms),
+			BufferAccessBit::CLIENT_MAP_WRITE));
 
 	// Start writing
 	blk->m_projectionParams = m_r->getProjectionParameters();
@@ -802,6 +811,8 @@ void Is::updateCommonBlock(CommandBufferPtr& cmdb, FrustumComponent& fr)
 			m_cam->getComponent<FrustumComponent>().getViewMatrix();
 		blk->m_groundLightDir = Vec4(-viewMat.getColumn(1).xyz(), 1.0);
 	}
+
+	m_commonVarsBuffs[m_currentFrame]->unmap();
 }
 
 } // end namespace anki

+ 2 - 10
src/resource/Material.cpp

@@ -46,16 +46,8 @@ Error UpdateTexturesVisitor
 	::visit<MaterialVariableTemplate<TextureResourcePtr>>(
 	const MaterialVariableTemplate<TextureResourcePtr>& var)
 {
-	if(var.getName() == "uMsDepthMap")
-	{
-		m_init->m_textures[var.getTextureUnit()].m_texture =
-			m_manager->getRenderer().getMs().getDepthRt();
-	}
-	else
-	{
-		m_init->m_textures[var.getTextureUnit()].m_texture =
-			(*var.begin())->getGrTexture();
-	}
+	m_init->m_textures[var.getTextureUnit()].m_texture =
+		(*var.begin())->getGrTexture();
 	return ErrorCode::NONE;
 }
 

+ 8 - 6
src/resource/MaterialProgramCreator.cpp

@@ -605,7 +605,7 @@ Error MaterialProgramCreator::parseOperationTag(
 	CString cstr;
 	XmlElement el;
 
-	static const char OUT[] = "out";
+	static const char* OUT = "out";
 
 	CString funcName;
 	StringListAuto argsList(m_alloc);
@@ -653,12 +653,14 @@ Error MaterialProgramCreator::parseOperationTag(
 				}
 			}
 
-			// The argument should be an input variable or an outXX
-			if(!(input != nullptr
-				|| std::memcmp(&arg[0], OUT, 3) == 0))
+			// The argument should be an input variable or an outXX or global
+			if(input == nullptr)
 			{
-				ANKI_LOGE("Incorrect argument: %s", &arg[0]);
-				return ErrorCode::USER_DATA;
+				if(arg.find(OUT) != 0 && arg.find("anki_") != 0)
+				{
+					ANKI_LOGE("Incorrect argument: %s", &arg[0]);
+					return ErrorCode::USER_DATA;
+				}
 			}
 
 			// Add to a list and do something special if instanced

+ 0 - 4
src/scene/ParticleEmitter.cpp

@@ -72,10 +72,6 @@ void ParticleSimple::simulate(const ParticleEmitter& pe,
 {
 	F32 dt = crntTime - prevUpdateTime;
 
-	ANKI_ASSERT(
-		static_cast<const ParticleEmitterProperties&>(pe).
-		m_particle.m_gravity.getLength() > 0.0);
-
 	Vec4 xp = m_position;
 	Vec4 xc = m_acceleration * (dt * dt) + m_velocity * dt + xp;