浏览代码

Sslr is working

Panagiotis Christopoulos Charitos 11 年之前
父节点
当前提交
b5cd74b359

+ 2 - 1
include/anki/renderer/MainRenderer.h

@@ -35,7 +35,8 @@ private:
 	ProgramResourcePointer m_blitFrag;
 	GlProgramPipelineHandle m_blitPpline;
 
-	GlJobChainInitHints m_jobsInitHints; ///< Optimize job chain
+	/// Optimize job chain
+	Array<GlJobChainInitHints, JOB_CHAINS_COUNT> m_jobsInitHints; 
 
 	void takeScreenshotTga(const char* filename);
 	void initGl();

+ 10 - 45
include/anki/renderer/Renderer.h

@@ -36,6 +36,10 @@ public:
 class Renderer
 {
 public:
+	/// Cut the job submition into multiple chains. We want to avoid feeding
+	/// GL with a huge job chain
+	static const U32 JOB_CHAINS_COUNT = 2;
+		
 	Renderer();
 	~Renderer();
 
@@ -136,21 +140,9 @@ public:
 		return m_sceneDrawer;
 	}
 
-	const Vec2& getPlanes() const
+	Timestamp getProjectionParametersUpdateTimestamp() const
 	{
-		return m_planes;
-	}
-	const Vec2& getLimitsOfNearPlane() const
-	{
-		return m_limitsOfNearPlane;
-	}
-	const Vec2& getLimitsOfNearPlane2() const
-	{
-		return m_limitsOfNearPlane2;
-	}
-	Timestamp getPlanesUpdateTimestamp() const
-	{
-		return m_planesUpdateTimestamp;
+		return m_projectionParamsUpdateTimestamp;
 	}
 	const Vec4& getProjectionParameters() const
 	{
@@ -209,7 +201,8 @@ public:
 	void init(const RendererInitializer& initializer);
 
 	/// This function does all the rendering stages and produces a final FAI
-	void render(SceneGraph& scene, GlJobChainHandle& jobs);
+	void render(SceneGraph& scene, 
+		Array<GlJobChainHandle, JOB_CHAINS_COUNT>& jobs);
 
 	/// My version of gluUnproject
 	/// @param windowCoords Window screen coords
@@ -227,25 +220,6 @@ public:
 
 	void drawQuadInstanced(GlJobChainHandle& jobs, U32 primitiveCount);
 
-	/// Calculate the planes needed for the calculation of the fragment
-	/// position z in view space. Having the fragment's depth, the camera's
-	/// zNear and zFar the z of the fragment is being calculated inside the
-	/// fragment shader from:
-	/// @code z = (- zFar * zNear) / (zFar - depth * (zFar - zNear))
-	/// @endcode
-	/// The above can be optimized and this method actually pre-calculates a
-	/// few things in order to lift a few calculations from the fragment
-	/// shader. So the z is:
-	/// @code z =  -planes.y / (planes.x + depth) @endcode
-	/// @param[in] cameraRange The zNear, zFar
-	/// @param[out] planes The planes
-	static void calcPlanes(const Vec2& cameraRange, Vec2& planes);
-
-	/// Calculates two values needed for the calculation of the fragment
-	/// position in view space.
-	static void calcLimitsOfNearPlane(const class PerspectiveCamera& cam,
-		Vec2& limitsOfNearPlane);
-
 	/// Get the LOD given the distance of an object from the camera
 	F32 calculateLod(F32 distance) const
 	{
@@ -294,21 +268,12 @@ private:
 	/// @name Optimization vars
 	/// Used in other stages
 	/// @{
-	Timestamp m_planesUpdateTimestamp = getGlobTimestamp();
-
-	/// Used to to calculate the frag pos in view space inside a few shader
-	/// programs
-	Vec2 m_planes;
-	/// Used to to calculate the frag pos in view space inside a few shader
-	/// programs
-	Vec2 m_limitsOfNearPlane;
-	/// Used to to calculate the frag pos in view space inside a few shader
-	/// programs
-	Vec2 m_limitsOfNearPlane2;
 
 	/// A vector that contains useful numbers for calculating the view space
 	/// position from the depth
 	Vec4 m_projectionParams;
+
+	Timestamp m_projectionParamsUpdateTimestamp = getGlobTimestamp();
 	/// @}
 
 	SceneGraph* m_scene; ///< Current scene

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

@@ -18,6 +18,7 @@ class Ssao: public OptionalRenderingPass
 {
 	friend class Pps;
 	friend class Sslr;
+	friend class MainRenderer;
 
 private:
 	U32 m_width, m_height; ///< Blur passes size

+ 1 - 2
shaders/Final.frag.glsl

@@ -14,7 +14,6 @@ layout(location = 0) out vec3 outFragColor;
 void main()
 {
 	vec3 col = textureRt(uRasterImage, inTexCoords).rgb;
-	//vec3 col = vec3(textureRt(uRasterImage, inTexCoords).r);
-	//lowp vec3 col = vec3(readAndUnpackNormal(rasterImage, vTexCoords) * 0.5 + 0.5);
+	//vec3 col = vec3(textureRt(uRasterImage, inTexCoords).a);
 	outFragColor = col;
 }

+ 17 - 5
shaders/Pack.glsl

@@ -48,8 +48,8 @@ void writeGBuffer(
 	out vec4 fai0, out vec4 fai1)
 {
 	vec3 unorm = normal * 0.5 + 0.5;
-	fai0 = vec4(diffColor, specColor);
-	fai1 = vec4(unorm.xyz, specPower / MAX_SPECULARITY);
+	fai0 = vec4(diffColor, specPower / MAX_SPECULARITY);
+	fai1 = vec4(unorm.xyz, specColor);
 }
 
 // Read from the G buffer
@@ -61,11 +61,11 @@ void readGBuffer(
 {
 	vec4 comp = textureRt(fai0, texCoord);
 	diffColor = comp.rgb;
-	specColor = comp.a;
+	specPower = comp.w * MAX_SPECULARITY;
 
 	comp = textureRt(fai1, texCoord);
 	normal = normalize(comp.xyz * 2.0 - 1.0);
-	specPower = comp.w * MAX_SPECULARITY;
+	specColor = comp.a;
 }
 
 // Read only normal from G buffer
@@ -74,5 +74,17 @@ void readNormalFromGBuffer(
 	in vec2 texCoord,
 	out vec3 normal)
 {
-	normal = normalize(textureRt(fai1, texCoord).xyz);
+	normal = normalize(textureRt(fai1, texCoord).xyz * 2.0 - 1.0);
+}
+
+// Read only normal and specular color from G buffer
+void readNormalSpecularColorFromGBuffer(
+	in sampler2D fai1,
+	in vec2 texCoord,
+	out vec3 normal,
+	out float specColor)
+{
+	vec4 comp = textureRt(fai1, texCoord);
+	normal = normalize(comp.xyz * 2.0 - 1.0);
+	specColor = comp.a;
 }

+ 2 - 2
shaders/PpsSsao.frag.glsl

@@ -90,8 +90,8 @@ void main(void)
 		// project sample position:
 		vec4 offset = vec4(sample_, 1.0);
 		offset = uProjectionMatrix * offset;
-		offset.xy /= offset.w;
-		offset.xy = offset.xy * 0.5 + 0.5;
+		offset.xy = offset.xy / (2.0 * offset.w) + 0.5; // persp div & 
+		                                                // to NDC -> [0, 1]
 
 		// get sample depth:
 		float sampleDepth = readZ(offset.xy);

+ 40 - 12
shaders/PpsSslr.frag.glsl

@@ -20,14 +20,6 @@ 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;
-}
-
 // Returns the Z of the position in view space
 float readZ(in vec2 uv)
 {
@@ -50,16 +42,42 @@ vec3 readPosition(in vec2 uv)
 	return fragPosVspace;
 }
 
+vec3 project(vec3 p)
+{
+	vec4 a = uProjectionMatrix * vec4(p, 1.0);
+	a.xyz /= a.w;
+	return a.xyz;
+}
+
 void main()
 {
-	vec3 normal = readNormal(inTexCoords);
+	vec3 normal;
+	float specColor;
+	readNormalSpecularColorFromGBuffer(uMsRt, inTexCoords, normal, specColor);
+
+	if(specColor < 0.5)
+	{
+		outColor = vec3(0.0);
+		return;
+	}
+
 	vec3 posv = readPosition(inTexCoords);
 
 	// Reflection direction
-	vec3 rDir = normalize(reflect(posv, normal));
+	vec3 rDir = reflect(normalize(posv), normal);
+
+	/*vec3 startpos = posv;
+	vec3 endpos = startpos + rDir * 1.0;
 
+	vec3 startposproj = project(startpos);
+	vec3 endposproj = project(endpos);
+
+	outColor = textureRt(uIsRt, endposproj.xy * 0.5 + 0.5).rgb;
+	outColor = vec3(0.0);*/
+
+#if 1
 	vec3 pos = posv;
-	for(int i = 0; i < 200; i++)
+	for(int i = 0; i < 500; i++)
 	{
 		pos += rDir * 0.1;
 
@@ -80,10 +98,20 @@ void main()
 
 		if(diffDepth > 0.0)
 		{
-			outColor = textureRt(uIsRt, posClip.xy).rgb;
+			if(diffDepth > 0.001)
+			{
+				break;
+			}
+
+			float factor = 1.0 - length(posNdc.xy);
+
+			outColor = textureRt(uIsRt, posClip.xy).rgb * (factor * specColor);
+			//outColor = vec3(diffDepth);
 			return;
 		}
 	}
 
+	//outColor = vec3(0.5, 0.0, 0.0);
 	outColor = vec3(0.0);
+#endif
 }

+ 27 - 13
src/renderer/Is.cpp

@@ -549,9 +549,10 @@ void Is::lightPass(GlJobChainHandle& jobs)
 	clamp(visibleSpotLightsCount, m_maxSpotLights);
 	clamp(visibleSpotTexLightsCount, m_maxSpotTexLights);
 
-	ANKI_COUNTER_INC(RENDERER_LIGHTS_COUNT, 
-		U64(visiblePointLightsCount + visibleSpotLightsCount 
-		+ visibleSpotTexLightsCount));
+	U totalLightsCount = visiblePointLightsCount + visibleSpotLightsCount 
+		+ visibleSpotTexLightsCount;
+
+	ANKI_COUNTER_INC(RENDERER_LIGHTS_COUNT, U64(totalLightsCount));
 
 	//
 	// Do shadows pass
@@ -583,8 +584,12 @@ void Is::lightPass(GlJobChainHandle& jobs)
 	// Fire the super jobs
 	Array<WriteLightsJob, Threadpool::MAX_THREADS> tjobs;
 
-	GlClientBufferHandle lightsClientBuff(
-		jobs, spotTexLightsOffset + spotTexLightsSize, nullptr);
+	GlClientBufferHandle lightsClientBuff;
+	if(totalLightsCount > 0)
+	{
+		lightsClientBuff = GlClientBufferHandle(
+			jobs, spotTexLightsOffset + spotTexLightsSize, nullptr);
+	}
 
 	GlClientBufferHandle tilesClientBuff(jobs, m_tilesBuff.getSize(), nullptr);
 
@@ -615,12 +620,18 @@ void Is::lightPass(GlJobChainHandle& jobs)
 
 		if(i == 0)
 		{
-			job.m_pointLights = (shader::PointLight*)(
-				(U8*)lightsClientBuff.getBaseAddress() + pointLightsOffset);
-			job.m_spotLights = (shader::SpotLight*)(
-				(U8*)lightsClientBuff.getBaseAddress() + spotLightsOffset);
-			job.m_spotTexLights = (shader::SpotTexLight*)(
-				(U8*)lightsClientBuff.getBaseAddress() + spotTexLightsOffset);
+			if(totalLightsCount > 0)
+			{
+				job.m_pointLights = (shader::PointLight*)(
+					(U8*)lightsClientBuff.getBaseAddress() 
+					+ pointLightsOffset);
+				job.m_spotLights = (shader::SpotLight*)(
+					(U8*)lightsClientBuff.getBaseAddress() 
+					+ spotLightsOffset);
+				job.m_spotTexLights = (shader::SpotTexLight*)(
+					(U8*)lightsClientBuff.getBaseAddress() 
+					+ spotTexLightsOffset);
+			}
 
 			job.m_tileBuffer = (U8*)tilesClientBuff.getBaseAddress();
 
@@ -679,8 +690,11 @@ void Is::lightPass(GlJobChainHandle& jobs)
 	}
 
 	// Write BOs
-	m_lightsBuff.write(jobs,
-		lightsClientBuff, 0, 0, spotTexLightsOffset + spotTexLightsSize);
+	if(totalLightsCount > 0)
+	{
+		m_lightsBuff.write(jobs,
+			lightsClientBuff, 0, 0, spotTexLightsOffset + spotTexLightsSize);
+	}
 	m_tilesBuff.write(jobs, tilesClientBuff, 0, 0, tilesClientBuff.getSize());
 
 	//

+ 23 - 10
src/renderer/MainRenderer.cpp

@@ -45,7 +45,13 @@ void MainRenderer::render(SceneGraph& scene)
 	ANKI_COUNTER_START_TIMER(MAIN_RENDERER_TIME);
 
 	GlManager& gl = GlManagerSingleton::get();
-	GlJobChainHandle jobs(&gl, m_jobsInitHints);
+	Array<GlJobChainHandle, JOB_CHAINS_COUNT> jobs;
+	GlJobChainHandle& lastJobs = jobs[JOB_CHAINS_COUNT - 1];
+
+	for(U i = 0; i < JOB_CHAINS_COUNT; i++)
+	{
+		jobs[i] = GlJobChainHandle(&gl, m_jobsInitHints[i]);
+	}
 
 	Renderer::render(scene, jobs);
 
@@ -54,10 +60,10 @@ void MainRenderer::render(SceneGraph& scene)
 
 	if(notDrawnToDefault)
 	{
-		getDefaultFramebuffer().bind(jobs, false);
-		jobs.setViewport(0, 0, getWindowWidth(), getWindowHeight());
+		getDefaultFramebuffer().bind(lastJobs, false);
+		lastJobs.setViewport(0, 0, getWindowWidth(), getWindowHeight());
 
-		m_blitPpline.bind(jobs);
+		m_blitPpline.bind(lastJobs);
 
 		GlTextureHandle* rt;
 
@@ -71,16 +77,23 @@ void MainRenderer::render(SceneGraph& scene)
 		}
 
 		//rt = &getPps().getSslr().m_rt;
+		//rt = &getMs()._getRt0();
 
-		rt->setFilter(jobs, GlTextureHandle::Filter::LINEAR);
-		rt->bind(jobs, 0);
+		rt->setFilter(lastJobs, GlTextureHandle::Filter::LINEAR);
+		rt->bind(lastJobs, 0);
 
-		drawQuad(jobs);
+		drawQuad(lastJobs);
 	}
 
-	ANKI_ASSERT(jobs.getReferenceCount() == 1);
-	jobs.flush();
-	m_jobsInitHints = jobs.computeInitHints();
+	// Set the hints
+	for(U i = 0; i < JOB_CHAINS_COUNT; i++)
+	{
+		m_jobsInitHints[i] = jobs[i].computeInitHints();	
+	}
+
+	// Flush the last job chain
+	ANKI_ASSERT(lastJobs.getReferenceCount() == 1);
+	lastJobs.flush();
 
 	ANKI_COUNTER_STOP_TIMER_INC(MAIN_RENDERER_TIME);
 }

+ 15 - 40
src/renderer/Renderer.cpp

@@ -161,11 +161,12 @@ void Renderer::init(const RendererInitializer& initializer)
 	// Default FB
 	m_defaultFb = GlFramebufferHandle(jobs, {});
 
-	jobs.flush();
+	jobs.finish();
 }
 
 //==============================================================================
-void Renderer::render(SceneGraph& scene, GlJobChainHandle& jobs)
+void Renderer::render(SceneGraph& scene, 
+	Array<GlJobChainHandle, JOB_CHAINS_COUNT>& jobs)
 {
 	m_scene = &scene;
 	Camera& cam = m_scene->getActiveCamera();
@@ -173,46 +174,40 @@ void Renderer::render(SceneGraph& scene, GlJobChainHandle& jobs)
 	// Calc a few vars
 	//
 	Timestamp camUpdateTimestamp = cam.FrustumComponent::getTimestamp();
-	if(m_planesUpdateTimestamp < m_scene->getActiveCameraChangeTimestamp()
-		|| m_planesUpdateTimestamp < camUpdateTimestamp
-		|| m_planesUpdateTimestamp == 1)
+	if(m_projectionParamsUpdateTimestamp 
+			< m_scene->getActiveCameraChangeTimestamp()
+		|| m_projectionParamsUpdateTimestamp < camUpdateTimestamp
+		|| m_projectionParamsUpdateTimestamp == 1)
 	{
-		calcPlanes(Vec2(cam.getNear(), cam.getFar()), m_planes);
-
 		ANKI_ASSERT(cam.getCameraType() == Camera::CT_PERSPECTIVE);
-		const PerspectiveCamera& pcam =
-			static_cast<const PerspectiveCamera&>(cam);
-
-		calcLimitsOfNearPlane(pcam, m_limitsOfNearPlane);
-		m_limitsOfNearPlane2 = m_limitsOfNearPlane * 2.0;
-
 		computeProjectionParams(cam.getProjectionMatrix());
-
-		m_planesUpdateTimestamp = getGlobTimestamp();
+		m_projectionParamsUpdateTimestamp = getGlobTimestamp();
 	}
 
 	ANKI_COUNTER_START_TIMER(RENDERER_MS_TIME);
-	m_ms.run(jobs);
+	m_ms.run(jobs[0]);
+	ANKI_ASSERT(jobs[0].getReferenceCount() == 1);
+	jobs[0].flush();
 	ANKI_COUNTER_STOP_TIMER_INC(RENDERER_MS_TIME);
 
 	m_tiler.runMinMax(m_ms._getDepthRt());
 
 	ANKI_COUNTER_START_TIMER(RENDERER_IS_TIME);
-	m_is.run(jobs);
+	m_is.run(jobs[1]);
 	ANKI_COUNTER_STOP_TIMER_INC(RENDERER_IS_TIME);
 
-	m_bs.run(jobs);
+	m_bs.run(jobs[1]);
 
 	ANKI_COUNTER_START_TIMER(RENDERER_PPS_TIME);
 	if(m_pps.getEnabled())
 	{
-		m_pps.run(jobs);
+		m_pps.run(jobs[1]);
 	}
 	ANKI_COUNTER_STOP_TIMER_INC(RENDERER_PPS_TIME);
 
 	if(m_dbg.getEnabled())
 	{
-		m_dbg.run(jobs);
+		m_dbg.run(jobs[1]);
 	}
 
 	++m_framesNum;
@@ -252,26 +247,6 @@ Vec3 Renderer::unproject(const Vec3& windowCoords, const Mat4& modelViewMat,
 	return out.xyz();
 }
 
-//==============================================================================
-void Renderer::calcPlanes(const Vec2& cameraRange, Vec2& planes)
-{
-	F32 zNear = cameraRange.x();
-	F32 zFar = cameraRange.y();
-
-	F32 opt = zNear - zFar;
-
-	planes.x() = zFar / opt;
-	planes.y() = (zFar * zNear) / opt;
-}
-
-//==============================================================================
-void Renderer::calcLimitsOfNearPlane(const PerspectiveCamera& pcam,
-	Vec2& limitsOfNearPlane)
-{
-	limitsOfNearPlane.y() = tan(0.5 * pcam.getFovY());
-	limitsOfNearPlane.x() = tan(0.5 * pcam.getFovX());
-}
-
 //==============================================================================
 void Renderer::computeProjectionParams(const Mat4& m)
 {

+ 2 - 1
src/renderer/Ssao.cpp

@@ -243,7 +243,8 @@ void Ssao::run(GlJobChainHandle& jobs)
 	m_noiseTex.bind(jobs, 2);
 
 	// Write common block
-	if(m_commonUboUpdateTimestamp < m_r->getPlanesUpdateTimestamp()
+	if(m_commonUboUpdateTimestamp 
+			< m_r->getProjectionParametersUpdateTimestamp()
 		|| m_commonUboUpdateTimestamp < cam.FrustumComponent::getTimestamp()
 		|| m_commonUboUpdateTimestamp == 1)
 	{

+ 1 - 0
testapp/Main.cpp

@@ -637,6 +637,7 @@ void initSubsystems(int argc, char* argv[])
 	initializer.set("pps.hdr.blurringIterationsCount", 1);
 	initializer.set("pps.hdr.exposure", 8.0);
 	initializer.set("pps.hdr.samples", 9);
+	initializer.set("pps.sslr.renderingQuality", 0.5);
 	initializer.set("pps.ssao.blurringIterationsNum", 1);
 	initializer.set("pps.ssao.enabled", true);
 	initializer.set("pps.ssao.renderingQuality", 0.35);

+ 12 - 0
tools/scene/Model.cpp

@@ -318,6 +318,18 @@ void exportMaterial(
 			exporter.texrpath + normTex);
 	}
 
+	aiColor3D specCol = {0.0, 0.0, 0.0};
+	mtl.Get(AI_MATKEY_COLOR_SPECULAR, specCol);
+
+	float shininess = 0.0;
+	mtl.Get(AI_MATKEY_SHININESS, shininess);
+	
+
+	str = replaceAllString(str, "%specularColor%", 
+		std::to_string((specCol[0] + specCol[1] + specCol[2]) / 3.0));
+	str = replaceAllString(str, "%specularPower%", 
+		std::to_string(shininess));
+
 	str = replaceAllString(str, "%instanced%", (instanced) ? "1" : "0");
 	str = replaceAllString(str, "%diffuseMap%", exporter.texrpath + diffTex);
 

+ 1 - 1
tools/scene/diffNormTemplateMtl.h

@@ -31,7 +31,7 @@ R"(<?xml version="1.0" encoding="UTF-8" ?>
 			</includes>
 
 			<inputs>
-				<input><type>vec2</type><name>uSpecular</name><value>1.0 90.0</value></input>
+				<input><type>vec2</type><name>uSpecular</name><value>%specularColor% %specularPower%</value></input>
 				<input><type>float</type><name>uBlurring</name><value>0.0</value><const>1</const></input>
 				<input><type>sampler2D</type><name>uDiffuseMap</name><value>%diffuseMap%</value></input>
 				<input><type>sampler2D</type><name>uNormalMap</name><value>%normalMap%</value></input>

+ 1 - 1
tools/scene/diffTemplateMtl.h

@@ -30,7 +30,7 @@ R"(<?xml version="1.0" encoding="UTF-8" ?>
 			</includes>
 
 			<inputs>
-				<input><type>vec2</type><name>uSpecular</name><value>1.0 90.0</value></input>
+				<input><type>vec2</type><name>uSpecular</name><value>%specularColor% %specularPower%</value></input>
 				<input><type>float</type><name>uBlurring</name><value>0.0</value><const>1</const></input>
 				<input><type>sampler2D</type><name>uDiffuseMap</name><value>%diffuseMap%</value></input>
 			</inputs>