Explorar o código

Move forward shading after light shading

Panagiotis Christopoulos Charitos %!s(int64=7) %!d(string=hai) anos
pai
achega
c0c7a82e00

+ 2 - 2
shaders/ForwardShadingCommonFrag.glsl

@@ -20,13 +20,13 @@ layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D anki_msDepthRt;
 #include <shaders/ClusteredShadingCommon.glsl>
 
 #define anki_u_time u_time
-#define RENDERER_SIZE (u_rendererSize * 0.5)
+#define RENDERER_SIZE (u_rendererSize)
 
 layout(location = 0) out Vec4 out_color;
 
 void writeGBuffer(in Vec4 color)
 {
-	out_color = Vec4(color.rgb, 1.0 - color.a);
+	out_color = Vec4(color.rgb, color.a);
 }
 
 Vec4 readAnimatedTextureRgba(sampler2DArray tex, F32 period, Vec2 uv, F32 time)

+ 0 - 55
shaders/ForwardShadingUpscale.glslp

@@ -1,55 +0,0 @@
-// Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors.
-// All rights reserved.
-// Code licensed under the BSD License.
-// http://www.anki3d.org/LICENSE
-
-#pragma anki input const Vec2 SRC_SIZE
-#pragma anki input const Vec2 FB_SIZE
-#pragma anki input const U32 NOISE_TEX_SIZE
-
-#pragma anki start vert
-#include <shaders/QuadVert.glsl>
-#pragma anki end
-
-#pragma anki start frag
-#include <shaders/Common.glsl>
-#include <shaders/Functions.glsl>
-
-#define EXPENSIVE_PASS 0
-#define BLUE_NOISE 0
-
-layout(location = 0) in Vec2 in_uv;
-
-layout(location = 0) out Vec4 out_color;
-
-layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_depthFullTex;
-layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_depthHalfTex;
-layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2D u_fsRt;
-#if BLUE_NOISE
-layout(ANKI_TEX_BINDING(0, 3)) uniform sampler2DArray u_noiseTex;
-#endif
-
-layout(ANKI_UBO_BINDING(0, 0)) uniform u0_
-{
-	Vec4 u_linearizeCfFarPad1;
-};
-
-void main()
-{
-#if EXPENSIVE_PASS
-	out_color =
-		bilateralUpsample(u_depthFullTex, u_depthHalfTex, u_fsRt, 1.0 / Vec2(SRC_SIZE), in_uv, u_linearizeCfFarPad1.xy);
-#else
-	const F32 thresholdMeters = 5.0 / 100.0; // 5 centimeters
-	F32 threshold = thresholdMeters / u_linearizeCfFarPad1.z;
-	out_color = nearestDepthUpscale(in_uv, u_depthFullTex, u_depthHalfTex, u_fsRt, u_linearizeCfFarPad1.xy, threshold);
-#endif
-
-#if BLUE_NOISE
-	Vec3 blueNoise = texture(u_noiseTex, Vec3(FB_SIZE / Vec2(NOISE_TEX_SIZE) * in_uv, 0.0), 0.0).rgb;
-	blueNoise = blueNoise * 2.0 - 1.0;
-	blueNoise = sign(blueNoise) * (1.0 - sqrt(1.0 - abs(blueNoise)));
-	out_color.rgb += blueNoise / 32.0;
-#endif
-}
-#pragma anki end

+ 14 - 49
src/anki/renderer/ForwardShading.cpp

@@ -35,22 +35,6 @@ Error ForwardShading::init(const ConfigSet& cfg)
 
 Error ForwardShading::initInternal(const ConfigSet&)
 {
-	m_width = m_r->getWidth() / FS_FRACTION;
-	m_height = m_r->getHeight() / FS_FRACTION;
-
-	// Create RT descr
-	m_rtDescr = m_r->create2DRenderTargetDescription(
-		m_width, m_height, FORWARD_SHADING_COLOR_ATTACHMENT_PIXEL_FORMAT, "forward");
-	m_rtDescr.bake();
-
-	// Create FB descr
-	m_fbDescr.m_colorAttachmentCount = 1;
-	m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
-	m_fbDescr.m_colorAttachments[0].m_clearValue.m_colorf = {{0.0, 0.0, 0.0, 1.0}};
-	m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::LOAD;
-	m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH;
-	m_fbDescr.bake();
-
 	ANKI_CHECK(initVol());
 
 	return Error::NONE;
@@ -65,7 +49,7 @@ Error ForwardShading::initVol()
 	ShaderProgramResourceConstantValueInitList<3> consts(m_vol.m_prog);
 	consts.add("NOISE_TEX_SIZE", U32(m_vol.m_noiseTex->getWidth()))
 		.add("SRC_SIZE", Vec2(m_r->getWidth() / VOLUMETRIC_FRACTION, m_r->getHeight() / VOLUMETRIC_FRACTION))
-		.add("FB_SIZE", Vec2(m_width, m_height));
+		.add("FB_SIZE", Vec2(m_r->getWidth(), m_r->getHeight()));
 
 	const ShaderProgramResourceVariant* variant;
 	m_vol.m_prog->getOrCreateVariant(consts.get(), variant);
@@ -74,16 +58,15 @@ Error ForwardShading::initVol()
 	return Error::NONE;
 }
 
-void ForwardShading::drawVolumetric(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
+void ForwardShading::drawVolumetric(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 
-	cmdb->setViewport(0, 0, m_width, m_height);
-	cmdb->bindShaderProgram(m_vol.m_grProg);
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ONE);
-	cmdb->setDepthWrite(false);
 	cmdb->setDepthCompareOperation(CompareOperation::ALWAYS);
+	cmdb->setDepthWrite(false);
 
+	cmdb->bindShaderProgram(m_vol.m_grProg);
 	Vec4* unis = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
 	computeLinearizeDepthOptimal(ctx.m_renderQueue->m_cameraNear, ctx.m_renderQueue->m_cameraFar, unis->x(), unis->y());
 
@@ -102,11 +85,11 @@ void ForwardShading::drawVolumetric(RenderingContext& ctx, RenderPassWorkContext
 
 	// Restore state
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
-	cmdb->setDepthWrite(true);
 	cmdb->setDepthCompareOperation(CompareOperation::LESS);
+	cmdb->setDepthWrite(true);
 }
 
-void ForwardShading::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
+void ForwardShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
 {
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	const U threadId = rgraphCtx.m_currentSecondLevelCommandBufferIndex;
@@ -117,6 +100,9 @@ void ForwardShading::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 
 	if(start != end)
 	{
+		cmdb->setDepthWrite(false);
+		cmdb->setBlendFactors(0, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA);
+
 		const ClusterBinOut& rsrc = ctx.m_clusterBinOut;
 		rgraphCtx.bindTextureAndSampler(
 			0, 0, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH, m_r->getLinearSampler());
@@ -127,12 +113,6 @@ void ForwardShading::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 		bindStorage(cmdb, 0, 0, rsrc.m_clustersToken);
 		bindStorage(cmdb, 0, 1, rsrc.m_indicesToken);
 
-		cmdb->setViewport(0, 0, m_width, m_height);
-		cmdb->setBlendFactors(
-			0, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::SRC_ALPHA, BlendFactor::DST_ALPHA, BlendFactor::ZERO);
-		cmdb->setBlendOperation(0, BlendOperation::ADD);
-		cmdb->setDepthWrite(false);
-
 		// Start drawing
 		m_r->getSceneDrawer().drawRange(Pass::FS,
 			ctx.m_matrices.m_view,
@@ -141,6 +121,10 @@ void ForwardShading::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 			cmdb,
 			ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + start,
 			ctx.m_renderQueue->m_forwardShadingRenderables.getBegin() + end);
+
+		// Restore state
+		cmdb->setDepthWrite(true);
+		cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
 	}
 
 	if(threadId == threadCount - 1)
@@ -154,30 +138,11 @@ void ForwardShading::run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx
 	}
 }
 
-void ForwardShading::populateRenderGraph(RenderingContext& ctx)
+void ForwardShading::setDependencies(const RenderingContext& ctx, GraphicsRenderPassDescription& pass)
 {
-	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
-	m_runCtx.m_ctx = &ctx;
-
-	// Create RT
-	m_runCtx.m_rt = rgraph.newRenderTarget(m_rtDescr);
-
-	// Create pass
-	GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Forward shading");
-
-	pass.setWork(runCallback,
-		this,
-		computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_forwardShadingRenderables.getSize()));
-	pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rt}}, m_r->getDepthDownscale().getHalfDepthRt());
-
-	pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});
-	pass.newDependency({m_r->getDepthDownscale().getHalfDepthRt(),
-		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
-		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
 	pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
 	pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_QUARTER_DEPTH});
 	pass.newDependency({m_r->getVolumetric().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
-	pass.newDependency({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 
 	if(ctx.m_renderQueue->m_lensFlares.getSize())
 	{

+ 3 - 41
src/anki/renderer/ForwardShading.h

@@ -26,33 +26,11 @@ anki_internal:
 
 	ANKI_USE_RESULT Error init(const ConfigSet& initializer);
 
-	/// Populate the rendergraph.
-	void populateRenderGraph(RenderingContext& ctx);
+	void setDependencies(const RenderingContext& ctx, GraphicsRenderPassDescription& pass);
 
-	void drawUpscale(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
-
-	U32 getWidth() const
-	{
-		return m_width;
-	}
-
-	U32 getHeight() const
-	{
-		return m_height;
-	}
-
-	RenderTargetHandle getRt() const
-	{
-		return m_runCtx.m_rt;
-	}
+	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 
 private:
-	U32 m_width;
-	U32 m_height;
-
-	FramebufferDescription m_fbDescr;
-	RenderTargetDescription m_rtDescr;
-
 	class Vol
 	{
 	public:
@@ -61,26 +39,10 @@ private:
 		TextureResourcePtr m_noiseTex;
 	} m_vol;
 
-	class
-	{
-	public:
-		RenderTargetHandle m_rt;
-		RenderingContext* m_ctx = nullptr;
-	} m_runCtx;
-
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 	ANKI_USE_RESULT Error initVol();
 
-	/// A RenderPassWorkCallback.
-	static void runCallback(RenderPassWorkContext& rgraphCtx)
-	{
-		ForwardShading* self = scast<ForwardShading*>(rgraphCtx.m_userData);
-		self->run(*self->m_runCtx.m_ctx, rgraphCtx);
-	}
-
-	void run(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
-
-	void drawVolumetric(RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
+	void drawVolumetric(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

+ 4 - 9
src/anki/renderer/LensFlare.cpp

@@ -146,11 +146,8 @@ void LensFlare::runDrawFlares(const RenderingContext& ctx, CommandBufferPtr& cmd
 	const U count = min<U>(ctx.m_renderQueue->m_lensFlares.getSize(), m_maxFlares);
 
 	cmdb->bindShaderProgram(m_realGrProg);
+	cmdb->setBlendFactors(0, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA);
 	cmdb->setDepthWrite(false);
-	cmdb->setDepthCompareOperation(CompareOperation::ALWAYS);
-	cmdb->setBlendFactors(
-		0, BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendFactor::DST_ALPHA, BlendFactor::ONE);
-	cmdb->setBlendOperation(0, BlendOperation::ADD, BlendOperation::REVERSE_SUBTRACT);
 
 	for(U i = 0; i < count; ++i)
 	{
@@ -181,8 +178,8 @@ void LensFlare::runDrawFlares(const RenderingContext& ctx, CommandBufferPtr& cmd
 		// First flare
 		sprites[c].m_posScale = Vec4(posNdc, flareEl.m_firstFlareSize * Vec2(1.0f, m_r->getAspectRatio()));
 		sprites[c].m_depthPad3 = Vec4(0.0f);
-		F32 alpha = flareEl.m_colorMultiplier.w() * (1.0 - pow(absolute(posNdc.x()), 6.0f))
-					* (1.0 - pow(absolute(posNdc.y()), 6.0)); // Fade the flare on the edges
+		const F32 alpha = flareEl.m_colorMultiplier.w() * (1.0 - pow(absolute(posNdc.x()), 6.0f))
+						  * (1.0 - pow(absolute(posNdc.y()), 6.0)); // Fade the flare on the edges
 		sprites[c].m_color = Vec4(flareEl.m_colorMultiplier.xyz(), alpha);
 		++c;
 
@@ -199,10 +196,8 @@ void LensFlare::runDrawFlares(const RenderingContext& ctx, CommandBufferPtr& cmd
 	}
 
 	// Restore state
-	cmdb->setDepthWrite(true);
-	cmdb->setDepthCompareOperation(CompareOperation::LESS);
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
-	cmdb->setBlendOperation(0, BlendOperation::ADD);
+	cmdb->setDepthWrite(true);
 }
 
 } // end namespace anki

+ 16 - 55
src/anki/renderer/LightShading.cpp

@@ -63,38 +63,26 @@ Error LightShading::initInternal(const ConfigSet& config)
 	// Create FB descr
 	m_fbDescr.m_colorAttachmentCount = 1;
 	m_fbDescr.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+	m_fbDescr.m_depthStencilAttachment.m_loadOperation = AttachmentLoadOperation::LOAD;
+	m_fbDescr.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH;
 	m_fbDescr.bake();
 
-	// FS upscale
-	{
-		ANKI_CHECK(getResourceManager().loadResource("engine_data/BlueNoiseLdrRgb64x64.ankitex", m_fs.m_noiseTex));
-
-		// Shader
-		ANKI_CHECK(getResourceManager().loadResource("shaders/ForwardShadingUpscale.glslp", m_fs.m_prog));
-
-		ShaderProgramResourceConstantValueInitList<3> consts(m_fs.m_prog);
-		consts.add("NOISE_TEX_SIZE", U32(m_fs.m_noiseTex->getWidth()))
-			.add("SRC_SIZE", Vec2(m_r->getWidth() / FS_FRACTION, m_r->getHeight() / FS_FRACTION))
-			.add("FB_SIZE", Vec2(m_r->getWidth(), m_r->getWidth()));
-
-		const ShaderProgramResourceVariant* variant;
-		m_fs.m_prog->getOrCreateVariant(consts.get(), variant);
-		m_fs.m_grProg = variant->getProgram();
-	}
-
 	return Error::NONE;
 }
 
-void LightShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx)
+void LightShading::run(RenderPassWorkContext& rgraphCtx)
 {
+	const RenderingContext& ctx = *m_runCtx.m_ctx;
 	CommandBufferPtr& cmdb = rgraphCtx.m_commandBuffer;
 	const ClusterBinOut& rsrc = ctx.m_clusterBinOut;
 
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 
-	// Do light shading
+	// Do light shading first
+	if(rgraphCtx.m_currentSecondLevelCommandBufferIndex == 0)
 	{
 		cmdb->bindShaderProgram(m_progVariant->getProgram());
+		cmdb->setDepthWrite(false);
 
 		// Bind textures
 		rgraphCtx.bindColorTextureAndSampler(0, 0, m_r->getGBuffer().getColorRt(0), m_r->getNearestSampler());
@@ -133,36 +121,7 @@ void LightShading::run(const RenderingContext& ctx, RenderPassWorkContext& rgrap
 	}
 
 	// Forward shading
-	{
-		// Bind textures
-		rgraphCtx.bindTextureAndSampler(0,
-			0,
-			m_r->getGBuffer().getDepthRt(),
-			TextureSubresourceInfo(DepthStencilAspectBit::DEPTH),
-			m_r->getNearestSampler());
-		rgraphCtx.bindTextureAndSampler(
-			0, 1, m_r->getDepthDownscale().getHiZRt(), HIZ_HALF_DEPTH, m_r->getNearestSampler());
-		rgraphCtx.bindColorTextureAndSampler(0, 2, m_r->getForwardShading().getRt(), m_r->getLinearSampler());
-		cmdb->bindTextureAndSampler(0,
-			3,
-			m_fs.m_noiseTex->getGrTextureView(),
-			m_r->getTrilinearRepeatSampler(),
-			TextureUsageBit::SAMPLED_FRAGMENT);
-
-		// Bind uniforms
-		Vec4* linearDepth = allocateAndBindUniforms<Vec4*>(sizeof(Vec4), cmdb, 0, 0);
-		computeLinearizeDepthOptimal(
-			ctx.m_renderQueue->m_cameraNear, ctx.m_renderQueue->m_cameraFar, linearDepth->x(), linearDepth->y());
-		linearDepth->z() = ctx.m_renderQueue->m_cameraFar;
-
-		// Other state & draw
-		cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA);
-		cmdb->bindShaderProgram(m_fs.m_grProg);
-		drawQuad(cmdb);
-	}
-
-	// Restore state
-	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
+	m_r->getForwardShading().run(ctx, rgraphCtx);
 }
 
 void LightShading::populateRenderGraph(RenderingContext& ctx)
@@ -174,10 +133,13 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	m_runCtx.m_rt = rgraph.newRenderTarget(m_rtDescr);
 
 	// Create pass
-	GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Light Shading");
+	GraphicsRenderPassDescription& pass = rgraph.newGraphicsRenderPass("Light&FW Shad.");
 
-	pass.setWork(runCallback, this, 0);
-	pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rt}}, {});
+	pass.setWork(
+		[](RenderPassWorkContext& rgraphCtx) { static_cast<LightShading*>(rgraphCtx.m_userData)->run(rgraphCtx); },
+		this,
+		computeNumberOfSecondLevelCommandBuffers(ctx.m_renderQueue->m_forwardShadingRenderables.getSize()));
+	pass.setFramebufferInfo(m_fbDescr, {{m_runCtx.m_rt}}, {m_r->getGBuffer().getDepthRt()});
 
 	// Light shading
 	pass.newDependency({m_runCtx.m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE});
@@ -185,7 +147,7 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	pass.newDependency({m_r->getGBuffer().getColorRt(1), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newDependency({m_r->getGBuffer().getColorRt(2), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newDependency({m_r->getGBuffer().getDepthRt(),
-		TextureUsageBit::SAMPLED_FRAGMENT,
+		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ,
 		TextureSubresourceInfo(DepthStencilAspectBit::DEPTH)});
 	pass.newDependency({m_r->getShadowMapping().getShadowmapRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 	pass.newDependency({m_r->getSsao().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
@@ -196,8 +158,7 @@ void LightShading::populateRenderGraph(RenderingContext& ctx)
 	pass.newDependency({m_r->getIndirect().getIrradianceRt(), TextureUsageBit::SAMPLED_FRAGMENT});
 
 	// For forward shading
-	pass.newDependency({m_r->getDepthDownscale().getHiZRt(), TextureUsageBit::SAMPLED_FRAGMENT, HIZ_HALF_DEPTH});
-	pass.newDependency({m_r->getForwardShading().getRt(), TextureUsageBit::SAMPLED_FRAGMENT});
+	m_r->getForwardShading().setDependencies(ctx, pass);
 }
 
 } // end namespace anki

+ 1 - 16
src/anki/renderer/LightShading.h

@@ -40,14 +40,6 @@ private:
 	ShaderProgramResourcePtr m_prog;
 	const ShaderProgramResourceVariant* m_progVariant = nullptr;
 
-	class
-	{
-	public:
-		ShaderProgramResourcePtr m_prog;
-		ShaderProgramPtr m_grProg;
-		TextureResourcePtr m_noiseTex;
-	} m_fs; ///< Apply forward shading.
-
 	class
 	{
 	public:
@@ -58,14 +50,7 @@ private:
 	/// Called by init
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 
-	void run(const RenderingContext& ctx, RenderPassWorkContext& rgraphCtx);
-
-	/// A RenderPassWorkCallback for the light pass.
-	static void runCallback(RenderPassWorkContext& rgraphCtx)
-	{
-		LightShading* const self = scast<LightShading*>(rgraphCtx.m_userData);
-		self->run(*self->m_runCtx.m_ctx, rgraphCtx);
-	}
+	void run(RenderPassWorkContext& rgraphCtx);
 };
 /// @}
 

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

@@ -292,7 +292,6 @@ Error Renderer::populateRenderGraph(RenderingContext& ctx)
 	m_vol->populateRenderGraph(ctx);
 	m_ssao->populateRenderGraph(ctx);
 	m_lensFlare->populateRenderGraph(ctx);
-	m_forwardShading->populateRenderGraph(ctx);
 	m_ssr->populateRenderGraph(ctx);
 	m_lightShading->populateRenderGraph(ctx);
 	m_temporalAA->populateRenderGraph(ctx);

+ 1 - 1
src/anki/renderer/VolumetricLightingAccumulation.cpp

@@ -78,7 +78,7 @@ void VolumetricLightingAccumulation::populateRenderGraph(RenderingContext& ctx)
 	m_runCtx.m_ctx = &ctx;
 	RenderGraphDescription& rgraph = ctx.m_renderGraphDescr;
 
-	m_runCtx.m_rt = rgraph.importRenderTarget(m_rtTex, TextureUsageBit::SAMPLED_FRAGMENT);
+	m_runCtx.m_rt = rgraph.importRenderTarget(m_rtTex, TextureUsageBit::IMAGE_COMPUTE_READ_WRITE); // TODO
 
 	ComputeRenderPassDescription& pass = rgraph.newComputeRenderPass("Vol light");
 

+ 3 - 3
tools/texture/create_atlas.py

@@ -31,7 +31,7 @@ class Frame:
 	@classmethod
 	def diagonal(self):
 		return sqrt(self.w * self.w + self.h * self.h)
-	
+
 	@classmethod
 	def area(self):
 		return self.w * self.h
@@ -177,7 +177,7 @@ def place_sub_images(ctx):
 		sub_image = ctx.sub_images[unplaced_imgs[0]]
 		unplaced_imgs.pop(0)
 
-		printi("Will try to place image \"%s\" of size %ux%d" % 
+		printi("Will try to place image \"%s\" of size %ux%d" %
 				(sub_image.image_name, sub_image.width, sub_image.height))
 
 		# Find best frame
@@ -288,7 +288,7 @@ def write_xml(ctx):
 def main():
 	""" The main """
 
-	ctx = parse_commandline();
+	ctx = parse_commandline()
 	load_images(ctx)
 	compute_atlas_rough_size(ctx)
 	place_sub_images(ctx)

+ 92 - 0
tools/texture/noise_array.py

@@ -0,0 +1,92 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors.
+# All rights reserved.
+# Code licensed under the BSD License.
+# http://www.anki3d.org/LICENSE
+
+import argparse
+from PIL import Image, ImageDraw
+from math import *
+import os
+
+class Context:
+	input = ""
+	out_prefix = ""
+	out_count = 0
+	out_format = ""
+
+	img = None
+	color_delta = 0.0
+
+ctx = Context()
+
+def parse_commandline():
+	""" Parse the command line arguments """
+
+	parser = argparse.ArgumentParser(description = "This program takes a blue noise texture and creates an array of " \
+			"noise textures",
+			formatter_class = argparse.ArgumentDefaultsHelpFormatter)
+
+	parser.add_argument("-i", "--input", required = True, help = "the input noise texture")
+
+	parser.add_argument("-o", "--output-prefix", required = True, help = "prefix of the output images")
+
+	parser.add_argument("-c", "--output-img-count", required = True, help = "number of output images")
+
+	parser.add_argument("-f", "--output-format", help = "output format", default = "")
+
+	args = parser.parse_args()
+
+	ctx.input = args.input
+	ctx.out_prefix = args.output_prefix
+	ctx.out_count = int(args.output_img_count)
+	ctx.out_format = args.output_format
+
+def init():
+	# Open image
+	ctx.img = Image.open(ctx.input)
+
+	# Color fmt
+	if ctx.img.mode != "RGB" and ctx.img.mode != "RGBA":
+		raise Exception("Unknown mode %s" % ctx.img.mode)
+
+	if ctx.out_format == "":
+		ctx.out_format = ctx.img.mode
+
+	# Color delta
+	ctx.color_delta = int(0xFF / (ctx.out_count + 1.0))
+
+def create_image(idx):
+	out_img = Image.new(ctx.img.mode, (ctx.img.width, ctx.img.height))
+
+	delta = idx * ctx.color_delta
+
+	for x in range(0, ctx.img.width):
+		for y in range(0, ctx.img.height):
+			pixel = ctx.img.getpixel((x, y))
+
+			r = int(pixel[0] + delta) % 0xFF
+			g = int(pixel[1] + delta) % 0xFF
+			b = int(pixel[2] + delta) % 0xFF
+
+			if ctx.img.mode == "RGBA":
+				a = int(pixel[3] + delta) % 0xFF
+
+			if ctx.out_format == "RGB":
+				out_img.putpixel((x, y), (r, g, b))
+			else:
+				out_img.putpixel((x, y), (r, g, b, a))
+
+	out_img.save("%s_%02d.png" % (ctx.out_prefix, idx))
+
+def main():
+	""" The main """
+
+	parse_commandline()
+	init()
+	for i in range(ctx.out_count):
+		create_image(i + 1)
+
+if __name__ == "__main__":
+	main()