Panagiotis Christopoulos Charitos 11 лет назад
Родитель
Сommit
241b35425f

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

@@ -152,6 +152,10 @@ public:
 	{
 		return m_planesUpdateTimestamp;
 	}
+	const Vec4& getProjectionParameters() const
+	{
+		return m_projectionParams;
+	}
 
 	U getSamples() const
 	{
@@ -301,6 +305,10 @@ private:
 	/// 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;
 	/// @}
 
 	SceneGraph* m_scene; ///< Current scene
@@ -312,6 +320,8 @@ private:
 	std::string m_shaderPostProcessorString;
 
 	GlFramebufferHandle m_defaultFb;
+
+	void computeProjectionParams(const Mat4& projMat);
 };
 
 /// @}

+ 2 - 2
shaders/Common.glsl

@@ -16,8 +16,8 @@ precision DEFAULT_FLOAT_PRECISION float;
 precision DEFAULT_FLOAT_PRECISION int;
 
 // Read from a render target texture
-#define textureRt(tex_, texc_) texture(tex_, texc_)
-//#define textureRt(tex_, texc_) textureLod(tex_, texc_, 0.0)
+//#define textureRt(tex_, texc_) texture(tex_, texc_)
+#define textureRt(tex_, texc_) textureLod(tex_, texc_, 0.0)
 
 #define POSITION_LOCATION 0
 #define NORMAL_LOCATION 1

+ 1 - 9
shaders/IsCommon.glsl

@@ -48,15 +48,7 @@ struct Lights
 // Common uniforms between lights
 layout(std140, row_major, binding = 0) readonly buffer commonBlock
 {
-	/// Packs:
-	/// - xy: Planes. For the calculation of frag pos in view space
-	vec4 uPlanesComp;
-
+	vec4 uProjectionParams;
 	vec4 uSceneAmbientColor;
-
 	vec4 uGroundLightDir;
-
-	vec4 uLimitsOfNearPlane;
 };
-
-#define uPlanes uPlanesComp.xy

+ 4 - 5
shaders/IsLp.frag.glsl

@@ -38,20 +38,19 @@ layout(binding = 3) uniform highp sampler2DArrayShadow uShadowMapArr;
 
 layout(location = 0) in vec2 inTexCoord;
 layout(location = 1) flat in int inInstanceId;
-layout(location = 2) in vec2 inLimitsOfNearPlaneOpt;
+layout(location = 2) in vec2 inProjectionParams;
 
 layout(location = 0) out vec3 outColor;
 
 //==============================================================================
-// @return frag pos in view space
+// Return frag pos in view space
 vec3 getFragPosVSpace()
 {
 	float depth = textureRt(uMsDepthRt, inTexCoord).r;
 
 	vec3 fragPosVspace;
-	fragPosVspace.z = uPlanes.y / (uPlanes.x + depth);
-	fragPosVspace.xy = inLimitsOfNearPlaneOpt * fragPosVspace.z;
-	fragPosVspace.z = -fragPosVspace.z;
+	fragPosVspace.z = uProjectionParams.z / (uProjectionParams.w + depth);
+	fragPosVspace.xy = inProjectionParams * fragPosVspace.z;
 
 	return fragPosVspace;
 }

+ 2 - 3
shaders/IsLp.vert.glsl

@@ -10,7 +10,7 @@ layout(location = 0) in vec2 inPosition;
 
 layout(location = 0) out vec2 outTexCoord;
 layout(location = 1) flat out int outInstanceId;
-layout(location = 2) out vec2 outLimitsOfNearPlaneOpt;
+layout(location = 2) out vec2 outProjectionParams;
 
 out gl_PerVertex
 {
@@ -34,8 +34,7 @@ void main()
 	vec2 vertPosNdc = outTexCoord * 2.0 - 1.0;
 	gl_Position = vec4(vertPosNdc, 0.0, 1.0);
 
-	outLimitsOfNearPlaneOpt = 
-		(outTexCoord * uLimitsOfNearPlane.zw) - uLimitsOfNearPlane.xy;
+	outProjectionParams = uProjectionParams.xy * vertPosNdc;
 }
 
 

+ 13 - 28
shaders/PpsSsao.frag.glsl

@@ -10,28 +10,14 @@ layout(location = 0) in vec2 inTexCoords;
 
 layout(location = 0) out float outColor;
 
-layout(std140, row_major, binding = 0) readonly buffer commonBlock
+layout(std140, row_major, 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;
+	vec4 uProjectionParams;
 
 	/// 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 uMsDepthRt;
 layout(binding = 1) uniform sampler2D uMsRt;
 layout(binding = 2) uniform sampler2D uNoiseMap;
@@ -60,29 +46,28 @@ vec3 readRandom(in vec2 uv)
 	return noise;
 }
 
+// Returns the Z of the position in view space
+float readZ(in vec2 uv)
+{
+	float depth = textureRt(uMsDepthRt, uv).r;
+	float z = uProjectionParams.z / (uProjectionParams.w + depth);
+	return z;
+}
+
 // Read 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.z = readZ(uv);
 	
-	fragPosVspace.xy = (uv * uLimitsOfNearPlane2) - uLimitsOfNearPlane;
-	
-	float sc = -fragPosVspace.z;
-	fragPosVspace.xy *= sc;
+	fragPosVspace.xy = 
+		(2.0 * uv - 1.0) * uProjectionParams.xy * fragPosVspace.z;
 
 	return fragPosVspace;
 }
 
-float readZ(in vec2 uv)
-{
-	float depth = textureRt(uMsDepthRt, uv).r;
-	float z = -uPlanes.y / (uPlanes.x + depth);
-	return z;
-}
-
 void main(void)
 {
 	vec3 origin = readPosition(inTexCoords);

+ 28 - 36
shaders/PpsSslr.frag.glsl

@@ -10,26 +10,12 @@ 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;
+	vec4 uProjectionParams;
 
 	/// 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;
@@ -42,29 +28,28 @@ vec3 readNormal(in vec2 uv)
 	return normal;
 }
 
-// Get position in view space
+// Returns the Z of the position in view space
+float readZ(in vec2 uv)
+{
+	float depth = textureRt(uMsDepthRt, uv).r;
+	float z = uProjectionParams.z / (uProjectionParams.w + depth);
+	return z;
+}
+
+// Read 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.z = readZ(uv);
 	
-	fragPosVspace.xy = (uv * uLimitsOfNearPlane2) - uLimitsOfNearPlane;
-	
-	float sc = -fragPosVspace.z;
-	fragPosVspace.xy *= sc;
+	fragPosVspace.xy = 
+		(2.0 * uv - 1.0) * uProjectionParams.xy * fragPosVspace.z;
 
 	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);
@@ -74,21 +59,28 @@ void main()
 	vec3 rDir = normalize(reflect(posv, normal));
 
 	vec3 pos = posv;
-	for(int i = 0; i < 20; i++)
+	for(int i = 0; i < 200; i++)
 	{
-		pos += rDir;
+		pos += rDir * 0.1;
 
 		vec4 posNdc = uProjectionMatrix * vec4(pos, 1.0);
-		posNdc.xy /= posNdc.w;
-		posNdc.xy = posNdc.xy * 0.5 + 0.5;
+		posNdc.xyz /= posNdc.w;
+
+		if(posNdc.x > 1.0 || posNdc.x < -1.0
+			|| posNdc.y > 1.0 || posNdc.y < -1.0)
+		{
+			break;
+		}
+
+		vec3 posClip = posNdc.xyz * 0.5 + 0.5;
 
-		float depth = readZ(posNdc.xy);
+		float depth = textureRt(uMsDepthRt, posClip.xy).r;
 
-		float diffDepth = posNdc.z - depth;
+		float diffDepth = posClip.z - depth;
 
-		if(diffDepth < 0.0)
+		if(diffDepth > 0.0)
 		{
-			outColor = texture(uIsRt, posNdc.xy).rgb;
+			outColor = textureRt(uIsRt, posClip.xy).rgb;
 			return;
 		}
 	}

+ 2 - 7
src/renderer/Is.cpp

@@ -57,10 +57,9 @@ public:
 class CommonUniforms
 {
 public:
-	Vec4 m_planes;
+	Vec4 m_projectionParams;
 	Vec4 m_sceneAmbientColor;
 	Vec4 m_groundLightDir;
-	Vec4 m_limitsOfNearPlane;
 };
 
 } // end namespace shader
@@ -773,7 +772,7 @@ void Is::updateCommonBlock(GlJobChainHandle& jobs)
 		*(shader::CommonUniforms*)cbuff.getBaseAddress();
 
 	// Start writing
-	blk.m_planes = Vec4(m_r->getPlanes().x(), m_r->getPlanes().y(), 0.0, 0.0);
+	blk.m_projectionParams = m_r->getProjectionParameters();
 
 	blk.m_sceneAmbientColor = scene.getAmbientColor();
 
@@ -784,10 +783,6 @@ void Is::updateCommonBlock(GlJobChainHandle& jobs)
 			Vec4(-m_cam->getViewMatrix().getColumn(1).xyz(), 1.0);
 	}
 
-	blk.m_limitsOfNearPlane = Vec4(
-		m_r->getLimitsOfNearPlane(), 
-		m_r->getLimitsOfNearPlane2().x(), m_r->getLimitsOfNearPlane2().y());
-
 	m_commonBuff.write(jobs, cbuff, 0, 0, cbuff.getSize());
 }
 

+ 103 - 96
src/renderer/Lf.cpp

@@ -188,129 +188,136 @@ void Lf::run(GlJobChainHandle& jobs)
 		}
 	}
 
-	// Early exit
-	if(lightsCount == 0)
+	// Check the light count
+	if(lightsCount != 0)
 	{
-		return;
-	}
-
-	// Sort the lights using their lens flare texture
-	std::sort(lights.begin(), lights.begin() + lightsCount, LightSortFunctor());
-
-	// Write the UBO and get the groups
-	//
-	GlClientBufferHandle flaresCBuff(jobs,
-		sizeof(Flare) * lightsCount * m_maxFlaresPerLight, nullptr);
-	Flare* flares = (Flare*)flaresCBuff.getBaseAddress();
-	U flaresCount = 0;
+		// Sort the lights using their lens flare texture
+		std::sort(lights.begin(), lights.begin() + lightsCount, 
+			LightSortFunctor());
+
+		// Write the UBO and get the groups
+		//
+		GlClientBufferHandle flaresCBuff(jobs,
+			sizeof(Flare) * lightsCount * m_maxFlaresPerLight, nullptr);
+		Flare* flares = (Flare*)flaresCBuff.getBaseAddress();
+		U flaresCount = 0;
+
+		// Contains the number of flares per flare texture
+		SceneFrameVector<U> groups(lightsCount, 0U, scene.getFrameAllocator());
+		SceneFrameVector<const GlTextureHandle*> texes(
+			lightsCount, nullptr, scene.getFrameAllocator());
+		U groupsCount = 0;
+
+		GlTextureHandle lastTex;
+
+		// Iterate all lights and update the flares as well as the groups
+		while(lightsCount-- != 0)
+		{
+			Light& light = *lights[lightsCount];
+			const GlTextureHandle& tex = light.getLensFlareTexture();
+			const U depth = tex.getDepth();
 
-	// Contains the number of flares per flare texture
-	SceneFrameVector<U> groups(lightsCount, 0U, scene.getFrameAllocator());
-	SceneFrameVector<const GlTextureHandle*> texes(
-		lightsCount, nullptr, scene.getFrameAllocator());
-	U groupsCount = 0;
+			// Transform
+			Vec3 posWorld = light.getWorldTransform().getOrigin();
+			Vec4 posClip = cam.getViewProjectionMatrix() * Vec4(posWorld, 1.0);
 
-	GlTextureHandle lastTex;
+			if(posClip.x() > posClip.w() || posClip.x() < -posClip.w()
+				|| posClip.y() > posClip.w() || posClip.y() < -posClip.w())
+			{
+				// Outside clip
+				continue;
+			}
 
-	// Iterate all lights and update the flares as well as the groups
-	while(lightsCount-- != 0)
-	{
-		Light& light = *lights[lightsCount];
-		const GlTextureHandle& tex = light.getLensFlareTexture();
-		const U depth = tex.getDepth();
+			Vec2 posNdc = posClip.xy() / posClip.w();
 
-		// Transform
-		Vec3 posWorld = light.getWorldTransform().getOrigin();
-		Vec4 posClip = cam.getViewProjectionMatrix() * Vec4(posWorld, 1.0);
+			Vec2 dir = -posNdc;
+			F32 len = dir.getLength();
+			dir /= len; // Normalize dir
 
-		if(posClip.x() > posClip.w() || posClip.x() < -posClip.w()
-			|| posClip.y() > posClip.w() || posClip.y() < -posClip.w())
-		{
-			// Outside clip
-			continue;
-		}
+			// New group?
+			if(lastTex != tex)
+			{
+				texes[groupsCount] = &tex;
+				lastTex = tex;
 
-		Vec2 posNdc = posClip.xy() / posClip.w();
+				++groupsCount;
+			}
 
-		Vec2 dir = -posNdc;
-		F32 len = dir.getLength();
-		dir /= len; // Normalize dir
+			// First flare 
+			F32 stretchFactor = 1.0 - posNdc.getLength();
+			stretchFactor *= stretchFactor;
 
-		// New group?
-		if(lastTex != tex)
-		{
-			texes[groupsCount] = &tex;
-			lastTex = tex;
+			Vec2 stretch = 
+				light.getLensFlaresStretchMultiplier() * stretchFactor;
 
-			++groupsCount;
-		}
+			flares[flaresCount].m_pos = posNdc;
+			flares[flaresCount].m_scale =
+				light.getLensFlaresSize() * Vec2(1.0, m_r->getAspectRatio())
+				* stretch;
+			flares[flaresCount].m_depth = 0.0;
+			flares[flaresCount].m_alpha = 
+				light.getLensFlaresAlpha() * stretchFactor;
+			++flaresCount;
+			++groups[groupsCount - 1];
 
-		// First flare 
-		F32 stretchFactor = 1.0 - posNdc.getLength();
-		stretchFactor *= stretchFactor;
+			// The rest of the flares
+			for(U d = 1; d < depth; d++)
+			{
+				// Write the "flares"
+				F32 factor = d / ((F32)depth - 1.0);
 
-		Vec2 stretch = light.getLensFlaresStretchMultiplier() * stretchFactor;
+				F32 flen = len * 2.0 * factor;
 
-		flares[flaresCount].m_pos = posNdc;
-		flares[flaresCount].m_scale =
-			light.getLensFlaresSize() * Vec2(1.0, m_r->getAspectRatio())
-			* stretch;
-		flares[flaresCount].m_depth = 0.0;
-		flares[flaresCount].m_alpha = 
-			light.getLensFlaresAlpha() * stretchFactor;
-		++flaresCount;
-		++groups[groupsCount - 1];
+				flares[flaresCount].m_pos = posNdc + dir * flen;
 
-		// The rest of the flares
-		for(U d = 1; d < depth; d++)
-		{
-			// Write the "flares"
-			F32 factor = d / ((F32)depth - 1.0);
+				flares[flaresCount].m_scale =
+					light.getLensFlaresSize() * Vec2(1.0, m_r->getAspectRatio())
+					* ((len - flen) * 2.0);
 
-			F32 flen = len * 2.0 * factor;
+				flares[flaresCount].m_depth = d;
 
-			flares[flaresCount].m_pos = posNdc + dir * flen;
+				flares[flaresCount].m_alpha = light.getLensFlaresAlpha();
 
-			flares[flaresCount].m_scale =
-				light.getLensFlaresSize() * Vec2(1.0, m_r->getAspectRatio())
-				* ((len - flen) * 2.0);
+				// Advance
+				++flaresCount;
+				++groups[groupsCount - 1];
+			}
+		}
 
-			flares[flaresCount].m_depth = d;
+		// Time to render
+		//
 
-			flares[flaresCount].m_alpha = light.getLensFlaresAlpha();
+		// Write the buffer
+		m_flareDataBuff.write(
+			jobs, flaresCBuff, 0, 0, sizeof(Flare) * flaresCount);
 
-			// Advance
-			++flaresCount;
-			++groups[groupsCount - 1];
-		}
-	}
+		// Set the common state
+		m_realPpline.bind(jobs);
 
-	// Time to render
-	//
+		jobs.enableBlend(true);
+		jobs.setBlendFunctions(GL_ONE, GL_ONE);
 
-	// Write the buffer
-	m_flareDataBuff.write(
-		jobs, flaresCBuff, 0, 0, sizeof(Flare) * flaresCount);
+		PtrSize offset = 0;
+		for(U i = 0; i < groupsCount; i++)
+		{
+			GlTextureHandle tex = *texes[i];
+			U instances = groups[i];
+			PtrSize buffSize = sizeof(Flare) * instances;
 
-	// Set the common state
-	m_realPpline.bind(jobs);
+			tex.bind(jobs, 0);
+			m_flareDataBuff.bindShaderBuffer(jobs, offset, buffSize, 0);
 
-	jobs.enableBlend(true);
-	jobs.setBlendFunctions(GL_ONE, GL_ONE);
+			m_r->drawQuadInstanced(jobs, instances);
 
-	PtrSize offset = 0;
-	for(U i = 0; i < groupsCount; i++)
+			offset += buffSize;
+		}
+	}
+	else
 	{
-		GlTextureHandle tex = *texes[i];
-		U instances = groups[i];
-		PtrSize buffSize = sizeof(Flare) * instances;
-
-		tex.bind(jobs, 0);
-		m_flareDataBuff.bindShaderBuffer(jobs, offset, buffSize, 0);
-
-		m_r->drawQuadInstanced(jobs, instances);
+		// No lights
 
-		offset += buffSize;
+		jobs.enableBlend(true);
+		jobs.setBlendFunctions(GL_ONE, GL_ONE);
 	}
 
 	// Blit the HDR RT back to LF RT

+ 21 - 0
src/renderer/Renderer.cpp

@@ -186,6 +186,8 @@ void Renderer::render(SceneGraph& scene, GlJobChainHandle& jobs)
 		calcLimitsOfNearPlane(pcam, m_limitsOfNearPlane);
 		m_limitsOfNearPlane2 = m_limitsOfNearPlane * 2.0;
 
+		computeProjectionParams(cam.getProjectionMatrix());
+
 		m_planesUpdateTimestamp = getGlobTimestamp();
 	}
 
@@ -270,6 +272,25 @@ void Renderer::calcLimitsOfNearPlane(const PerspectiveCamera& pcam,
 	limitsOfNearPlane.x() = tan(0.5 * pcam.getFovX());
 }
 
+//==============================================================================
+void Renderer::computeProjectionParams(const Mat4& m)
+{
+	// First, z' = (m * Pv) / 2 + 0.5 where Pv is the view space position.
+	// Solving that for Pv.z we get
+	// Pv.z = A / (z' + B)
+	// where A = (-m23 / 2) and B = (m22/2 - 0.5)
+	// so we save the A and B in the projection params vector
+	m_projectionParams.z() = -m(2, 3) * 0.5;
+	m_projectionParams.w() = m(2, 2) * 0.5 - 0.5;
+
+	// Using the same logic the Pv.x = x' * w / m00
+	// so Pv.x = x' * Pv.z * (-1 / m00)
+	m_projectionParams.x() = -1.0 / m(0, 0);
+
+	// Same for y
+	m_projectionParams.y() = -1.0 / m(1, 1);
+}
+
 //==============================================================================
 void Renderer::createRenderTarget(U32 w, U32 h, GLenum internalFormat, 
 	GLenum format, GLenum type, U32 samples, GlTextureHandle& rt)

+ 2 - 8
src/renderer/Ssao.cpp

@@ -53,8 +53,7 @@ static void genNoise(Vec3* ANKI_RESTRICT arr,
 class ShaderCommonUniforms
 {
 public:
-	Vec4 m_nearPlanes;
-	Vec4 m_limitsOfNearPlane;
+	Vec4 m_projectionParams;
 	Mat4 m_projectionMatrix;
 };
 
@@ -254,12 +253,7 @@ void Ssao::run(GlJobChainHandle& jobs)
 		ShaderCommonUniforms& blk = 
 			*((ShaderCommonUniforms*)tmpBuff.getBaseAddress());
 
-		blk.m_nearPlanes = Vec4(cam.getNear(), cam.getFar(), 
-			m_r->getPlanes().x(), m_r->getPlanes().y());
-
-		blk.m_limitsOfNearPlane = Vec4(m_r->getLimitsOfNearPlane(),
-			m_r->getLimitsOfNearPlane2().x(),
-			m_r->getLimitsOfNearPlane2().y());
+		blk.m_projectionParams = m_r->getProjectionParameters();
 
 		blk.m_projectionMatrix = cam.getProjectionMatrix().getTransposed();