فهرست منبع

Initial commit of the experiment

Panagiotis Christopoulos Charitos 9 سال پیش
والد
کامیت
46d52f85cb

+ 56 - 0
shaders/IsAlternate.frag.glsl

@@ -0,0 +1,56 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "shaders/Functions.glsl"
+
+layout(location = 0) in vec2 in_uv;
+layout(location = 0) out vec3 out_color;
+
+layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_depthRt;
+layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_oldIsRt;
+layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2D u_prevDepthRt;
+
+layout(ANKI_UBO_BINDING(0, 0), row_major) uniform u_
+{
+	mat4 u_invViewProjMat;
+	mat4 u_prevViewProjMat;
+};
+
+void main()
+{
+	vec2 ndc = 2.0 * in_uv - 1.0;
+
+	// Get crnt pos in world space
+	float depth = texture(u_depthRt, in_uv).r;
+	vec4 worldPos4 = u_invViewProjMat * vec4(ndc, depth * 2.0 - 1.0, 1.0);
+	worldPos4 = worldPos4 / worldPos4.w;
+
+	// Project to get old ndc
+	vec4 oldNdc4 = u_prevViewProjMat * worldPos4;
+	vec2 oldNdc = oldNdc4.xy / oldNdc4.w;
+	
+	if(oldNdc.x < 1.0 && oldNdc.y < 1.0 && oldNdc.x > -1.0 && oldNdc.y > -1.0)
+	{
+		vec2 oldUv = oldNdc * 0.5 + 0.5;
+
+		// Get prev depth
+		float prevDepth = textureLod(u_prevDepthRt, oldUv, 0.0).r;
+
+		if(abs(prevDepth - depth) < 0.01)
+		{
+			out_color = textureLod(u_oldIsRt, oldUv, 0.0).rgb;
+		}
+		else
+		{
+			discard;
+			//out_color = vec3(1.0);
+		}
+	}
+	else
+	{
+		discard;
+		//out_color = vec3(1.0);
+	}
+}

+ 1 - 1
shaders/Pps.frag.glsl

@@ -148,7 +148,7 @@ void main()
 
 
 #if 0
 #if 0
 	{
 	{
-		out_color = textureLod(u_smaaBlendTex, uv, 0.0).rgb;
+		out_color = vec3(textureLod(u_isRt, uv, 0.0).rgb);
 	}
 	}
 #endif
 #endif
 
 

+ 53 - 0
shaders/Velocity.frag.glsl

@@ -0,0 +1,53 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "shaders/Functions.glsl"
+
+layout(location = 0) in vec2 in_uv;
+layout(location = 0) out vec2 out_color;
+
+layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_prevDepthRt;
+
+layout(ANKI_UBO_BINDING(0, 0), row_major) uniform u_
+{
+	mat4 u_prevInvViewProjMat;
+	mat4 u_crntViewProjMat;
+};
+
+void main()
+{
+	vec2 ndc = 2.0 * in_uv - 1.0;
+
+	// Get prev pos in w space
+	float prevDepth = texture(u_prevDepthRt, in_uv).r * 2.0 - 1.0;
+	vec4 prevWPos4 = u_prevInvViewProjMat * vec4(ndc, prevDepth, 1.0);
+	prevWPos4 = prevWPos4 / prevWPos4.w;
+
+	// Project prev pos
+	vec4 pos = u_crntViewProjMat * prevWPos4;
+	pos /= pos.w;
+	vec2 estNdc = pos.xy;
+
+	// Write result
+	/*if(gl_FragCoord.x > 1920.0/2./2.)
+	{
+		out_color = vec2(length(ndc));
+	}
+	else
+	{
+		out_color = vec2(length(estNdc));
+	}*/
+
+	if(pos.x < 1.0 && pos.y < 1.0 && pos.z < 1.0 && pos.x > -1.0 && pos.y > -1.0 && pos.z > -1.0)
+	{
+		vec2 diff = estNdc - ndc;
+		out_color = (diff * 0.5 + 0.5);
+	}
+	else
+	{
+		out_color = vec2(1.0);
+	}
+}
+

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

@@ -80,7 +80,7 @@ void BloomExposure::run(RenderingContext& ctx)
 	cmdb->beginRenderPass(m_fb);
 	cmdb->beginRenderPass(m_fb);
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->setViewport(0, 0, m_width, m_height);
 	cmdb->bindShaderProgram(m_prog);
 	cmdb->bindShaderProgram(m_prog);
-	cmdb->bindTexture(0, 0, m_r->getIs().getRt());
+	cmdb->bindTexture(0, 0, m_r->getIs().getRt(m_r->getFrameCount() % 2));
 
 
 	TransientMemoryToken token;
 	TransientMemoryToken token;
 	Vec4* uniforms = static_cast<Vec4*>(
 	Vec4* uniforms = static_cast<Vec4*>(

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

@@ -31,6 +31,7 @@ class DownscaleBlur;
 class Volumetric;
 class Volumetric;
 class DepthDownscale;
 class DepthDownscale;
 class Smaa;
 class Smaa;
+class Velocity;
 
 
 class RenderingContext;
 class RenderingContext;
 class DebugDrawer;
 class DebugDrawer;

+ 13 - 10
src/anki/renderer/DownscaleBlur.cpp

@@ -32,12 +32,15 @@ Error DownscaleBlur::initSubpass(U idx, const UVec2& inputTexSize)
 	m_r->createDrawQuadShaderProgram(pass.m_frag->getGrShader(), pass.m_prog);
 	m_r->createDrawQuadShaderProgram(pass.m_frag->getGrShader(), pass.m_prog);
 
 
 	// FB
 	// FB
-	FramebufferInitInfo fbInit;
-	fbInit.m_colorAttachmentCount = 1;
-	fbInit.m_colorAttachments[0].m_texture = m_r->getIs().getRt();
-	fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
-	fbInit.m_colorAttachments[0].m_surface.m_level = idx + 1;
-	pass.m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
+	for(U i = 0; i < 2; ++i)
+	{
+		FramebufferInitInfo fbInit;
+		fbInit.m_colorAttachmentCount = 1;
+		fbInit.m_colorAttachments[0].m_texture = m_r->getIs().getRt(i);
+		fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+		fbInit.m_colorAttachments[0].m_surface.m_level = idx + 1;
+		pass.m_fb[i] = getGrManager().newInstance<Framebuffer>(fbInit);
+	}
 
 
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }
@@ -73,7 +76,7 @@ void DownscaleBlur::run(RenderingContext& ctx)
 {
 {
 	CommandBufferPtr cmdb = ctx.m_commandBuffer;
 	CommandBufferPtr cmdb = ctx.m_commandBuffer;
 
 
-	cmdb->bindTexture(0, 0, m_r->getIs().getRt());
+	cmdb->bindTexture(0, 0, m_r->getIs().getRt(m_r->getFrameCount() % 2));
 
 
 	UVec2 size(m_r->getWidth(), m_r->getHeight());
 	UVec2 size(m_r->getWidth(), m_r->getHeight());
 	for(U i = 0; i < m_passes.getSize(); ++i)
 	for(U i = 0; i < m_passes.getSize(); ++i)
@@ -83,18 +86,18 @@ void DownscaleBlur::run(RenderingContext& ctx)
 
 
 		if(i > 0)
 		if(i > 0)
 		{
 		{
-			cmdb->setTextureSurfaceBarrier(m_r->getIs().getRt(),
+			cmdb->setTextureSurfaceBarrier(m_r->getIs().getRt(m_r->getFrameCount() % 2),
 				TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 				TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 				TextureUsageBit::SAMPLED_FRAGMENT,
 				TextureUsageBit::SAMPLED_FRAGMENT,
 				TextureSurfaceInfo(i, 0, 0, 0));
 				TextureSurfaceInfo(i, 0, 0, 0));
 		}
 		}
 
 
-		cmdb->setTextureSurfaceBarrier(m_r->getIs().getRt(),
+		cmdb->setTextureSurfaceBarrier(m_r->getIs().getRt(m_r->getFrameCount() % 2),
 			TextureUsageBit::NONE,
 			TextureUsageBit::NONE,
 			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 			TextureSurfaceInfo(i + 1, 0, 0, 0));
 			TextureSurfaceInfo(i + 1, 0, 0, 0));
 
 
-		cmdb->beginRenderPass(pass.m_fb);
+		cmdb->beginRenderPass(pass.m_fb[m_r->getFrameCount() % 2]);
 		cmdb->setViewport(0, 0, size.x(), size.y());
 		cmdb->setViewport(0, 0, size.x(), size.y());
 		cmdb->bindShaderProgram(pass.m_prog);
 		cmdb->bindShaderProgram(pass.m_prog);
 
 

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

@@ -34,7 +34,7 @@ private:
 	public:
 	public:
 		ShaderResourcePtr m_frag;
 		ShaderResourcePtr m_frag;
 		ShaderProgramPtr m_prog;
 		ShaderProgramPtr m_prog;
-		FramebufferPtr m_fb;
+		Array<FramebufferPtr, 2> m_fb;
 	};
 	};
 
 
 	DynamicArray<Subpass> m_passes;
 	DynamicArray<Subpass> m_passes;

+ 31 - 6
src/anki/renderer/FsUpscale.cpp

@@ -54,11 +54,22 @@ Error FsUpscale::initInternal(const ConfigSet& config)
 	m_prog = gr.newInstance<ShaderProgram>(m_vert->getGrShader(), m_frag->getGrShader());
 	m_prog = gr.newInstance<ShaderProgram>(m_vert->getGrShader(), m_frag->getGrShader());
 
 
 	// Create FB
 	// Create FB
-	FramebufferInitInfo fbInit;
-	fbInit.m_colorAttachmentCount = 1;
-	fbInit.m_colorAttachments[0].m_texture = m_r->getIs().getRt();
-	fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::LOAD;
-	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
+	for(U i = 0; i < 2; ++i)
+	{
+		FramebufferInitInfo fbInit;
+		fbInit.m_colorAttachmentCount = 1;
+		fbInit.m_colorAttachments[0].m_texture = m_r->getIs().getRt(i);
+		fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::LOAD;
+
+		if(i == 1)
+		{
+			fbInit.m_depthStencilAttachment.m_texture = m_r->getIs().m_stencilRt;
+			fbInit.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::LOAD;
+			fbInit.m_depthStencilAttachment.m_stencilStoreOperation = AttachmentStoreOperation::DONT_CARE;
+			fbInit.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::STENCIL;
+		}
+		m_fb[i] = getGrManager().newInstance<Framebuffer>(fbInit);
+	}
 
 
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }
@@ -82,15 +93,29 @@ void FsUpscale::run(RenderingContext& ctx)
 
 
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA);
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::SRC_ALPHA);
 
 
-	cmdb->beginRenderPass(m_fb);
+	cmdb->beginRenderPass(m_fb[m_r->getFrameCount() % 2]);
 	cmdb->bindShaderProgram(m_prog);
 	cmdb->bindShaderProgram(m_prog);
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 
 
+	Bool cheat = (m_r->getFrameCount() % 2) == 1;
+	if(cheat)
+	{
+		cmdb->setStencilCompareMask(FaceSelectionBit::FRONT, 0xF);
+		cmdb->setStencilWriteMask(FaceSelectionBit::FRONT, 0x0);
+		cmdb->setStencilReference(FaceSelectionBit::FRONT, 0xF);
+		cmdb->setStencilCompareOperation(FaceSelectionBit::FRONT, CompareOperation::NOT_EQUAL);
+	}
+
 	m_r->drawQuad(cmdb);
 	m_r->drawQuad(cmdb);
 	cmdb->endRenderPass();
 	cmdb->endRenderPass();
 
 
 	// Restore state
 	// Restore state
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
 	cmdb->setBlendFactors(0, BlendFactor::ONE, BlendFactor::ZERO);
+
+	if(cheat)
+	{
+		cmdb->setStencilCompareOperation(FaceSelectionBit::FRONT, CompareOperation::ALWAYS);
+	}
 }
 }
 
 
 } // end namespace anki
 } // end namespace anki

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

@@ -27,7 +27,7 @@ public:
 	void run(RenderingContext& ctx);
 	void run(RenderingContext& ctx);
 
 
 private:
 private:
-	FramebufferPtr m_fb;
+	Array<FramebufferPtr, 2> m_fb;
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_frag;
 	ShaderResourcePtr m_vert;
 	ShaderResourcePtr m_vert;
 	ShaderProgramPtr m_prog;
 	ShaderProgramPtr m_prog;

+ 92 - 16
src/anki/renderer/Is.cpp

@@ -9,6 +9,7 @@
 #include <anki/renderer/Ir.h>
 #include <anki/renderer/Ir.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/Ms.h>
 #include <anki/renderer/LightBin.h>
 #include <anki/renderer/LightBin.h>
+#include <anki/renderer/DepthDownscale.h>
 #include <anki/scene/FrustumComponent.h>
 #include <anki/scene/FrustumComponent.h>
 #include <anki/misc/ConfigSet.h>
 #include <anki/misc/ConfigSet.h>
 #include <anki/util/HighRezTimer.h>
 #include <anki/util/HighRezTimer.h>
@@ -117,23 +118,46 @@ Error Is::initInternal(const ConfigSet& config)
 
 
 	m_lightProg = getGrManager().newInstance<ShaderProgram>(m_lightVert->getGrShader(), m_lightFrag->getGrShader());
 	m_lightProg = getGrManager().newInstance<ShaderProgram>(m_lightVert->getGrShader(), m_lightFrag->getGrShader());
 
 
+
+	// XXX
+	m_r->createRenderTarget(m_r->getWidth(),
+		m_r->getHeight(),
+			PixelFormat(ComponentFormat::S8, TransformFormat::UINT),
+			TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
+			SamplingFilter::LINEAR,
+			1,
+			m_stencilRt);
+
 	//
 	//
 	// Create framebuffer
 	// Create framebuffer
 	//
 	//
-	m_r->createRenderTarget(m_r->getWidth(),
-		m_r->getHeight(),
-		IS_COLOR_ATTACHMENT_PIXEL_FORMAT,
-		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE
-			| TextureUsageBit::SAMPLED_COMPUTE,
-		SamplingFilter::LINEAR,
-		m_rtMipCount,
-		m_rt);
-
-	FramebufferInitInfo fbInit;
-	fbInit.m_colorAttachmentCount = 1;
-	fbInit.m_colorAttachments[0].m_texture = m_rt;
-	fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
-	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
+	for(U i = 0; i < 2; ++i)
+	{
+		m_r->createRenderTarget(m_r->getWidth(),
+			m_r->getHeight(),
+			IS_COLOR_ATTACHMENT_PIXEL_FORMAT,
+			TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE
+				| TextureUsageBit::SAMPLED_COMPUTE,
+			SamplingFilter::LINEAR,
+			m_rtMipCount,
+			m_rt[i]);
+
+		FramebufferInitInfo fbInit;
+		fbInit.m_colorAttachmentCount = 1;
+		fbInit.m_colorAttachments[0].m_texture = m_rt[i];
+		//fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+		fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::CLEAR;
+		fbInit.m_colorAttachments[0].m_clearValue.m_colorf = {{1.0, 0.0, 1.0, 0.0}};
+
+		if(i == 1)
+		{
+			fbInit.m_depthStencilAttachment.m_texture = m_stencilRt;
+			fbInit.m_depthStencilAttachment.m_stencilLoadOperation = AttachmentLoadOperation::CLEAR;
+			fbInit.m_depthStencilAttachment.m_stencilStoreOperation = AttachmentStoreOperation::STORE;
+			fbInit.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::STENCIL;
+		}
+		m_fb[i] = getGrManager().newInstance<Framebuffer>(fbInit);
+	}
 
 
 	TextureInitInfo texinit;
 	TextureInitInfo texinit;
 	texinit.m_width = texinit.m_height = 4;
 	texinit.m_width = texinit.m_height = 4;
@@ -141,6 +165,13 @@ Error Is::initInternal(const ConfigSet& config)
 	texinit.m_format = PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM);
 	texinit.m_format = PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM);
 	m_dummyTex = getGrManager().newInstance<Texture>(texinit);
 	m_dummyTex = getGrManager().newInstance<Texture>(texinit);
 
 
+	//
+	// Create XXX
+	//
+	ANKI_CHECK(getResourceManager().loadResource("shaders/IsAlternate.frag.glsl", m_alt.m_frag));
+
+	m_r->createDrawQuadShaderProgram(m_alt.m_frag->getGrShader(), m_alt.m_prog);
+
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }
 
 
@@ -168,8 +199,46 @@ void Is::run(RenderingContext& ctx)
 {
 {
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 
 
-	cmdb->beginRenderPass(m_fb);
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
+	cmdb->beginRenderPass(m_fb[m_r->getFrameCount() % 2]);
+
+	Bool cheat = (m_r->getFrameCount() % 2) == 1;
+	if(cheat)
+	{
+		cmdb->bindTexture(0, 0, m_r->getMs().m_depthRt, DepthStencilAspectBit::DEPTH);
+		cmdb->bindTexture(0, 1, m_rt[(m_r->getFrameCount() + 1) % 2], DepthStencilAspectBit::DEPTH);
+		cmdb->bindTexture(0, 2, m_r->getDepthDownscale().m_qd.m_depthRt);
+
+		struct Uniforms
+		{
+			Mat4 m_invViewProjMat;
+			Mat4 m_prevViewProjMat;
+		};
+
+		TransientMemoryToken token;
+		Uniforms* unis = static_cast<Uniforms*>(getGrManager().allocateFrameTransientMemory(sizeof(Uniforms), 
+			BufferUsageBit::UNIFORM_ALL, token));
+		cmdb->bindUniformBuffer(0, 0, token);
+
+		unis->m_invViewProjMat = ctx.m_frustumComponent->getViewProjectionMatrix().getInverse();
+		unis->m_prevViewProjMat = ctx.m_prevFrameViewProjMatrix;
+
+		cmdb->setStencilOperations(
+			FaceSelectionBit::FRONT, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::REPLACE);
+		cmdb->setStencilCompareMask(FaceSelectionBit::FRONT, 0xF);
+		cmdb->setStencilWriteMask(FaceSelectionBit::FRONT, 0xF);
+		cmdb->setStencilReference(FaceSelectionBit::FRONT, 0xF);
+		cmdb->setStencilCompareOperation(FaceSelectionBit::FRONT, CompareOperation::ALWAYS);
+
+		cmdb->bindShaderProgram(m_alt.m_prog);
+		m_r->drawQuad(cmdb);
+
+		cmdb->setStencilOperations(
+			FaceSelectionBit::FRONT, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::KEEP);
+		cmdb->setStencilCompareOperation(FaceSelectionBit::FRONT, CompareOperation::NOT_EQUAL);
+	}
+
+
 	cmdb->bindShaderProgram(m_lightProg);
 	cmdb->bindShaderProgram(m_lightProg);
 
 
 	cmdb->bindTexture(0, 0, m_r->getMs().m_rt0);
 	cmdb->bindTexture(0, 0, m_r->getMs().m_rt0);
@@ -195,7 +264,14 @@ void Is::run(RenderingContext& ctx)
 	cmdb->bindStorageBuffer(0, 1, ctx.m_is.m_lightIndicesToken);
 	cmdb->bindStorageBuffer(0, 1, ctx.m_is.m_lightIndicesToken);
 
 
 	cmdb->drawArrays(PrimitiveTopology::TRIANGLE_STRIP, 4, m_r->getTileCount());
 	cmdb->drawArrays(PrimitiveTopology::TRIANGLE_STRIP, 4, m_r->getTileCount());
+
 	cmdb->endRenderPass();
 	cmdb->endRenderPass();
+
+	// Restore state
+	if(cheat)
+	{
+		cmdb->setStencilCompareOperation(FaceSelectionBit::FRONT, CompareOperation::ALWAYS);
+	}
 }
 }
 
 
 void Is::updateCommonBlock(RenderingContext& ctx)
 void Is::updateCommonBlock(RenderingContext& ctx)
@@ -219,7 +295,7 @@ void Is::updateCommonBlock(RenderingContext& ctx)
 
 
 void Is::setPreRunBarriers(RenderingContext& ctx)
 void Is::setPreRunBarriers(RenderingContext& ctx)
 {
 {
-	ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt,
+	ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt[m_r->getFrameCount() % 2],
 		TextureUsageBit::NONE,
 		TextureUsageBit::NONE,
 		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
 		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
 		TextureSurfaceInfo(0, 0, 0, 0));
 		TextureSurfaceInfo(0, 0, 0, 0));

+ 13 - 4
src/anki/renderer/Is.h

@@ -24,6 +24,8 @@ enum class ShaderVariantBit : U8;
 class Is : public RenderingPass
 class Is : public RenderingPass
 {
 {
 anki_internal:
 anki_internal:
+	TexturePtr m_stencilRt;
+
 	Is(Renderer* r);
 	Is(Renderer* r);
 
 
 	~Is();
 	~Is();
@@ -36,9 +38,9 @@ anki_internal:
 
 
 	void run(RenderingContext& ctx);
 	void run(RenderingContext& ctx);
 
 
-	TexturePtr getRt() const
+	TexturePtr getRt(U idx) const
 	{
 	{
-		return m_rt;
+		return m_rt[idx];
 	}
 	}
 
 
 	/// Get the number of mips for IS's render target.
 	/// Get the number of mips for IS's render target.
@@ -54,12 +56,12 @@ anki_internal:
 
 
 private:
 private:
 	/// The IS render target
 	/// The IS render target
-	TexturePtr m_rt;
+	Array<TexturePtr, 2> m_rt;
 	U8 m_rtMipCount = 0;
 	U8 m_rtMipCount = 0;
 	U32 m_clusterCount = 0;
 	U32 m_clusterCount = 0;
 
 
 	/// The IS FBO
 	/// The IS FBO
-	FramebufferPtr m_fb;
+	Array<FramebufferPtr, 2> m_fb;
 
 
 	TexturePtr m_dummyTex;
 	TexturePtr m_dummyTex;
 
 
@@ -96,6 +98,13 @@ private:
 	U32 m_maxLightIds;
 	U32 m_maxLightIds;
 	/// @}
 	/// @}
 
 
+	class Alt
+	{
+	public:
+		ShaderResourcePtr m_frag;
+		ShaderProgramPtr m_prog;
+	} m_alt;
+
 	/// Called by init
 	/// Called by init
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 
 

+ 3 - 1
src/anki/renderer/Pps.cpp

@@ -16,6 +16,7 @@
 #include <anki/misc/ConfigSet.h>
 #include <anki/misc/ConfigSet.h>
 #include <anki/scene/SceneNode.h>
 #include <anki/scene/SceneNode.h>
 #include <anki/scene/FrustumComponent.h>
 #include <anki/scene/FrustumComponent.h>
+#include <anki/renderer/Velocity.h>
 
 
 namespace anki
 namespace anki
 {
 {
@@ -142,7 +143,8 @@ Error Pps::run(RenderingContext& ctx)
 	}
 	}
 
 
 	// Bind stuff
 	// Bind stuff
-	cmdb->bindTexture(0, 0, m_r->getIs().getRt());
+	cmdb->bindTexture(0, 0, m_r->getIs().getRt(m_r->getFrameCount() % 2));
+	//cmdb->bindTexture(0, 0, m_r->getVelocity().m_rt);
 	cmdb->bindTexture(0, 1, m_r->getBloom().m_upscale.m_rt);
 	cmdb->bindTexture(0, 1, m_r->getBloom().m_upscale.m_rt);
 	cmdb->bindTexture(0, 2, m_lut->getGrTexture());
 	cmdb->bindTexture(0, 2, m_lut->getGrTexture());
 	cmdb->bindTexture(0, 3, m_r->getSmaa().m_weights.m_rt);
 	cmdb->bindTexture(0, 3, m_r->getSmaa().m_weights.m_rt);

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

@@ -25,6 +25,7 @@
 #include <anki/renderer/Volumetric.h>
 #include <anki/renderer/Volumetric.h>
 #include <anki/renderer/DepthDownscale.h>
 #include <anki/renderer/DepthDownscale.h>
 #include <anki/renderer/Smaa.h>
 #include <anki/renderer/Smaa.h>
+#include <anki/renderer/Velocity.h>
 
 
 #include <cstdarg> // For var args
 #include <cstdarg> // For var args
 
 
@@ -181,6 +182,9 @@ Error Renderer::initInternal(const ConfigSet& config)
 	m_dbg.reset(m_alloc.newInstance<Dbg>(this));
 	m_dbg.reset(m_alloc.newInstance<Dbg>(this));
 	ANKI_CHECK(m_dbg->init(config));
 	ANKI_CHECK(m_dbg->init(config));
 
 
+	m_vel.reset(m_alloc.newInstance<Velocity>(this));
+	ANKI_CHECK(m_vel->init(config));
+
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;
 }
 }
 
 
@@ -188,6 +192,7 @@ Error Renderer::render(RenderingContext& ctx)
 {
 {
 	FrustumComponent& frc = *ctx.m_frustumComponent;
 	FrustumComponent& frc = *ctx.m_frustumComponent;
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
+	ctx.m_prevFrameViewProjMatrix = m_prevFrameViewProjMatrix;
 
 
 	ANKI_ASSERT(frc.getFrustum().getType() == FrustumType::PERSPECTIVE);
 	ANKI_ASSERT(frc.getFrustum().getType() == FrustumType::PERSPECTIVE);
 
 
@@ -226,10 +231,10 @@ Error Renderer::render(RenderingContext& ctx)
 	m_smaa->m_weights.setPreRunBarriers(ctx);
 	m_smaa->m_weights.setPreRunBarriers(ctx);
 	m_vol->setPreRunBarriers(ctx);
 	m_vol->setPreRunBarriers(ctx);
 
 
-	// SM
+	// Batch
 	m_sm->run(ctx);
 	m_sm->run(ctx);
-
 	m_ms->run(ctx);
 	m_ms->run(ctx);
+	m_vel->run(ctx);
 
 
 	m_ms->setPostRunBarriers(ctx);
 	m_ms->setPostRunBarriers(ctx);
 	m_sm->setPostRunBarriers(ctx);
 	m_sm->setPostRunBarriers(ctx);
@@ -258,14 +263,14 @@ Error Renderer::render(RenderingContext& ctx)
 
 
 	m_fsUpscale->run(ctx);
 	m_fsUpscale->run(ctx);
 
 
-	cmdb->setTextureSurfaceBarrier(m_is->getRt(),
+	cmdb->setTextureSurfaceBarrier(m_is->getRt(getFrameCount() % 2),
 		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
 		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
 		TextureUsageBit::SAMPLED_FRAGMENT,
 		TextureUsageBit::SAMPLED_FRAGMENT,
 		TextureSurfaceInfo(0, 0, 0, 0));
 		TextureSurfaceInfo(0, 0, 0, 0));
 
 
 	m_downscale->run(ctx);
 	m_downscale->run(ctx);
 
 
-	cmdb->setTextureSurfaceBarrier(m_is->getRt(),
+	cmdb->setTextureSurfaceBarrier(m_is->getRt(getFrameCount() % 2),
 		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 		TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
 		TextureUsageBit::SAMPLED_COMPUTE,
 		TextureUsageBit::SAMPLED_COMPUTE,
 		TextureSurfaceInfo(m_is->getRtMipmapCount() - 1, 0, 0, 0));
 		TextureSurfaceInfo(m_is->getRtMipmapCount() - 1, 0, 0, 0));
@@ -275,7 +280,7 @@ Error Renderer::render(RenderingContext& ctx)
 	m_smaa->m_edge.run(ctx);
 	m_smaa->m_edge.run(ctx);
 
 
 	// Barriers
 	// Barriers
-	cmdb->setTextureSurfaceBarrier(m_is->getRt(),
+	cmdb->setTextureSurfaceBarrier(m_is->getRt(getFrameCount() % 2),
 		TextureUsageBit::SAMPLED_COMPUTE,
 		TextureUsageBit::SAMPLED_COMPUTE,
 		TextureUsageBit::SAMPLED_FRAGMENT,
 		TextureUsageBit::SAMPLED_FRAGMENT,
 		TextureSurfaceInfo(m_is->getRtMipmapCount() - 1, 0, 0, 0));
 		TextureSurfaceInfo(m_is->getRtMipmapCount() - 1, 0, 0, 0));
@@ -300,6 +305,7 @@ Error Renderer::render(RenderingContext& ctx)
 
 
 	ANKI_CHECK(m_pps->run(ctx));
 	ANKI_CHECK(m_pps->run(ctx));
 
 
+	m_prevFrameViewProjMatrix = frc.getViewProjectionMatrix();
 	++m_frameCount;
 	++m_frameCount;
 
 
 	return ErrorCode::NONE;
 	return ErrorCode::NONE;

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

@@ -32,6 +32,7 @@ class RenderingContext
 public:
 public:
 	/// Active frustum.
 	/// Active frustum.
 	FrustumComponent* m_frustumComponent ANKI_DBG_NULLIFY_PTR;
 	FrustumComponent* m_frustumComponent ANKI_DBG_NULLIFY_PTR;
+	Mat4 m_prevFrameViewProjMatrix;
 
 
 	CommandBufferPtr m_commandBuffer; ///< Primary command buffer.
 	CommandBufferPtr m_commandBuffer; ///< Primary command buffer.
 
 
@@ -208,6 +209,11 @@ public:
 		return *m_smaa;
 		return *m_smaa;
 	}
 	}
 
 
+	Velocity& getVelocity()
+	{
+		return *m_vel;
+	}
+
 	U32 getWidth() const
 	U32 getWidth() const
 	{
 	{
 		return m_width;
 		return m_width;
@@ -392,6 +398,7 @@ private:
 	UniquePtr<Bloom> m_bloom;
 	UniquePtr<Bloom> m_bloom;
 	UniquePtr<Pps> m_pps; ///< Postprocessing rendering stage
 	UniquePtr<Pps> m_pps; ///< Postprocessing rendering stage
 	UniquePtr<Dbg> m_dbg; ///< Debug stage.
 	UniquePtr<Dbg> m_dbg; ///< Debug stage.
+	UniquePtr<Velocity> m_vel;
 	/// @}
 	/// @}
 
 
 	U32 m_width;
 	U32 m_width;
@@ -415,6 +422,8 @@ private:
 
 
 	Bool8 m_willDrawToDefaultFbo = false;
 	Bool8 m_willDrawToDefaultFbo = false;
 
 
+	Mat4 m_prevFrameViewProjMatrix = Mat4::getIdentity();
+
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 	ANKI_USE_RESULT Error initInternal(const ConfigSet& initializer);
 
 
 	ANKI_USE_RESULT Error buildCommandBuffers(RenderingContext& ctx);
 	ANKI_USE_RESULT Error buildCommandBuffers(RenderingContext& ctx);

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

@@ -91,7 +91,7 @@ void SmaaEdge::run(RenderingContext& ctx)
 
 
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	cmdb->setViewport(0, 0, m_r->getWidth(), m_r->getHeight());
 	cmdb->bindShaderProgram(m_prog);
 	cmdb->bindShaderProgram(m_prog);
-	cmdb->bindTexture(0, 0, m_r->getIs().getRt());
+	cmdb->bindTexture(0, 0, m_r->getIs().getRt(m_r->getFrameCount() % 2));
 
 
 	cmdb->setStencilOperations(
 	cmdb->setStencilOperations(
 		FaceSelectionBit::FRONT, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::REPLACE);
 		FaceSelectionBit::FRONT, StencilOperation::KEEP, StencilOperation::KEEP, StencilOperation::REPLACE);

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

@@ -61,7 +61,7 @@ void Tm::run(RenderingContext& ctx)
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
 	cmdb->bindShaderProgram(m_prog);
 	cmdb->bindShaderProgram(m_prog);
 	cmdb->bindStorageBuffer(0, 0, m_luminanceBuff, 0);
 	cmdb->bindStorageBuffer(0, 0, m_luminanceBuff, 0);
-	cmdb->bindTexture(0, 0, m_r->getIs().getRt());
+	cmdb->bindTexture(0, 0, m_r->getIs().getRt(m_r->getFrameCount() % 2));
 
 
 	cmdb->dispatchCompute(1, 1, 1);
 	cmdb->dispatchCompute(1, 1, 1);
 }
 }

+ 83 - 0
src/anki/renderer/Velocity.cpp

@@ -0,0 +1,83 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include <anki/renderer/Velocity.h>
+#include <anki/renderer/Renderer.h>
+#include <anki/renderer/DepthDownscale.h>
+#include <anki/scene/FrustumComponent.h>
+
+namespace anki
+{
+
+Velocity::~Velocity()
+{
+}
+
+Error Velocity::init(const ConfigSet& cfg)
+{
+	ANKI_LOGI("Initializing velocity pass");
+
+	Error err = initInternal(cfg);
+	if(err)
+	{
+		ANKI_LOGE("Failed to initialize velocity pass");
+	}
+
+	return err;
+}
+
+Error Velocity::initInternal(const ConfigSet& cfg)
+{
+	U width = m_r->getWidth() / 2, height = m_r->getHeight() / 2;
+	ANKI_CHECK(m_r->createShaderf("shaders/Velocity.frag.glsl", m_frag, "#define FB_SIZE uvec2(%uu, %uu)", 
+		width, height));
+
+	m_r->createDrawQuadShaderProgram(m_frag->getGrShader(), m_prog);
+
+	m_r->createRenderTarget(width,
+		height,
+		PixelFormat(ComponentFormat::R8G8, TransformFormat::UNORM),
+		TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
+		SamplingFilter::LINEAR,
+		1,
+		m_rt);
+
+	FramebufferInitInfo fbInit;
+	fbInit.m_colorAttachmentCount = 1;
+	fbInit.m_colorAttachments[0].m_texture = m_rt;
+	fbInit.m_colorAttachments[0].m_loadOperation = AttachmentLoadOperation::DONT_CARE;
+
+	m_fb = getGrManager().newInstance<Framebuffer>(fbInit);
+
+	return ErrorCode::NONE;
+}
+
+void Velocity::run(RenderingContext& ctx)
+{
+	CommandBufferPtr& cmdb = ctx.m_commandBuffer;
+
+	struct Uniforms
+	{
+		Mat4 m_prevInvViewProjMat;
+		Mat4 m_crntViewProjMat;
+	};
+
+	TransientMemoryToken token;
+	Uniforms* unis = static_cast<Uniforms*>(getGrManager().allocateFrameTransientMemory(sizeof(Uniforms), 
+		BufferUsageBit::UNIFORM_ALL, token));
+
+	unis->m_prevInvViewProjMat = ctx.m_prevFrameViewProjMatrix.getInverse();
+	unis->m_crntViewProjMat = ctx.m_frustumComponent->getViewProjectionMatrix();
+
+	cmdb->bindTexture(0, 0, m_r->getDepthDownscale().m_hd.m_depthRt);
+	cmdb->bindUniformBuffer(0, 0, token);
+	cmdb->setViewport(0, 0, m_r->getWidth() / 2, m_r->getHeight() / 2);
+	cmdb->bindShaderProgram(m_prog);
+	cmdb->beginRenderPass(m_fb);
+	m_r->drawQuad(cmdb);
+	cmdb->endRenderPass();
+}
+
+} // end namespace anki

+ 53 - 0
src/anki/renderer/Velocity.h

@@ -0,0 +1,53 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#pragma once
+
+#include <anki/renderer/RenderingPass.h>
+
+namespace anki
+{
+
+/// @addtogroup renderer
+/// @{
+
+/// XXX
+class Velocity : public RenderingPass
+{
+anki_internal:
+	TexturePtr m_rt;
+
+	Velocity(Renderer* r)
+		: RenderingPass(r)
+	{
+	}
+
+	~Velocity();
+
+	ANKI_USE_RESULT Error init(const ConfigSet& cfg);
+
+	void setPreRunBarriers(RenderingContext& ctx)
+	{
+		// XXX
+	}
+
+	void run(RenderingContext& ctx);
+
+	void setPostRunBarriers(RenderingContext& ctx)
+	{
+		// XXX
+	}
+
+private:
+	ShaderResourcePtr m_frag;
+	ShaderProgramPtr m_prog;
+	FramebufferPtr m_fb;
+
+	Error initInternal(const ConfigSet& cfg);
+};
+/// @}
+
+} // end namespace anki
+