浏览代码

- Refactoring the renderer
- adding new SSAO implementation

Panagiotis Christopoulos Charitos 14 年之前
父节点
当前提交
acbb462a8e
共有 9 个文件被更改,包括 168 次插入34 次删除
  1. 0 1
      build/debug/Makefile
  2. 11 0
      shaders/LinearDepth.glsl
  3. 115 0
      shaders/PpsSsao-2.glsl
  4. 3 3
      shaders/PpsSsao.glsl
  5. 0 11
      shaders/linear_depth.glsl
  6. 24 14
      src/Renderer/Is.cpp
  7. 12 3
      src/Renderer/Is.h
  8. 2 1
      src/Renderer/Ms.cpp
  9. 1 1
      src/Renderer/Ssao.cpp

文件差异内容过多而无法显示
+ 0 - 1
build/debug/Makefile


+ 11 - 0
shaders/LinearDepth.glsl

@@ -0,0 +1,11 @@
+// convert to linear depth
+
+float linearizeDepth(in float depth, in float zNear, in float zFar)
+{
+	return (2.0 * zNear) / (zFar + zNear - depth * (zFar - zNear));
+}
+
+float readFromTexAndLinearizeDepth(in sampler2D depthMap, in vec2 texCoord, in float zNear, in float zFar)
+{
+	return linearizeDepth(texture2D(depthMap, texCoord).r, zNear, zFar);
+}

+ 115 - 0
shaders/PpsSsao-2.glsl

@@ -0,0 +1,115 @@
+#pragma anki vertShaderBegins
+
+layout(location = 0) in vec2 position; ///< the vert coords are {1.0,1.0}, {0.0,1.0}, {0.0,0.0}, {1.0,0.0}
+layout(location = 1) in vec3 viewVector;
+
+out vec2 vTexCoords;
+out vec3 vPosition;
+
+
+//======================================================================================================================
+// main                                                                                                                =
+//======================================================================================================================
+void main()
+{
+	vPosition = viewVector;
+	vTexCoords = position;
+	vec2 vertPosNdc = position * 2.0 - 1.0;
+	gl_Position = vec4(vertPosNdc, 0.0, 1.0);
+}
+
+
+#pragma anki fragShaderBegins
+
+#pragma anki include "shaders/Pack.glsl"
+
+/// @name Uniforms
+/// @{
+uniform vec2 camerarange;  // = vec2( znear, zfar )
+uniform vec2 planes; ///< for the calculation of frag pos in view space	
+uniform sampler2D msDepthFai;
+uniform sampler2D noiseMap;
+uniform sampler2D msNormalFai;
+
+uniform float noiseMapSize;
+uniform float g_sample_rad;
+uniform float g_intensity;
+uniform float g_scale;
+uniform float g_bias;
+/// @}
+
+/// @name Varyings
+/// @{
+in vec2 vTexCoords;
+in vec3 vPosition; ///< for the calculation of frag pos in view space
+/// @}
+
+/// @name Output
+/// @{
+layout(location = 0) out float fColor;
+/// @}
+
+
+vec3 getPosition(in sampler2D depthMap, in vec2 uv)
+{
+	float depth = texture2D(depthMap, uv).r;
+
+	vec3 fragPosVspace;
+	vec3 vposn = normalize(vPosition);
+	fragPosVspace.z = -planes.y / (planes.x + depth);
+	fragPosVspace.xy = vposn.xy * (fragPosVspace.z / vposn.z);
+	return fragPosVspace;
+}
+
+
+vec3 getNormal(in sampler2D normalMap, in vec2 uv)
+{
+	return unpackNormal(texture2D(normalMap, uv).rg);
+}
+
+
+vec2 getRandom(in sampler2D noiseMap, in vec2 uv)
+{
+	return normalize(texture2D(noiseMap, screenSize * uv / noiseMapSize).xy * 2.0f - 1.0f);
+}
+
+
+float doAmbientOcclusion(in vec2 tcoord, in vec2 uv, in vec3 p, in vec3 cnorm)
+{
+	vec3 diff = getPosition(tcoord + uv) - p;
+	vec3 v = normalize(diff);
+	float d = length(diff) * g_scale;
+	return max(0.0, dot(cnorm, v) - g_bias) * (1.0 / (1.0 + d)) * g_intensity;
+}
+
+
+void main(void)
+{
+	fColor = 1.0f;
+	
+	const vec3 kernel[4] = vec3[](vec2(1, 0), vec2(-1, 0), vec2(0, 1), vec2(0, -1));
+
+	vec3 p = getPosition(msDepthFai, vTexCoords);
+	vec3 n = getNormal(msNormalFai, vTexCoords);
+	vec2 rand = getRandom(noiseMap, vTexCoords);
+
+	float ao = 0.0f;
+	float rad = g_sample_rad / p.z;
+
+	// SSAO Calculation
+	const int iterations = 4;
+	for(int j = 0; j < iterations; ++j)
+	{
+		vec2 coord1 = reflect(kernel[j], rand) * rad;
+		vec2 coord2 = vec2(coord1.x * 0.707 - coord1.y * 0.707, coord1.x * 0.707 + coord1.y * 0.707);
+
+		ao += doAmbientOcclusion(vTexCoords, coord1 * 0.25, p, n);
+		ao += doAmbientOcclusion(vTexCoords, coord2 * 0.5, p, n);
+		ao += doAmbientOcclusion(vTexCoords, coord1 * 0.75, p, n);
+		ao += doAmbientOcclusion(vTexCoords, coord2, p, n);
+	} 
+	ao /= 4.0;
+
+	fColor = ao;
+}
+

+ 3 - 3
shaders/PpsSsao.glsl

@@ -4,7 +4,7 @@
 
 #pragma anki fragShaderBegins
 
-#pragma anki include "shaders/linear_depth.glsl"
+#pragma anki include "shaders/LinearDepth.glsl"
 #pragma anki include "shaders/Pack.glsl"
 
 uniform vec2 camerarange;  // = vec2( znear, zfar )
@@ -36,7 +36,7 @@ void main(void)
 	// grab a normal for reflecting the sample rays later on
 
 
-	float currentPixelDepth = ReadFromTexAndLinearizeDepth( msDepthFai, vTexCoords, camerarange.x, camerarange.y );
+	float currentPixelDepth = readFromTexAndLinearizeDepth( msDepthFai, vTexCoords, camerarange.x, camerarange.y );
 
 	/*if( currentPixelDepth * camerarange.y > MAX_SSAO_DISTANCE )
 	{
@@ -77,7 +77,7 @@ void main(void)
 		occNorm = unpackNormal(occluderFragment.xy);
 
 		// if depthDifference is negative = occluder is behind current fragment
-		depthDifference = currentPixelDepth - ReadFromTexAndLinearizeDepth( msDepthFai, se.xy, camerarange.x, camerarange.y );;
+		depthDifference = currentPixelDepth - readFromTexAndLinearizeDepth( msDepthFai, se.xy, camerarange.x, camerarange.y );;
 
 		// calculate the difference between the normals as a weight
 

+ 0 - 11
shaders/linear_depth.glsl

@@ -1,11 +0,0 @@
-// convert to linear depth
-
-float LinearizeDepth( in float depth_, in float znear_, in float zfar_ )
-{
-	return (2.0 * znear_) / (zfar_ + znear_ - depth_ * (zfar_ - znear_));
-}
-
-float ReadFromTexAndLinearizeDepth( in sampler2D depth_map_, in vec2 tex_coord_, in float znear_, in float zfar_ )
-{
-	return LinearizeDepth( texture2D( depth_map_, tex_coord_ ).r, znear_, zfar_ );
-}

+ 24 - 14
src/Renderer/Is.cpp

@@ -26,17 +26,15 @@ Is::Is(Renderer& r_):
 {}
 
 
+
 //======================================================================================================================
 // calcViewVectors                                                                                                     =
 //======================================================================================================================
-void Is::calcViewVectors()
+void Is::calcViewVectors(const boost::array<float, 2>& screenSize, const Mat4& invProjectionMat,
+                         boost::array<Vec3, 4>& viewVectors)
 {
-	boost::array<Vec3, 4> viewVectors;
-
-	const Camera& cam = r.getCamera();
-
-	uint w = r.getWidth();
-	uint h = r.getHeight();
+	uint w = screenSize[0];
+	uint h = screenSize[1];
 
 	// From right up and CC wise to right down, Just like we render the quad
 	uint pixels[4][2] = {{w, h}, {0, h}, {0, 0}, {w, 0}};
@@ -57,11 +55,22 @@ void Is::calcViewVectors()
 		vec.y() = (2.0 * (pixels[i][1] - viewport[1])) / viewport[3] - 1.0;
 		vec.z() = 1.0;
 
-		viewVectors[i] = vec.getTransformed(cam.getInvProjectionMatrix());
+		viewVectors[i] = vec.getTransformed(invProjectionMat);
 		// end of optimized code
 	}
+}
+
+
+//======================================================================================================================
+// calcViewVectors                                                                                                     =
+//======================================================================================================================
+void Is::calcViewVectors()
+{
+	boost::array<Vec3, 4> viewVectors;
+	boost::array<float, 2> screenSize = {{r.getWidth(), r.getHeight()}};
+
+	calcViewVectors(screenSize, r.getCamera().getInvProjectionMatrix(), viewVectors);
 
-	ASSERT(sizeof(viewVectors) == viewVectorsVbo.getSizeInBytes());
 	viewVectorsVbo.write(&viewVectors[0]);
 }
 
@@ -69,12 +78,13 @@ void Is::calcViewVectors()
 //======================================================================================================================
 // calcPlanes                                                                                                          =
 //======================================================================================================================
-void Is::calcPlanes()
+void Is::calcPlanes(const Vec2& cameraRange, Vec2& planes)
 {
-	const Camera& cam = r.getCamera();
+	float zNear = cameraRange.x();
+	float zFar = cameraRange.y();
 
-	planes.x() = cam.getZFar() / (cam.getZNear() - cam.getZFar());
-	planes.y() = (cam.getZFar() * cam.getZNear()) / (cam.getZNear() -cam.getZFar());
+	planes.x() = zFar / (zNear - zFar);
+	planes.y() = (zFar * zNear) / (zNear -zFar);
 }
 
 
@@ -332,7 +342,7 @@ void Is::run()
 	glEnable(GL_STENCIL_TEST);
 
 	calcViewVectors();
-	calcPlanes();
+	calcPlanes(Vec2(r.getCamera().getZNear(), r.getCamera().getZFar()), planes);
 
 	// for all lights
 	BOOST_FOREACH(const PointLight* light, r.getCamera().getVisiblePointLights())

+ 12 - 3
src/Renderer/Is.h

@@ -30,6 +30,18 @@ class Is: private RenderingPass
 		const Texture& getFai() const {return fai;}
 		/// @}
 
+		/// Calculate the view vectors needed for the calculation of the frag pos in view space in shaders
+		/// @param[in] screenSize The width and height of the screen
+		/// @param[in] invProjectionMat The inverted camera projection matrix
+		/// @param[out] viewVectors The output
+		static void calcViewVectors(const boost::array<float, 2>& screenSize, const Mat4& invProjectionMat,
+		                            boost::array<Vec3, 4>& viewVectors);
+
+		/// Calculate the planes needed for the calculation of the frag pos in view space in shaders
+		/// @param[in] cameraRange The zNear, zFar
+		/// @param[out] planes The planes
+		static void calcPlanes(const Vec2& cameraRange, Vec2& planes);
+
 	private:
 		Sm sm; ///< Shadowmapping pass
 		Smo smo; /// Stencil masking optimizations pass
@@ -58,9 +70,6 @@ class Is: private RenderingPass
 		/// calculates the view vectors and updates the @ref viewVectorsVbo
 		void calcViewVectors();
 
-		/// Calc the planes that we will use inside the shader to calculate the frag pos in view space
-		void calcPlanes();
-
 		/// The ambient pass
 		void ambientPass(const Vec3& color);
 

+ 2 - 1
src/Renderer/Ms.cpp

@@ -33,7 +33,8 @@ void Ms::init(const RendererInitializer& initializer)
 		normalFai.createEmpty2D(r.getWidth(), r.getHeight(), GL_RG16F, GL_RG, GL_FLOAT);
 		diffuseFai.createEmpty2D(r.getWidth(), r.getHeight(), GL_RGB16F, GL_RGB, GL_FLOAT);
 		specularFai.createEmpty2D(r.getWidth(), r.getHeight(), GL_RGBA16F, GL_RGBA, GL_FLOAT);
-		depthFai.createEmpty2D(r.getWidth(), r.getHeight(), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8);
+		depthFai.createEmpty2D(r.getWidth(), r.getHeight(), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL,
+		                       GL_UNSIGNED_INT_24_8);
 
 		normalFai.setRepeat(false);
 		diffuseFai.setRepeat(false);

+ 1 - 1
src/Renderer/Ssao.cpp

@@ -129,7 +129,7 @@ void Ssao::run()
 	// blurring passes
 	hblurFai.setRepeat(false);
 	fai.setRepeat(false);
-	for(uint i=0; i<blurringIterationsNum; i++)
+	for(uint i = 0; i < blurringIterationsNum; i++)
 	{
 		// hpass
 		hblurFbo.bind();

部分文件因为文件数量过多而无法显示