Browse Source

Move decals to its own pass

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
aaad5caa4f

+ 88 - 3
programs/GBufferPost.ankiprog

@@ -9,8 +9,6 @@ http://www.anki3d.org/LICENSE
 		<input name="CLUSTER_COUNT_X" type="uint" const="1"/>
 		<input name="CLUSTER_COUNT_X" type="uint" const="1"/>
 		<input name="CLUSTER_COUNT_Y" type="uint" const="1"/>
 		<input name="CLUSTER_COUNT_Y" type="uint" const="1"/>
 		<input name="CLUSTER_COUNT_Z" type="uint" const="1"/>
 		<input name="CLUSTER_COUNT_Z" type="uint" const="1"/>
-		<input name="CLUSTER_COUNT" type="uint" const="1"/>
-		<input name="IR_MIPMAP_COUNT" type="uint" const="1"/>
 	</inputs>
 	</inputs>
 
 
 	<shaders>
 	<shaders>
@@ -39,12 +37,99 @@ void main()
 
 
 		<shader type="frag">
 		<shader type="frag">
 			<source><![CDATA[
 			<source><![CDATA[
+#include "shaders/Pack.glsl"
+#include "shaders/Clusterer.glsl"
+#include "shaders/Functions.glsl"
 
 
-// TODO
+#define LIGHT_SET 0
+#define LIGHT_SS_BINDING 0
+#define LIGHT_UBO_BINDING 0
+#define LIGHT_TEX_BINDING 2
+#define LIGHT_DECALS
+#define LIGHT_COMMON_UNIS
+#include "shaders/ClusterLightCommon.glsl"
+
+layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_msDepthRt;
+layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_ssaoTex;
+
+layout(location = 0) in vec2 in_uv;
+layout(location = 1) in vec2 in_clusterIJ;
+
+layout(location = 0) out vec4 out_color0;
+layout(location = 1) out vec4 out_color1;
 
 
 void main()
 void main()
 {
 {
+	// This code blends the diffuse and the specular+rougness of the decals with GBuffer render targets.
+	// Normaly the blending is being done ('D' is the decal diffuse and 'f' is decal blend factor):
+	// d=gbuffer.diff
+	// 1st decal: d'=d*(1-f)+D*f
+	// 2nd decal: d''=d'*(1-f')+D'*f' <=> d''=d*(1-f)*(1-f')+D*f*(1-f')+D'*f'
+	// By looking at the trend we will have to multiply the gbuffer.diff with: (1-f)*(1-f') ... (1-f'''')
+
+	vec4 outDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
+	vec4 outSpecular = vec4(0.0, 0.0, 0.0, 1.0);
+
+	// Sample SSAO
+	float ssao = textureLod(u_ssaoTex, in_uv, 0.0).r;
+	outDiffuse.a *= ssao;
+
+	// Get worldPos
+	float depth = textureLod(u_msDepthRt, in_uv, 0.0).r;
+	vec2 ndc = UV_TO_NDC(in_uv);
+	vec4 worldPos4 = u_invViewProjMat * vec4(ndc, depth, 1.0);
+	vec3 worldPos = worldPos4.xyz / worldPos4.w;
+
+	// Get first light index
+	uint idxOffset;
+	{
+		uint k = computeClusterK(u_clustererMagic, worldPos);
+		uint clusterIdx = 
+			k * (CLUSTER_COUNT_X * CLUSTER_COUNT_Y) + uint(in_clusterIJ.y) * CLUSTER_COUNT_X + uint(in_clusterIJ.x);
+
+		idxOffset = u_clusters[clusterIdx];
+	}
+
+	// Process decals
+	uint count = u_lightIndices[idxOffset++];
+	while(count-- != 0)
+	{
+		Decal decal = u_decals[u_lightIndices[idxOffset++]];
+
+		// Project pos to decal space
+		vec4 texCoords4 = decal.texProjectionMat * vec4(worldPos, 1.0);
+		if(texCoords4.w <= 0.7)
+		{
+			// Behind the decal, skip
+			continue;
+		}
+
+		vec2 texCoords2 = texCoords4.xy / texCoords4.w;
+
+		// Clamp the tex coords. Expect a border in the texture atlas
+		texCoords2 = saturate(texCoords2);
+	
+		// Read diffuse
+		vec2 diffUv = mad(texCoords2, decal.diffUv.zw, decal.diffUv.xy);
+		vec4 decalDiff = texture(u_diffDecalTex, diffUv);
+
+		// Read roughness
+		vec2 specUv = mad(texCoords2, decal.normRoughnessUv.zw, decal.normRoughnessUv.xy);
+		vec3 spec = texture(u_specularRoughnessDecalTex, specUv).rgb;
+
+		// Update diffuse
+		float f = decalDiff.a * decal.blendFactors[0];
+		outDiffuse.rgb = outDiffuse.rgb * (1.0 - f) + decalDiff.rgb * f;
+		outDiffuse.a *= (1.0 - f);
+
+		// Update specular
+		f = decalDiff.a * decal.blendFactors[1];
+		outSpecular.rgb = outSpecular.rgb * (1.0 - f) + spec.rgb * f;
+		outSpecular.a *= (1.0 - f);
+	}
 
 
+	out_color0 = outDiffuse;
+	out_color1 = outSpecular;
 }
 }
 			]]></source>
 			]]></source>
 		</shader>
 		</shader>

+ 7 - 38
programs/LightShading.ankiprog

@@ -46,19 +46,16 @@ void main()
 #define LIGHT_SET 0
 #define LIGHT_SET 0
 #define LIGHT_SS_BINDING 0
 #define LIGHT_SS_BINDING 0
 #define LIGHT_UBO_BINDING 0
 #define LIGHT_UBO_BINDING 0
-#define LIGHT_TEX_BINDING 0
+#define LIGHT_TEX_BINDING 4
 #define LIGHT_LIGHTS
 #define LIGHT_LIGHTS
 #define LIGHT_INDIRECT
 #define LIGHT_INDIRECT
-#define LIGHT_DECALS
 #define LIGHT_COMMON_UNIS
 #define LIGHT_COMMON_UNIS
 #include "shaders/ClusterLightCommon.glsl"
 #include "shaders/ClusterLightCommon.glsl"
 
 
-layout(ANKI_TEX_BINDING(1, 0)) uniform sampler2D u_msRt0;
-layout(ANKI_TEX_BINDING(1, 1)) uniform sampler2D u_msRt1;
-layout(ANKI_TEX_BINDING(1, 2)) uniform sampler2D u_msRt2;
-layout(ANKI_TEX_BINDING(1, 3)) uniform sampler2D u_msDepthRt;
-
-layout(ANKI_TEX_BINDING(1, 4)) uniform sampler2D u_ssaoTex;
+layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_msRt0;
+layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_msRt1;
+layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2D u_msRt2;
+layout(ANKI_TEX_BINDING(0, 3)) uniform sampler2D u_msDepthRt;
 
 
 layout(location = 0) in vec2 in_uv;
 layout(location = 0) in vec2 in_uv;
 layout(location = 1) in vec2 in_clusterIJ;
 layout(location = 1) in vec2 in_clusterIJ;
@@ -77,25 +74,6 @@ const float SUBSURFACE_MIN = 0.05;
 	float att = computeAttenuationFactor(light.posRadius.w, frag2Light); \
 	float att = computeAttenuationFactor(light.posRadius.w, frag2Light); \
 	float lambert = nol;
 	float lambert = nol;
 
 
-// Compute the colors of a decal.
-void appendDecalColors(in Decal decal, in vec3 worldPos, inout vec3 diffuseColor, inout float roughness)
-{
-	vec4 texCoords4 = decal.texProjectionMat * vec4(worldPos, 1.0);
-	vec2 texCoords2 = texCoords4.xy / texCoords4.w;
-
-	// Clamp the tex coords. Expect a border in the texture atlas
-	texCoords2 = saturate(texCoords2);
-
-	vec2 diffUv = mad(texCoords2, decal.diffUv.zw, decal.diffUv.xy);
-	vec4 dcol = texture(u_diffDecalTex, diffUv);
-	diffuseColor = mix(diffuseColor, dcol.rgb, dcol.a * decal.blendFactors[0]);
-
-	// Roughness
-	vec2 roughnessUv = mad(texCoords2, decal.normRoughnessUv.zw, decal.normRoughnessUv.xy);
-	float r = texture(u_normalRoughnessDecalTex, roughnessUv).w;
-	roughness = mix(roughness, r, dcol.a * decal.blendFactors[1]);
-}
-
 void readIndirect(uint idxOffset, vec3 pos, vec3 r, vec3 n, float lod, out vec3 specIndirect, out vec3 diffIndirect)
 void readIndirect(uint idxOffset, vec3 pos, vec3 r, vec3 n, float lod, out vec3 specIndirect, out vec3 diffIndirect)
 {
 {
 	specIndirect = vec3(0.0);
 	specIndirect = vec3(0.0);
@@ -172,18 +150,9 @@ void main()
 		idxOffset = u_clusters[clusterIdx];
 		idxOffset = u_clusters[clusterIdx];
 	}
 	}
 
 
-	// Decals
+	// Skip decals
 	uint count = u_lightIndices[idxOffset++];
 	uint count = u_lightIndices[idxOffset++];
-	while(count-- != 0)
-	{
-		Decal decal = u_decals[u_lightIndices[idxOffset++]];
-
-		appendDecalColors(decal, worldPos, diffCol, roughness);
-	}
-
-	// Apply SSAO
-	float ssao = textureLod(u_ssaoTex, in_uv, 0.0).r;
-	diffCol *= ssao;
+	idxOffset += count;
 
 
 	// Ambient and emissive color
 	// Ambient and emissive color
 	vec3 outC = diffCol * emission;
 	vec3 outC = diffCol * emission;

+ 1 - 1
shaders/ClusterLightCommon.glsl

@@ -158,7 +158,7 @@ layout(std140, row_major, ANKI_UBO_BINDING(LIGHT_SET, _NEXT_UBO_BINDING_3)) unif
 };
 };
 
 
 layout(ANKI_TEX_BINDING(LIGHT_SET, _NEXT_TEX_BINDING_3 + 0)) uniform sampler2D u_diffDecalTex;
 layout(ANKI_TEX_BINDING(LIGHT_SET, _NEXT_TEX_BINDING_3 + 0)) uniform sampler2D u_diffDecalTex;
-layout(ANKI_TEX_BINDING(LIGHT_SET, _NEXT_TEX_BINDING_3 + 1)) uniform sampler2D u_normalRoughnessDecalTex;
+layout(ANKI_TEX_BINDING(LIGHT_SET, _NEXT_TEX_BINDING_3 + 1)) uniform sampler2D u_specularRoughnessDecalTex;
 #endif
 #endif
 
 
 //
 //

+ 2 - 2
src/anki/gr/CommandBuffer.h

@@ -204,8 +204,8 @@ public:
 	void setColorChannelWriteMask(U32 attachment, ColorBit mask);
 	void setColorChannelWriteMask(U32 attachment, ColorBit mask);
 
 
 	/// Set blend factors seperate.
 	/// Set blend factors seperate.
-	/// By default the values of srcRgb, dstRgb, srcA and dstA are BlendFactor::ONE, BlendFactor::ONE,
-	/// BlendFactor::ZERO, BlendFactor::ZERO respectively.
+	/// By default the values of srcRgb, dstRgb, srcA and dstA are BlendFactor::ONE, BlendFactor::ZERO,
+	/// BlendFactor::ONE, BlendFactor::ZERO respectively.
 	void setBlendFactors(U32 attachment, BlendFactor srcRgb, BlendFactor dstRgb, BlendFactor srcA, BlendFactor dstA);
 	void setBlendFactors(U32 attachment, BlendFactor srcRgb, BlendFactor dstRgb, BlendFactor srcA, BlendFactor dstA);
 
 
 	/// Set blend factors.
 	/// Set blend factors.

+ 1 - 0
src/anki/renderer/Common.h

@@ -20,6 +20,7 @@ namespace anki
 // Forward
 // Forward
 class Renderer;
 class Renderer;
 class GBuffer;
 class GBuffer;
+class GBufferPost;
 class ShadowMapping;
 class ShadowMapping;
 class LightShading;
 class LightShading;
 class ForwardShading;
 class ForwardShading;

+ 40 - 2
src/anki/renderer/GBufferPost.cpp

@@ -7,6 +7,7 @@
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/GBuffer.h>
 #include <anki/renderer/GBuffer.h>
 #include <anki/renderer/Ssao.h>
 #include <anki/renderer/Ssao.h>
+#include <anki/renderer/LightShading.h>
 #include <anki/misc/ConfigSet.h>
 #include <anki/misc/ConfigSet.h>
 
 
 namespace anki
 namespace anki
@@ -76,9 +77,46 @@ void GBufferPost::populateRenderGraph(RenderingContext& ctx)
 
 
 void GBufferPost::run(RenderPassWorkContext& rgraphCtx)
 void GBufferPost::run(RenderPassWorkContext& rgraphCtx)
 {
 {
+	const LightShadingResources& rsrc = m_r->getLightShading().getResources();
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
 
-	// TODO
+	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
+	cmdb->bindShaderProgram(m_grProg);
+
+	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA, BlendFactor::ZERO, BlendFactor::ONE);
+	cmdb->setBlendFactors(1, BlendFactor::ONE, BlendFactor::SRC_ALPHA, BlendFactor::ZERO, BlendFactor::ONE);
+
+	// Bind textures
+	rgraphCtx.bindTextureAndSampler(0,
+		0,
+		m_r->getGBuffer().getDepthRt(),
+		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
+		m_r->getNearestSampler());
+	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getSsao().getRt(), m_r->getLinearSampler());
+	cmdb->bindTextureAndSampler(0,
+		2,
+		(rsrc.m_diffDecalTexView) ? rsrc.m_diffDecalTexView : m_r->getDummyTextureView(),
+		m_r->getTrilinearRepeatSampler(),
+		TextureUsageBit::SAMPLED_FRAGMENT);
+	cmdb->bindTextureAndSampler(0,
+		3,
+		(rsrc.m_specularRoughnessDecalTexView) ? rsrc.m_specularRoughnessDecalTexView : m_r->getDummyTextureView(),
+		m_r->getTrilinearRepeatSampler(),
+		TextureUsageBit::SAMPLED_FRAGMENT);
+
+	// Uniforms
+	bindUniforms(cmdb, 0, 0, rsrc.m_commonUniformsToken);
+	bindUniforms(cmdb, 0, 1, rsrc.m_decalsToken);
+
+	// Storage
+	bindStorage(cmdb, 0, 0, rsrc.m_clustersToken);
+	bindStorage(cmdb, 0, 1, rsrc.m_lightIndicesToken);
+
+	cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
+
+	// Restore state
+	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
+	cmdb->setBlendFactors(1, BlendFactor::ONE, BlendFactor::ZERO);
 }
 }
 
 
-} // end namespace anki
+} // end namespace anki

+ 9 - 9
src/anki/renderer/LightBin.cpp

@@ -320,8 +320,8 @@ public:
 
 
 	TextureViewPtr m_diffDecalTexAtlas;
 	TextureViewPtr m_diffDecalTexAtlas;
 	SpinLock m_diffDecalTexAtlasMtx;
 	SpinLock m_diffDecalTexAtlasMtx;
-	TextureViewPtr m_normalRoughnessDecalTexAtlas;
-	SpinLock m_normalRoughnessDecalTexAtlasMtx;
+	TextureViewPtr m_specularRoughnessDecalTexAtlas;
+	SpinLock m_specularRoughnessDecalTexAtlasMtx;
 
 
 	LightBin* m_bin = nullptr;
 	LightBin* m_bin = nullptr;
 };
 };
@@ -494,7 +494,7 @@ Error LightBin::bin(const Mat4& viewMat,
 	ANKI_CHECK(m_threadPool->waitForAllThreadsToFinish());
 	ANKI_CHECK(m_threadPool->waitForAllThreadsToFinish());
 
 
 	out.m_diffDecalTexView = ctx.m_diffDecalTexAtlas;
 	out.m_diffDecalTexView = ctx.m_diffDecalTexAtlas;
-	out.m_normRoughnessDecalTexView = ctx.m_normalRoughnessDecalTexAtlas;
+	out.m_specularRoughnessDecalTexView = ctx.m_specularRoughnessDecalTexAtlas;
 
 
 	return Error::NONE;
 	return Error::NONE;
 }
 }
@@ -807,20 +807,20 @@ void LightBin::writeAndBinDecal(const DecalQueueElement& decalEl, LightBinContex
 		ctx.m_diffDecalTexAtlas = atlas;
 		ctx.m_diffDecalTexAtlas = atlas;
 	}
 	}
 
 
-	atlas.reset(const_cast<TextureView*>(decalEl.m_normalRoughnessAtlas));
-	uv = decalEl.m_normalRoughnessAtlasUv;
+	atlas.reset(const_cast<TextureView*>(decalEl.m_specularRoughnessAtlas));
+	uv = decalEl.m_specularRoughnessAtlasUv;
 	decal.m_normRoughnessUv = Vec4(uv.x(), uv.y(), uv.z() - uv.x(), uv.w() - uv.y());
 	decal.m_normRoughnessUv = Vec4(uv.x(), uv.y(), uv.z() - uv.x(), uv.w() - uv.y());
-	decal.m_blendFactors[1] = decalEl.m_normalRoughnessAtlasBlendFactor;
+	decal.m_blendFactors[1] = decalEl.m_specularRoughnessAtlasBlendFactor;
 
 
 	if(atlas)
 	if(atlas)
 	{
 	{
-		LockGuard<SpinLock> lock(ctx.m_normalRoughnessDecalTexAtlasMtx);
-		if(ctx.m_normalRoughnessDecalTexAtlas && ctx.m_normalRoughnessDecalTexAtlas != atlas)
+		LockGuard<SpinLock> lock(ctx.m_specularRoughnessDecalTexAtlasMtx);
+		if(ctx.m_specularRoughnessDecalTexAtlas && ctx.m_specularRoughnessDecalTexAtlas != atlas)
 		{
 		{
 			ANKI_R_LOGF("All decals should have the same tex atlas");
 			ANKI_R_LOGF("All decals should have the same tex atlas");
 		}
 		}
 
 
-		ctx.m_normalRoughnessDecalTexAtlas = atlas;
+		ctx.m_specularRoughnessDecalTexAtlas = atlas;
 	}
 	}
 
 
 	// bias * proj_l * view_
 	// bias * proj_l * view_

+ 1 - 1
src/anki/renderer/LightBin.h

@@ -28,7 +28,7 @@ public:
 	StagingGpuMemoryToken m_lightIndicesToken;
 	StagingGpuMemoryToken m_lightIndicesToken;
 
 
 	TextureViewPtr m_diffDecalTexView;
 	TextureViewPtr m_diffDecalTexView;
-	TextureViewPtr m_normRoughnessDecalTexView;
+	TextureViewPtr m_specularRoughnessDecalTexView;
 };
 };
 
 
 /// Bins lights and probes to clusters.
 /// Bins lights and probes to clusters.

+ 11 - 22
src/anki/renderer/LightShading.cpp

@@ -6,7 +6,6 @@
 #include <anki/renderer/LightShading.h>
 #include <anki/renderer/LightShading.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/Renderer.h>
 #include <anki/renderer/ShadowMapping.h>
 #include <anki/renderer/ShadowMapping.h>
-#include <anki/renderer/Ssao.h>
 #include <anki/renderer/Indirect.h>
 #include <anki/renderer/Indirect.h>
 #include <anki/renderer/GBuffer.h>
 #include <anki/renderer/GBuffer.h>
 #include <anki/renderer/LightBin.h>
 #include <anki/renderer/LightBin.h>
@@ -139,41 +138,32 @@ void LightShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgrap
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	cmdb->bindShaderProgram(m_progVariant->getProgram());
 	cmdb->bindShaderProgram(m_progVariant->getProgram());
 
 
-	rgraphCtx.bindColorTextureAndSampler(1, 0, m_r->getGBuffer().getColorRt(0), m_r->getNearestSampler());
-	rgraphCtx.bindColorTextureAndSampler(1, 1, m_r->getGBuffer().getColorRt(1), m_r->getNearestSampler());
-	rgraphCtx.bindColorTextureAndSampler(1, 2, m_r->getGBuffer().getColorRt(2), m_r->getNearestSampler());
-	rgraphCtx.bindTextureAndSampler(1,
+	// Bind textures
+	rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getGBuffer().getColorRt(0), m_r->getNearestSampler());
+	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getGBuffer().getColorRt(1), m_r->getNearestSampler());
+	rgraphCtx.bindColorTextureAndSampler(0, 2, m_r->getGBuffer().getColorRt(2), m_r->getNearestSampler());
+	rgraphCtx.bindTextureAndSampler(0,
 		3,
 		3,
 		m_r->getGBuffer().getDepthRt(),
 		m_r->getGBuffer().getDepthRt(),
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
 		m_r->getNearestSampler());
 		m_r->getNearestSampler());
-	rgraphCtx.bindColorTextureAndSampler(1, 4, m_r->getSsao().getRt(), m_r->getLinearSampler());
 
 
-	rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getShadowMapping().getShadowmapRt(), m_r->getLinearSampler());
-	rgraphCtx.bindColorTextureAndSampler(0, 1, m_r->getIndirect().getReflectionRt(), m_r->getTrilinearRepeatSampler());
-	rgraphCtx.bindColorTextureAndSampler(0, 2, m_r->getIndirect().getIrradianceRt(), m_r->getLinearSampler());
+	rgraphCtx.bindColorTextureAndSampler(0, 4, m_r->getShadowMapping().getShadowmapRt(), m_r->getLinearSampler());
+	rgraphCtx.bindColorTextureAndSampler(0, 5, m_r->getIndirect().getReflectionRt(), m_r->getTrilinearRepeatSampler());
+	rgraphCtx.bindColorTextureAndSampler(0, 6, m_r->getIndirect().getIrradianceRt(), m_r->getLinearSampler());
 	cmdb->bindTextureAndSampler(0,
 	cmdb->bindTextureAndSampler(0,
-		3,
+		7,
 		m_r->getIndirect().getIntegrationLut(),
 		m_r->getIndirect().getIntegrationLut(),
 		m_r->getIndirect().getIntegrationLutSampler(),
 		m_r->getIndirect().getIntegrationLutSampler(),
 		TextureUsageBit::SAMPLED_FRAGMENT);
 		TextureUsageBit::SAMPLED_FRAGMENT);
-	cmdb->bindTextureAndSampler(0,
-		4,
-		(rsrc.m_diffDecalTexView) ? rsrc.m_diffDecalTexView : m_r->getDummyTextureView(),
-		m_r->getTrilinearRepeatSampler(),
-		TextureUsageBit::SAMPLED_FRAGMENT);
-	cmdb->bindTextureAndSampler(0,
-		5,
-		(rsrc.m_normRoughnessDecalTexView) ? rsrc.m_normRoughnessDecalTexView : m_r->getDummyTextureView(),
-		m_r->getTrilinearRepeatSampler(),
-		TextureUsageBit::SAMPLED_FRAGMENT);
 
 
+	// Bind uniforms
 	bindUniforms(cmdb, 0, 0, rsrc.m_commonUniformsToken);
 	bindUniforms(cmdb, 0, 0, rsrc.m_commonUniformsToken);
 	bindUniforms(cmdb, 0, 1, rsrc.m_pointLightsToken);
 	bindUniforms(cmdb, 0, 1, rsrc.m_pointLightsToken);
 	bindUniforms(cmdb, 0, 2, rsrc.m_spotLightsToken);
 	bindUniforms(cmdb, 0, 2, rsrc.m_spotLightsToken);
 	bindUniforms(cmdb, 0, 3, rsrc.m_probesToken);
 	bindUniforms(cmdb, 0, 3, rsrc.m_probesToken);
-	bindUniforms(cmdb, 0, 4, rsrc.m_decalsToken);
 
 
+	// Bind storage
 	bindStorage(cmdb, 0, 0, rsrc.m_clustersToken);
 	bindStorage(cmdb, 0, 0, rsrc.m_clustersToken);
 	bindStorage(cmdb, 0, 1, rsrc.m_lightIndicesToken);
 	bindStorage(cmdb, 0, 1, rsrc.m_lightIndicesToken);
 
 
@@ -237,7 +227,6 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	pass.newConsumer({m_r->getGBuffer().getDepthRt(),
 	pass.newConsumer({m_r->getGBuffer().getDepthRt(),
 		TextureUsageBit::SAMPLED_FRAGMENT,
 		TextureUsageBit::SAMPLED_FRAGMENT,
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
-	pass.newConsumer({m_r->getSsao().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newConsumer({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newConsumer({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newConsumer({m_r->getIndirect().getReflectionRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newConsumer({m_r->getIndirect().getReflectionRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newConsumer({m_r->getIndirect().getIrradianceRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newConsumer({m_r->getIndirect().getIrradianceRt(), TextureUsageBit::SAMPLED_FRAGMENT});

+ 3 - 3
src/anki/renderer/RenderQueue.h

@@ -145,11 +145,11 @@ public:
 	/// Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
 	/// Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
 	const TextureView* m_diffuseAtlas;
 	const TextureView* m_diffuseAtlas;
 	/// Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
 	/// Totaly unsafe but we can't have a smart ptr in here since there will be no deletion.
-	const TextureView* m_normalRoughnessAtlas;
+	const TextureView* m_specularRoughnessAtlas;
 	Vec4 m_diffuseAtlasUv;
 	Vec4 m_diffuseAtlasUv;
-	Vec4 m_normalRoughnessAtlasUv;
+	Vec4 m_specularRoughnessAtlasUv;
 	F32 m_diffuseAtlasBlendFactor;
 	F32 m_diffuseAtlasBlendFactor;
-	F32 m_normalRoughnessAtlasBlendFactor;
+	F32 m_specularRoughnessAtlasBlendFactor;
 	Mat4 m_textureMatrix;
 	Mat4 m_textureMatrix;
 	Vec3 m_obbCenter;
 	Vec3 m_obbCenter;
 	Vec3 m_obbExtend;
 	Vec3 m_obbExtend;

+ 5 - 0
src/anki/renderer/Renderer.cpp

@@ -11,6 +11,7 @@
 
 
 #include <anki/renderer/Indirect.h>
 #include <anki/renderer/Indirect.h>
 #include <anki/renderer/GBuffer.h>
 #include <anki/renderer/GBuffer.h>
+#include <anki/renderer/GBufferPost.h>
 #include <anki/renderer/LightShading.h>
 #include <anki/renderer/LightShading.h>
 #include <anki/renderer/ShadowMapping.h>
 #include <anki/renderer/ShadowMapping.h>
 #include <anki/renderer/FinalComposite.h>
 #include <anki/renderer/FinalComposite.h>
@@ -112,6 +113,9 @@ Error Renderer::initInternal(const ConfigSet& config)
 	m_gbuffer.reset(m_alloc.newInstance<GBuffer>(this));
 	m_gbuffer.reset(m_alloc.newInstance<GBuffer>(this));
 	ANKI_CHECK(m_gbuffer->init(config));
 	ANKI_CHECK(m_gbuffer->init(config));
 
 
+	m_gbufferPost.reset(m_alloc.newInstance<GBufferPost>(this));
+	ANKI_CHECK(m_gbufferPost->init(config));
+
 	m_shadowMapping.reset(m_alloc.newInstance<ShadowMapping>(this));
 	m_shadowMapping.reset(m_alloc.newInstance<ShadowMapping>(this));
 	ANKI_CHECK(m_shadowMapping->init(config));
 	ANKI_CHECK(m_shadowMapping->init(config));
 
 
@@ -269,6 +273,7 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	m_refl->populateRenderGraph(ctx);
 	m_refl->populateRenderGraph(ctx);
 	m_vol->populateRenderGraph(ctx);
 	m_vol->populateRenderGraph(ctx);
 	m_ssao->populateRenderGraph(ctx);
 	m_ssao->populateRenderGraph(ctx);
+	m_gbufferPost->populateRenderGraph(ctx);
 	m_lensFlare->populateRenderGraph(ctx);
 	m_lensFlare->populateRenderGraph(ctx);
 	m_forwardShading->populateRenderGraph(ctx);
 	m_forwardShading->populateRenderGraph(ctx);
 	m_lightShading->populateRenderGraph(ctx);
 	m_lightShading->populateRenderGraph(ctx);

+ 1 - 0
src/anki/renderer/Renderer.h

@@ -353,6 +353,7 @@ private:
 	UniquePtr<Indirect> m_indirect;
 	UniquePtr<Indirect> m_indirect;
 	UniquePtr<ShadowMapping> m_shadowMapping; ///< Shadow mapping.
 	UniquePtr<ShadowMapping> m_shadowMapping; ///< Shadow mapping.
 	UniquePtr<GBuffer> m_gbuffer; ///< Material rendering stage
 	UniquePtr<GBuffer> m_gbuffer; ///< Material rendering stage
+	UniquePtr<GBufferPost> m_gbufferPost;
 	UniquePtr<Reflections> m_refl;
 	UniquePtr<Reflections> m_refl;
 	UniquePtr<LightShading> m_lightShading; ///< Illumination rendering stage
 	UniquePtr<LightShading> m_lightShading; ///< Illumination rendering stage
 	UniquePtr<DepthDownscale> m_depth;
 	UniquePtr<DepthDownscale> m_depth;

+ 13 - 13
src/anki/scene/components/DecalComponent.h

@@ -34,9 +34,9 @@ public:
 		return setLayer(texAtlasFname, texAtlasSubtexName, blendFactor, LayerType::DIFFUSE);
 		return setLayer(texAtlasFname, texAtlasSubtexName, blendFactor, LayerType::DIFFUSE);
 	}
 	}
 
 
-	ANKI_USE_RESULT Error setNormalRoughnessDecal(CString texAtlasFname, CString texAtlasSubtexName, F32 blendFactor)
+	ANKI_USE_RESULT Error setSpecularRoughnessDecal(CString texAtlasFname, CString texAtlasSubtexName, F32 blendFactor)
 	{
 	{
-		return setLayer(texAtlasFname, texAtlasSubtexName, blendFactor, LayerType::NORMAL_ROUGHNESS);
+		return setLayer(texAtlasFname, texAtlasSubtexName, blendFactor, LayerType::SPECULAR_ROUGHNESS);
 	}
 	}
 
 
 	/// Update the internal structures.
 	/// Update the internal structures.
@@ -99,18 +99,18 @@ public:
 		blendFactor = m_layers[LayerType::DIFFUSE].m_blendFactor;
 		blendFactor = m_layers[LayerType::DIFFUSE].m_blendFactor;
 	}
 	}
 
 
-	void getNormalRoughnessAtlasInfo(Vec4& uv, TexturePtr& tex, F32& blendFactor) const
+	void getSpecularRoughnessAtlasInfo(Vec4& uv, TexturePtr& tex, F32& blendFactor) const
 	{
 	{
-		uv = m_layers[LayerType::NORMAL_ROUGHNESS].m_uv;
-		if(m_layers[LayerType::NORMAL_ROUGHNESS].m_atlas)
+		uv = m_layers[LayerType::SPECULAR_ROUGHNESS].m_uv;
+		if(m_layers[LayerType::SPECULAR_ROUGHNESS].m_atlas)
 		{
 		{
-			tex = m_layers[LayerType::NORMAL_ROUGHNESS].m_atlas->getGrTexture();
+			tex = m_layers[LayerType::SPECULAR_ROUGHNESS].m_atlas->getGrTexture();
 		}
 		}
 		else
 		else
 		{
 		{
 			tex.reset(nullptr);
 			tex.reset(nullptr);
 		}
 		}
-		blendFactor = m_layers[LayerType::NORMAL_ROUGHNESS].m_blendFactor;
+		blendFactor = m_layers[LayerType::SPECULAR_ROUGHNESS].m_blendFactor;
 	}
 	}
 
 
 	const Vec3& getVolumeSize() const
 	const Vec3& getVolumeSize() const
@@ -123,13 +123,13 @@ public:
 		el.m_diffuseAtlas = (m_layers[LayerType::DIFFUSE].m_atlas)
 		el.m_diffuseAtlas = (m_layers[LayerType::DIFFUSE].m_atlas)
 								? m_layers[LayerType::DIFFUSE].m_atlas->getGrTextureView().get()
 								? m_layers[LayerType::DIFFUSE].m_atlas->getGrTextureView().get()
 								: nullptr;
 								: nullptr;
-		el.m_normalRoughnessAtlas = (m_layers[LayerType::NORMAL_ROUGHNESS].m_atlas)
-										? m_layers[LayerType::NORMAL_ROUGHNESS].m_atlas->getGrTextureView().get()
-										: nullptr;
+		el.m_specularRoughnessAtlas = (m_layers[LayerType::SPECULAR_ROUGHNESS].m_atlas)
+										  ? m_layers[LayerType::SPECULAR_ROUGHNESS].m_atlas->getGrTextureView().get()
+										  : nullptr;
 		el.m_diffuseAtlasUv = m_layers[LayerType::DIFFUSE].m_uv;
 		el.m_diffuseAtlasUv = m_layers[LayerType::DIFFUSE].m_uv;
-		el.m_normalRoughnessAtlasUv = m_layers[LayerType::NORMAL_ROUGHNESS].m_uv;
+		el.m_specularRoughnessAtlasUv = m_layers[LayerType::SPECULAR_ROUGHNESS].m_uv;
 		el.m_diffuseAtlasBlendFactor = m_layers[LayerType::DIFFUSE].m_blendFactor;
 		el.m_diffuseAtlasBlendFactor = m_layers[LayerType::DIFFUSE].m_blendFactor;
-		el.m_normalRoughnessAtlasBlendFactor = m_layers[LayerType::NORMAL_ROUGHNESS].m_blendFactor;
+		el.m_specularRoughnessAtlasBlendFactor = m_layers[LayerType::SPECULAR_ROUGHNESS].m_blendFactor;
 		el.m_textureMatrix = m_biasProjViewMat;
 		el.m_textureMatrix = m_biasProjViewMat;
 		el.m_obbCenter = m_obb.getCenter().xyz();
 		el.m_obbCenter = m_obb.getCenter().xyz();
 		el.m_obbExtend = m_obb.getExtend().xyz();
 		el.m_obbExtend = m_obb.getExtend().xyz();
@@ -142,7 +142,7 @@ private:
 	enum class LayerType
 	enum class LayerType
 	{
 	{
 		DIFFUSE,
 		DIFFUSE,
-		NORMAL_ROUGHNESS,
+		SPECULAR_ROUGHNESS,
 		COUNT
 		COUNT
 	};
 	};
 
 

+ 7 - 7
src/anki/script/Scene.cpp

@@ -1176,8 +1176,8 @@ static int wrapDecalComponentsetDiffuseDecal(lua_State* l)
 	return 0;
 	return 0;
 }
 }
 
 
-/// Pre-wrap method DecalComponent::setNormalRoughnessDecal.
-static inline int pwrapDecalComponentsetNormalRoughnessDecal(lua_State* l)
+/// Pre-wrap method DecalComponent::setSpecularRoughnessDecal.
+static inline int pwrapDecalComponentsetSpecularRoughnessDecal(lua_State* l)
 {
 {
 	LuaUserData* ud;
 	LuaUserData* ud;
 	(void)ud;
 	(void)ud;
@@ -1216,7 +1216,7 @@ static inline int pwrapDecalComponentsetNormalRoughnessDecal(lua_State* l)
 	}
 	}
 
 
 	// Call the method
 	// Call the method
-	Error ret = self->setNormalRoughnessDecal(arg0, arg1, arg2);
+	Error ret = self->setSpecularRoughnessDecal(arg0, arg1, arg2);
 
 
 	// Push return value
 	// Push return value
 	if(ANKI_UNLIKELY(ret))
 	if(ANKI_UNLIKELY(ret))
@@ -1230,10 +1230,10 @@ static inline int pwrapDecalComponentsetNormalRoughnessDecal(lua_State* l)
 	return 1;
 	return 1;
 }
 }
 
 
-/// Wrap method DecalComponent::setNormalRoughnessDecal.
-static int wrapDecalComponentsetNormalRoughnessDecal(lua_State* l)
+/// Wrap method DecalComponent::setSpecularRoughnessDecal.
+static int wrapDecalComponentsetSpecularRoughnessDecal(lua_State* l)
 {
 {
-	int res = pwrapDecalComponentsetNormalRoughnessDecal(l);
+	int res = pwrapDecalComponentsetSpecularRoughnessDecal(l);
 	if(res >= 0)
 	if(res >= 0)
 	{
 	{
 		return res;
 		return res;
@@ -1306,7 +1306,7 @@ static inline void wrapDecalComponent(lua_State* l)
 {
 {
 	LuaBinder::createClass(l, classnameDecalComponent);
 	LuaBinder::createClass(l, classnameDecalComponent);
 	LuaBinder::pushLuaCFuncMethod(l, "setDiffuseDecal", wrapDecalComponentsetDiffuseDecal);
 	LuaBinder::pushLuaCFuncMethod(l, "setDiffuseDecal", wrapDecalComponentsetDiffuseDecal);
-	LuaBinder::pushLuaCFuncMethod(l, "setNormalRoughnessDecal", wrapDecalComponentsetNormalRoughnessDecal);
+	LuaBinder::pushLuaCFuncMethod(l, "setSpecularRoughnessDecal", wrapDecalComponentsetSpecularRoughnessDecal);
 	LuaBinder::pushLuaCFuncMethod(l, "updateShape", wrapDecalComponentupdateShape);
 	LuaBinder::pushLuaCFuncMethod(l, "updateShape", wrapDecalComponentupdateShape);
 	lua_settop(l, 0);
 	lua_settop(l, 0);
 }
 }

+ 1 - 1
src/anki/script/Scene.xml

@@ -147,7 +147,7 @@ static SceneGraph* getSceneGraph(lua_State* l)
 					</args>
 					</args>
 					<return>Error</return>
 					<return>Error</return>
 				</method>
 				</method>
-				<method name="setNormalRoughnessDecal">
+				<method name="setSpecularRoughnessDecal">
 					<args>
 					<args>
 						<arg>CString</arg>
 						<arg>CString</arg>
 						<arg>CString</arg>
 						<arg>CString</arg>

+ 5 - 5
tools/scene/Exporter.cpp

@@ -895,11 +895,11 @@ void Exporter::visitNode(const aiNode* ainode)
 					}
 					}
 					else if(pr.first == "decal_normal_roughness_atlas")
 					else if(pr.first == "decal_normal_roughness_atlas")
 					{
 					{
-						decal.m_normalRoughnessAtlasFilename = pr.second;
+						decal.m_specularRoughnessAtlasFilename = pr.second;
 					}
 					}
 					else if(pr.first == "decal_normal_roughness_sub_texture")
 					else if(pr.first == "decal_normal_roughness_sub_texture")
 					{
 					{
-						decal.m_normalRoughnessSubTextureName = pr.second;
+						decal.m_specularRoughnessSubTextureName = pr.second;
 					}
 					}
 					else if(pr.first == "decal_normal_roughness_factor")
 					else if(pr.first == "decal_normal_roughness_factor")
 					{
 					{
@@ -1116,10 +1116,10 @@ void Exporter::exportAll()
 			 << decal.m_diffuseSubTextureName << "\", " << decal.m_factors[0] << ")\n";
 			 << decal.m_diffuseSubTextureName << "\", " << decal.m_factors[0] << ")\n";
 		file << "decalc:updateShape(" << decal.m_size.x << ", " << decal.m_size.y << ", " << decal.m_size.z << ")\n";
 		file << "decalc:updateShape(" << decal.m_size.x << ", " << decal.m_size.y << ", " << decal.m_size.z << ")\n";
 
 
-		if(!decal.m_normalRoughnessAtlasFilename.empty())
+		if(!decal.m_specularRoughnessAtlasFilename.empty())
 		{
 		{
-			file << "decalc:setNormalRoughnessDecal(\"" << decal.m_normalRoughnessAtlasFilename << "\", \""
-				 << decal.m_normalRoughnessSubTextureName << "\", " << decal.m_factors[1] << ")\n";
+			file << "decalc:setSpecularRoughnessDecal(\"" << decal.m_specularRoughnessAtlasFilename << "\", \""
+				 << decal.m_specularRoughnessSubTextureName << "\", " << decal.m_factors[1] << ")\n";
 		}
 		}
 
 
 		++i;
 		++i;

+ 2 - 2
tools/scene/Exporter.h

@@ -97,8 +97,8 @@ public:
 	aiMatrix4x4 m_transform;
 	aiMatrix4x4 m_transform;
 	std::string m_diffuseTextureAtlasFilename;
 	std::string m_diffuseTextureAtlasFilename;
 	std::string m_diffuseSubTextureName;
 	std::string m_diffuseSubTextureName;
-	std::string m_normalRoughnessAtlasFilename;
-	std::string m_normalRoughnessSubTextureName;
+	std::string m_specularRoughnessAtlasFilename;
+	std::string m_specularRoughnessSubTextureName;
 	aiVector3D m_size;
 	aiVector3D m_size;
 	std::array<float, 2> m_factors = {{1.0, 1.0}};
 	std::array<float, 2> m_factors = {{1.0, 1.0}};
 };
 };