Panagiotis Christopoulos Charitos 11 anni fa
parent
commit
27c9553e62

+ 1 - 0
include/anki/renderer/Is.h

@@ -27,6 +27,7 @@ class SpotLight;
 class Is: private RenderingPass
 {
 	friend class WriteLightsJob;
+	friend class Sslr;
 
 public:
 	Is(Renderer* r);

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

@@ -9,6 +9,7 @@
 #include "anki/renderer/Ssao.h"
 #include "anki/renderer/Bl.h"
 #include "anki/renderer/Lf.h"
+#include "anki/renderer/Sslr.h"
 
 namespace anki {
 
@@ -83,6 +84,7 @@ private:
 	Ssao m_ssao;
 	Bl m_bl;
 	Lf m_lf;
+	Sslr m_sslr;
 	/// @}
 
 	GlFramebufferHandle m_fb;

+ 5 - 0
include/anki/renderer/Sslr.h

@@ -28,8 +28,13 @@ private:
 	GlFramebufferHandle m_fb;
 	GlTextureHandle m_rt;
 
+	// 1st pass
 	ProgramResourcePointer m_reflectionFrag;
 	GlProgramPipelineHandle m_reflectionPpline;
+
+	// 2nd pass: blit
+	ProgramResourcePointer m_blitFrag;
+	GlProgramPipelineHandle m_blitPpline;
 };
 
 /// @}

+ 9 - 10
shaders/PpsSsao.frag.glsl

@@ -35,14 +35,13 @@ layout(std140, row_major, binding = 0) readonly buffer commonBlock
 layout(binding = 0) uniform sampler2D uMsDepthRt;
 layout(binding = 1) uniform sampler2D uMsRt;
 layout(binding = 2) uniform sampler2D uNoiseMap;
-/// @}
 
 #define RADIUS 0.5
 #define DARKNESS_MULTIPLIER 1.0 // Initial is 1.0 but the bigger it is the more
                                 // darker the SSAO factor gets
 
 // Get normal
-vec3 getNormal(in vec2 uv)
+vec3 readNormal(in vec2 uv)
 {
 	vec3 normal;
 	readNormalFromGBuffer(uMsRt, uv, normal);
@@ -50,7 +49,7 @@ vec3 getNormal(in vec2 uv)
 }
 
 // Read the noise tex
-vec3 getRandom(in vec2 uv)
+vec3 readRandom(in vec2 uv)
 {
 	const vec2 tmp = vec2(
 		float(WIDTH) / float(NOISE_MAP_SIZE), 
@@ -61,8 +60,8 @@ vec3 getRandom(in vec2 uv)
 	return noise;
 }
 
-// Get position in view space
-vec3 getPosition(in vec2 uv)
+// Read position in view space
+vec3 readPosition(in vec2 uv)
 {
 	float depth = textureRt(uMsDepthRt, uv).r;
 
@@ -77,7 +76,7 @@ vec3 getPosition(in vec2 uv)
 	return fragPosVspace;
 }
 
-float getZ(in vec2 uv)
+float readZ(in vec2 uv)
 {
 	float depth = textureRt(uMsDepthRt, uv).r;
 	float z = -uPlanes.y / (uPlanes.x + depth);
@@ -86,10 +85,10 @@ float getZ(in vec2 uv)
 
 void main(void)
 {
-	vec3 origin = getPosition(inTexCoords);
+	vec3 origin = readPosition(inTexCoords);
 
-	vec3 normal = getNormal(inTexCoords);
-	vec3 rvec = getRandom(inTexCoords);
+	vec3 normal = readNormal(inTexCoords);
+	vec3 rvec = readRandom(inTexCoords);
 	
 	vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
 	vec3 bitangent = cross(normal, tangent);
@@ -110,7 +109,7 @@ void main(void)
 		offset.xy = offset.xy * 0.5 + 0.5;
 
 		// get sample depth:
-		float sampleDepth = getZ(offset.xy);
+		float sampleDepth = readZ(offset.xy);
 
 		// range check & accumulate:
 		const float ADVANCE = DARKNESS_MULTIPLIER / float(KERNEL_SIZE);

+ 96 - 0
shaders/PpsSslr.frag.glsl

@@ -0,0 +1,96 @@
+// SSLR fragment shader
+#pragma anki type frag
+#pragma anki include "shaders/Common.glsl"
+#pragma anki include "shaders/LinearDepth.glsl"
+
+layout(location = 0) in vec2 inTexCoords;
+
+layout(location = 0) out vec3 outColor;
+
+layout(std140, binding = 0) readonly buffer bCommon
+{
+	/// Packs:
+	/// - x: uZNear. For the calculation of frag pos in view space
+	/// - zw: Planes. For the calculation of frag pos in view space
+	vec4 uNearPlanesComp;
+
+	/// For the calculation of frag pos in view space. The xy is the 
+	/// uLimitsOfNearPlane and the zw is an optimization see PpsSsao.glsl and 
+	/// r403 for the clean one
+	vec4 uLimitsOfNearPlaneComp;
+
+	/// The projection matrix
+	mat4 uProjectionMatrix;
+};
+
+#define uZNear uNearPlanesComp.x
+#define uZFar uNearPlanesComp.y
+#define uPlanes uNearPlanesComp.zw
+#define uLimitsOfNearPlane uLimitsOfNearPlaneComp.xy
+#define uLimitsOfNearPlane2 uLimitsOfNearPlaneComp.zw
+
+layout(binding = 0) uniform sampler2D uIsRt;
+layout(binding = 1) uniform sampler2D uMsDepthRt;
+layout(binding = 2) uniform sampler2D uMsRt;
+
+// Get normal
+vec3 readNormal(in vec2 uv)
+{
+	vec3 normal;
+	readNormalFromGBuffer(uMsRt, uv, normal);
+	return normal;
+}
+
+// Get position in view space
+vec3 readPosition(in vec2 uv)
+{
+	float depth = textureRt(uMsDepthRt, uv).r;
+
+	vec3 fragPosVspace;
+	fragPosVspace.z = -uPlanes.y / (uPlanes.x + depth);
+	
+	fragPosVspace.xy = (uv * uLimitsOfNearPlane2) - uLimitsOfNearPlane;
+	
+	float sc = -fragPosVspace.z;
+	fragPosVspace.xy *= sc;
+
+	return fragPosVspace;
+}
+
+float readZ(in vec2 uv)
+{
+	float depth = textureRt(uMsDepthRt, uv).r;
+	float z = -uPlanes.y / (uPlanes.x + depth);
+	return z;
+}
+
+void main()
+{
+	vec3 normal = readNormal(inTexCoords);
+	vec3 pos = readPosition(inTexCoords);
+
+	// Reflection direction
+	vec3 rDir = normalize(reflect(pos, normal));
+
+	vec3 sample = pos;
+	for(int i = 0; i < 20; i++)
+	{
+		sample += rDir;
+
+		vec4 sampleNdc = uProjectionMatrix * vec4(sample, 1.0);
+		sampleNdc.xy /= sampleNdc.w;
+		sampleNdc.xy = sampleNdc.xy * 0.5 + 0.5;
+
+		depth = readZ(sampleNdc.xy);
+
+		float diffDepth = sampleNdc.z - depth;
+
+		if(dDepth < 0.0)
+		{
+			outColor = texture(uIsRt, sampleNdc.xy);
+			return;
+		}
+	}
+
+	outColor = vec3(0.0);
+}

+ 1 - 1
src/renderer/Lf.cpp

@@ -133,7 +133,7 @@ void Lf::initInternal(const RendererInitializer& initializer)
 	m_blitPpline = m_r->createDrawQuadProgramPipeline(
 		m_blitFrag->getGlProgram());
 
-	jobs.flush();
+	jobs.finish();
 }
 
 //==============================================================================

+ 10 - 2
src/renderer/Pps.cpp

@@ -12,7 +12,8 @@ Pps::Pps(Renderer* r)
 		m_hdr(r), 
 		m_ssao(r), 
 		m_bl(r), 
-		m_lf(r)
+		m_lf(r),
+		m_sslr(r)
 {}
 
 //==============================================================================
@@ -33,6 +34,7 @@ void Pps::initInternal(const RendererInitializer& initializer)
 	m_ssao.init(initializer);
 	m_hdr.init(initializer);
 	m_lf.init(initializer);
+	m_sslr.init(initializer);
 
 	// FBO
 	GlManager& gl = GlManagerSingleton::get();
@@ -60,7 +62,7 @@ void Pps::initInternal(const RendererInitializer& initializer)
 
 	m_ppline = m_r->createDrawQuadProgramPipeline(m_frag->getGlProgram());
 
-	jobs.flush();
+	jobs.finish();
 }
 
 //==============================================================================
@@ -87,6 +89,12 @@ void Pps::run(GlJobChainHandle& jobs)
 		m_ssao.run(jobs);
 	}
 
+	// Then SSLR because HDR depends on it
+	if(m_sslr.getEnabled())
+	{
+		m_sslr.run(jobs);
+	}
+
 	if(m_hdr.getEnabled())
 	{
 		m_hdr.run(jobs);

+ 4 - 1
src/renderer/Renderer.cpp

@@ -45,6 +45,9 @@ RendererInitializer::RendererInitializer()
 	newOption("pps.ssao.renderingQuality", 0.3);
 	newOption("pps.ssao.blurringIterationsNum", 2);
 
+	newOption("pps.sslr.enabled", true);
+	newOption("pps.sslr.renderingQuality", 0.2);
+
 	newOption("pps.bl.enabled", true);
 	newOption("pps.bl.blurringIterationsNum", 2);
 	newOption("pps.bl.sideBlurFactor", 1.0);
@@ -300,7 +303,7 @@ void Renderer::createRenderTarget(U32 w, U32 h, GLenum internalFormat,
 	GlManager& gl = GlManagerSingleton::get();
 	GlJobChainHandle jobs(&gl);
 	rt = GlTextureHandle(jobs, init);
-	jobs.flush();
+	jobs.finish();
 }
 
 //==============================================================================

+ 26 - 2
src/renderer/Sslr.cpp

@@ -32,7 +32,7 @@ void Sslr::init(const RendererInitializer& initializer)
 		m_reflectionFrag->getGlProgram());
 
 	// Fb
-	m_r->createRenderTarget(m_width, m_height, GL_RGB, GL_RGB8, 
+	m_r->createRenderTarget(m_width, m_height, GL_RGB8, GL_RGB, 
 		GL_UNSIGNED_BYTE, 1, m_rt);
 
 	GlManager& gl = GlManagerSingleton::get();
@@ -40,6 +40,11 @@ void Sslr::init(const RendererInitializer& initializer)
 
 	m_fb = GlFramebufferHandle(jobs, {{m_rt, GL_COLOR_ATTACHMENT0}});
 
+	// Blit
+	m_blitFrag.load("shaders/Blit.frag.glsl");
+	m_blitPpline = m_r->createDrawQuadProgramPipeline(
+		m_blitFrag->getGlProgram());
+
 	jobs.finish();
 }
 
@@ -48,12 +53,31 @@ void Sslr::run(GlJobChainHandle& jobs)
 {
 	ANKI_ASSERT(m_enabled);
 
+	// Compute the reflection
+	//
 	m_fb.bind(jobs, true);
 	jobs.setViewport(0, 0, m_width, m_height);
 
+	m_reflectionPpline.bind(jobs);
+	m_r->getIs().getRt().bind(jobs, 0);
+	m_r->getMs().getDepthRt().bind(jobs, 1);
+
 	m_r->drawQuad(jobs);
-}
 
+	// Write the reflection back to IS RT
+	//
+	m_r->getIs().m_fb.bind(jobs, false);
+
+	jobs.enableBlend(true);
+	jobs.setBlendFunctions(GL_ONE, GL_ONE);
+
+	m_rt.bind(jobs, 0);
+
+	m_blitPpline.bind(jobs);
+	m_r->drawQuad(jobs);
+
+	jobs.enableBlend(false);
+}
 
 } // end namespace anki