瀏覽代碼

The new SSAO is up and running

Panagiotis Christopoulos Charitos 14 年之前
父節點
當前提交
1619e5f4af

+ 2 - 2
shaders/Final.glsl

@@ -15,6 +15,6 @@ void main()
 {
 	//if( gl_FragCoord.x > 0.5 ) discard;
 
-	//fFragColor = texture2D(rasterImage, vTexCoords).rgb;
-	fFragColor = vec3(texture2D(rasterImage, vTexCoords).r);
+	fFragColor = texture2D(rasterImage, vTexCoords).rgb;
+	//fFragColor = vec3(texture2D(rasterImage, vTexCoords).r);
 }

+ 2 - 4
shaders/MsMpGeneric.glsl

@@ -85,9 +85,9 @@ void main()
 	#endif
 
 
-	//#if defined(ENVIRONMENT_MAPPING) || defined(PARALLAX_MAPPING)
+	#if defined(ENVIRONMENT_MAPPING) || defined(PARALLAX_MAPPING)
 		vVertPosViewSpace = vec3(modelViewMat * vec4(position, 1.0));
-	//#endif
+	#endif
 }
 
 
@@ -136,7 +136,6 @@ in vec3 eye;
 layout(location = 0) out vec2 fMsNormalFai;
 layout(location = 1) out vec3 fMsDiffuseFai;
 layout(location = 2) out vec4 fMsSpecularFai;
-layout(location = 3) out vec3 fMsPosFai;
 
 
 //======================================================================================================================
@@ -313,6 +312,5 @@ void main()
 	fMsNormalFai = packNormal(_normal_);
 	fMsDiffuseFai = _diffColl_;
 	fMsSpecularFai = _specularCol_;
-	fMsPosFai = vVertPosViewSpace;
 }
 

+ 0 - 152
shaders/PpsSsao-2.glsl

@@ -1,152 +0,0 @@
-#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 vViewVector;
-
-
-//======================================================================================================================
-// main                                                                                                                =
-//======================================================================================================================
-void main()
-{
-	vViewVector = 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 planes; ///< for the calculation of frag pos in view space
-uniform sampler2D msDepthFai; ///< for the calculation of frag pos in view space
-uniform sampler2D msPosFai;
-uniform sampler2D noiseMap;
-uniform sampler2D msNormalFai;
-uniform vec2 limitsOfNearPlane;
-uniform float noiseMapSize = 100.0; /// Used in getRandom
-uniform float sampleRad = 0.1;  /// Used in main
-uniform float scale = 1.0; /// Used in doAmbientOcclusion
-uniform float intensity = 2.0; /// Used in doAmbientOcclusion
-uniform float bias = 0.00; /// Used in doAmbientOcclusion
-uniform vec2 screenSize; /// Used in getRandom
-/// @}
-
-/// @name Varyings
-/// @{
-in vec2 vTexCoords;
-in vec3 vViewVector; ///< for the calculation of frag pos in view space
-/// @}
-
-/// @name Output
-/// @{
-layout(location = 0) out float fColor;
-/// @}
-
-
-/// globals: msNormalFai
-vec3 getNormal(in vec2 uv)
-{
-	return unpackNormal(texture2D(msNormalFai, uv).rg);
-}
-
-
-/// globals: noiseMap, screenSize, noiseMapSize
-vec2 getRandom(in vec2 uv)
-{
-	return normalize(texture2D(noiseMap, screenSize * uv / noiseMapSize).xy * 2.0 - 1.0);
-}
-
-
-/// Get frag position in view space
-/// globals: msDepthFai, planes
-vec3 getPosition(in vec2 uv)
-{
-	float depth = texture2D(msDepthFai, uv).r;
-
-	vec3 fragPosVspace;
-	fragPosVspace.z = -planes.y / (planes.x + depth);
-
-	/*vec3 vposn = normalize(vViewVector);
-	fragPosVspace.xy = vposn.xy * (fragPosVspace.z / vposn.z);*/
-	
-	fragPosVspace.xy = (((uv) * 2.0) - 1.0) * limitsOfNearPlane;
-	
-	float sc = -fragPosVspace.z / 0.5;
-    fragPosVspace.xy *= sc;
-
-	return fragPosVspace;
-	//return abs(fragPosVspace - texture2D(msPosFai, uv).xyz);
-	//return vec3(texture2D(msPosFai, uv).xy, fragPosVspace.z);
-}
-
-
-float doAmbientOcclusion(in vec2 tcoord, in vec2 uv, in vec3 original, in vec3 cnorm)
-{
-	vec3 newp = getPosition(tcoord + uv);
-	vec3 diff = newp - original;
-	vec3 v = normalize(diff);
-	float d = length(diff) * scale;
-
-	float ret = max(0.0, dot(cnorm, v) - bias) * (1.0 / (1.0 + d)) * intensity;
-	return ret;
-	//return newp.x / 10.0;
-}
-
-
-void main(void)
-{
-	//const vec2 kernel[4] = vec2[](vec2(1, 0), vec2(-1, 0), vec2(0, 1), vec2(0, -1));
-
-	const vec2 KERNEL[16] = vec2[](vec2(0.53812504, 0.18565957), vec2(0.13790712, 0.24864247), vec2(0.33715037, 0.56794053), vec2(-0.6999805, -0.04511441), vec2(0.06896307, -0.15983082), vec2(0.056099437, 0.006954967), vec2(-0.014653638, 0.14027752), vec2(0.010019933, -0.1924225), vec2(-0.35775623, -0.5301969), vec2(-0.3169221, 0.106360726), vec2(0.010350345, -0.58698344), vec2(-0.08972908, -0.49408212), vec2(0.7119986, -0.0154690035), vec2(-0.053382345, 0.059675813), vec2(0.035267662, -0.063188605), vec2(-0.47761092, 0.2847911));
-
-	vec3 original = getPosition(vTexCoords);
-	vec3 n = getNormal(vTexCoords);
-	vec2 rand = getRandom(vTexCoords);
-
-	//rand = rand - rand + vec2(0.0, 0.0);
-
-	fColor = 0.0;
-	float rad = sampleRad ;// 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 /= ITERATIONS * 4.0;*/
-
-	const int ITERATIONS = 16;
-	for(int j = 0; j < ITERATIONS; ++j)
-	{
-		vec2 coord = reflect(KERNEL[j], rand) * rad;
-		fColor += doAmbientOcclusion(vTexCoords, coord, original, n);
-	}
-
-	fColor = 1.0 - fColor / ITERATIONS;
-
-	//fColor = gl_FragCoord.y / (720.0 / 2);
-
-	/*vec3 diff = getPosition(vTexCoords) - texture2D(msPosFai, vTexCoords).xyz;
-	fColor = (diff.x + diff.y + diff.z) / 3.0;*/
-
-	//fColor = original.x;
-	
-	/*vec2 v = getRandom(vTexCoords);	
-	fColor = (fColor - fColor) + ((v.x + v.y) / 2.0);*/
-}
-

+ 74 - 60
shaders/PpsSsao.glsl

@@ -4,89 +4,103 @@
 
 #pragma anki fragShaderBegins
 
-#pragma anki include "shaders/LinearDepth.glsl"
 #pragma anki include "shaders/Pack.glsl"
 
-uniform vec2 camerarange;  // = vec2( znear, zfar )
-uniform sampler2D msDepthFai;
-uniform sampler2D noiseMap;
-uniform sampler2D msNormalFai;
+/// @name Uniforms
+/// @{
+uniform vec2 planes; ///< for the calculation of frag pos in view space
+uniform vec2 limitsOfNearPlane; ///< for the calculation of frag pos in view space
+uniform float zNear; ///< for the calculation of frag pos in view space
+uniform sampler2D msDepthFai; ///< for the calculation of frag pos in view space
 
-in vec2 vTexCoords;
-
-layout(location = 0) out float fFragColor;
+uniform sampler2D noiseMap; /// Used in getRandom
+uniform float noiseMapSize = 100.0; /// Used in getRandom
+uniform vec2 screenSize; /// Used in getRandom
 
-const float totStrength = 1.3;
-const float strength = 0.07;
-const float offset = 18.0;
-const float falloff = 0.000002;
-const float rad = 0.006;
-const int SAMPLES = 16; // 10 is good
-const float invSamples = 1.0/float(SAMPLES);
+uniform sampler2D msNormalFai; /// Used in getNormal
+/// @}
 
-const float MAX_SSAO_DISTANCE = 40.0;
+/// @name Varyings
+/// @{
+in vec2 vTexCoords;
+/// @}
 
-void main(void)
-{
-	// these are the random vectors inside a unit sphere
-	const vec3 pSphere[16] = vec3[](vec3(0.53812504, 0.18565957, -0.43192),vec3(0.13790712, 0.24864247, 0.44301823),vec3(0.33715037, 0.56794053, -0.005789503),vec3(-0.6999805, -0.04511441, -0.0019965635),vec3(0.06896307, -0.15983082, -0.85477847),vec3(0.056099437, 0.006954967, -0.1843352),vec3(-0.014653638, 0.14027752, 0.0762037),vec3(0.010019933, -0.1924225, -0.034443386),vec3(-0.35775623, -0.5301969, -0.43581226),vec3(-0.3169221, 0.106360726, 0.015860917),vec3(0.010350345, -0.58698344, 0.0046293875),vec3(-0.08972908, -0.49408212, 0.3287904),vec3(0.7119986, -0.0154690035, -0.09183723),vec3(-0.053382345, 0.059675813, -0.5411899),vec3(0.035267662, -0.063188605, 0.54602677),vec3(-0.47761092, 0.2847911, -0.0271716));
-	//const vec3 pSphere[8] = vec3[](vec3(0.24710192, 0.6445882, 0.033550154),vec3(0.00991752, -0.21947019, 0.7196721),vec3(0.25109035, -0.1787317, -0.011580509),vec3(-0.08781511, 0.44514698, 0.56647956),vec3(-0.011737816, -0.0643377, 0.16030222),vec3(0.035941467, 0.04990871, -0.46533614),vec3(-0.058801126, 0.7347013, -0.25399926),vec3(-0.24799341, -0.022052078, -0.13399573));
-	//const vec3 pSphere[12] = vec3[](vec3(-0.13657719, 0.30651027, 0.16118456),vec3(-0.14714938, 0.33245975, -0.113095455),vec3(0.030659059, 0.27887347, -0.7332209),vec3(0.009913514, -0.89884496, 0.07381549),vec3(0.040318526, 0.40091, 0.6847858),vec3(0.22311053, -0.3039437, -0.19340435),vec3(0.36235332, 0.21894878, -0.05407306),vec3(-0.15198798, -0.38409665, -0.46785462),vec3(-0.013492276, -0.5345803, 0.11307949),vec3(-0.4972847, 0.037064247, -0.4381323),vec3(-0.024175806, -0.008928787, 0.17719103),vec3(0.694014, -0.122672155, 0.33098832));
-	//const vec3 pSphere[10] = vec3[](vec3(-0.010735935, 0.01647018, 0.0062425877),vec3(-0.06533369, 0.3647007, -0.13746321),vec3(-0.6539235, -0.016726388, -0.53000957),vec3(0.40958285, 0.0052428036, -0.5591124),vec3(-0.1465366, 0.09899267, 0.15571679),vec3(-0.44122112, -0.5458797, 0.04912532),vec3(0.03755566, -0.10961345, -0.33040273),vec3(0.019100213, 0.29652783, 0.066237666),vec3(0.8765323, 0.011236004, 0.28265962),vec3(0.29264435, -0.40794238, 0.15964167));
-	// grab a normal for reflecting the sample rays later on
+/// @name Output
+/// @{
+layout(location = 0) out float fColor;
+/// @}
 
 
-	float currentPixelDepth = readFromTexAndLinearizeDepth( msDepthFai, vTexCoords, camerarange.x, camerarange.y );
+/// @name Consts
+/// @{
+uniform float SAMPLE_RAD = 0.1;  /// Used in main
+uniform float SCALE = 1.0; /// Used in doAmbientOcclusion
+uniform float INTENSITY = 3.0; /// Used in doAmbientOcclusion
+uniform float BIAS = 0.00; /// Used in doAmbientOcclusion
+/// @}
 
-	/*if( currentPixelDepth * camerarange.y > MAX_SSAO_DISTANCE )
-	{
-		gl_FragColor.a = 1.0;
-		return;
-	}*/
 
-	vec3 fres = normalize((texture2D(noiseMap,vTexCoords*offset).xyz*2.0) - vec3(1.0));
+/// globals: msNormalFai
+vec3 getNormal(in vec2 uv)
+{
+	return unpackNormal(texture2D(msNormalFai, uv).rg);
+}
 
-	vec4 currentPixelSample = texture2D(msNormalFai,vTexCoords);
 
+/// globals: noiseMap, screenSize, noiseMapSize
+vec2 getRandom(in vec2 uv)
+{
+	return normalize(texture2D(noiseMap, screenSize * uv / noiseMapSize).xy * 2.0 - 1.0);
+}
 
 
-	// current fragment coords in screen space
-	vec3 ep = vec3( vTexCoords.xy, currentPixelDepth );
-	// get the normal of current fragment
-	vec3 norm = unpackNormal(currentPixelSample.xy);
+/// Get frag position in view space
+/// globals: msDepthFai, planes, zNear, limitsOfNearPlane
+vec3 getPosition(in vec2 uv)
+{
+	float depth = texture2D(msDepthFai, uv).r;
 
-	float bl = 0.0;
-	// adjust for the depth ( not shure if this is good..)
-	float radD = rad/currentPixelDepth;
+	vec3 fragPosVspace;
+	fragPosVspace.z = -planes.y / (planes.x + depth);
+	
+	fragPosVspace.xy = (((uv) * 2.0) - 1.0) * limitsOfNearPlane;
+	
+	float sc = -fragPosVspace.z / zNear;
+    fragPosVspace.xy *= sc;
 
-	vec3 ray, se, occNorm;
-	float occluderDepth, depthDifference, normDiff;
+	return fragPosVspace;
+}
 
-	for(int i=0; i<SAMPLES; ++i)
-	{
-		// get a vector (randomized inside of a sphere with radius 1.0) from a texture and reflect it
-		ray = radD*reflect(pSphere[i],fres);
+/// Calculate the ambient occlusion factor
+float doAmbientOcclusion(in vec2 tcoord, in vec2 uv, in vec3 original, in vec3 cnorm)
+{
+	vec3 newp = getPosition(tcoord + uv);
+	vec3 diff = newp - original;
+	vec3 v = normalize(diff);
+	float d = length(diff) /* * SCALE*/;
 
-		// if the ray is outside the hemisphere then change direction
-		se = ep + sign(dot(ray,norm) )*ray;
+	float ret = max(0.0, dot(cnorm, v) /* - BIAS*/) * (INTENSITY / (1.0 + d));
+	return ret;
+}
 
-		// get the depth of the occluder fragment
-		vec4 occluderFragment = texture2D(msNormalFai,se.xy);
 
-		// get the normal of the occluder fragment
-		occNorm = unpackNormal(occluderFragment.xy);
+void main(void)
+{
+	const vec2 KERNEL[16] = vec2[](vec2(0.53812504, 0.18565957), vec2(0.13790712, 0.24864247), vec2(0.33715037, 0.56794053), vec2(-0.6999805, -0.04511441), vec2(0.06896307, -0.15983082), vec2(0.056099437, 0.006954967), vec2(-0.014653638, 0.14027752), vec2(0.010019933, -0.1924225), vec2(-0.35775623, -0.5301969), vec2(-0.3169221, 0.106360726), vec2(0.010350345, -0.58698344), vec2(-0.08972908, -0.49408212), vec2(0.7119986, -0.0154690035), vec2(-0.053382345, 0.059675813), vec2(0.035267662, -0.063188605), vec2(-0.47761092, 0.2847911));
 
-		// if depthDifference is negative = occluder is behind current fragment
-		depthDifference = currentPixelDepth - readFromTexAndLinearizeDepth( msDepthFai, se.xy, camerarange.x, camerarange.y );;
+	vec3 p = getPosition(vTexCoords);
+	vec3 n = getNormal(vTexCoords);
+	vec2 rand = getRandom(vTexCoords);
 
-		// calculate the difference between the normals as a weight
+	fColor = 0.0;
 
-		normDiff = (1.0-dot(occNorm,norm));
-		// the falloff equation, starts at falloff and is kind of 1/x^2 falling
-		bl += step(falloff,depthDifference)*normDiff*(1.0-smoothstep(falloff,strength,depthDifference));
+	const int ITERATIONS = 16;
+	for(int j = 0; j < ITERATIONS; ++j)
+	{
+		vec2 coord = reflect(KERNEL[j], rand) * SAMPLE_RAD;
+		fColor += doAmbientOcclusion(vTexCoords, coord, p, n);
 	}
 
-	// output the result
-	float ao = 1.0-totStrength*bl*invSamples;
-	fFragColor = ao /** MAX_SSAO_DISTANCE*/;
+	fColor = 1.0 - fColor / ITERATIONS;
 }
+

+ 2 - 2
src/Core/App.cpp

@@ -213,9 +213,9 @@ void App::initRenderer()
 	initializer.pps.hdr.blurringDist = 1.0;
 	initializer.pps.hdr.blurringIterationsNum = 2;
 	initializer.pps.hdr.exposure = 4.0;
-	initializer.pps.ssao.blurringIterationsNum = 2;
+	initializer.pps.ssao.blurringIterationsNum = 1;
 	initializer.pps.ssao.enabled = true;
-	initializer.pps.ssao.renderingQuality = 0.5;
+	initializer.pps.ssao.renderingQuality = 0.4;
 	initializer.mainRendererQuality = 1.0;
 	MainRendererSingleton::getInstance().init(initializer);
 }

+ 1 - 1
src/Renderer/Bs.cpp

@@ -71,7 +71,7 @@ void Bs::createRefractFbo()
 void Bs::init(const RendererInitializer& /*initializer*/)
 {
 	createFbo();
-	refractFai.createEmpty2D(r.getWidth(), r.getHeight(), GL_RGBA8, GL_RGBA, GL_FLOAT);
+	Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGBA8, GL_RGBA, GL_FLOAT, refractFai);
 	createRefractFbo();
 	refractSProg.loadRsrc("shaders/BsRefract.glsl");
 }

+ 1 - 1
src/Renderer/Drawers/SceneDrawer.cpp

@@ -47,7 +47,7 @@ void SceneDrawer::UsrDefVarVisitor::operator()(const Vec4& x) const
 void SceneDrawer::UsrDefVarVisitor::operator()(const RsrcPtr<Texture>* x) const
 {
 	const RsrcPtr<Texture>& texPtr = *x;
-	texPtr->setRepeat(true);
+	//texPtr->setRepeat(true);
 	udvr.getUniVar().set(*texPtr, texUnit);
 	++texUnit;
 }

+ 2 - 3
src/Renderer/Hdr.cpp

@@ -21,9 +21,8 @@ void Hdr::initFbo(Fbo& fbo, Texture& fai)
 		// inform in what buffers we draw
 		fbo.setNumOfColorAttachements(1);
 
-		// create the texes
-		fai.createEmpty2D(width, height, GL_RGB, GL_RGB, GL_FLOAT);
-		fai.setFiltering(Texture::TFT_LINEAR);
+		// create the FAI
+		Renderer::createFai(width, height, GL_RGB, GL_RGB, GL_FLOAT, fai);
 
 		// attach
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fai.getGlId(), 0);

+ 2 - 2
src/Renderer/Is.cpp

@@ -109,7 +109,7 @@ void Is::initFbo()
 		fbo.setNumOfColorAttachements(1);
 
 		// create the FAI
-		fai.createEmpty2D(r.getWidth(), r.getHeight(), GL_RGB, GL_RGB, GL_FLOAT);
+		Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGB, GL_RGB, GL_FLOAT, fai);
 
 		// attach
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fai.getGlId(), 0);
@@ -269,7 +269,7 @@ void Is::spotLightPass(const SpotLight& light)
 	smo.run(light);
 
 	// set the texture
-	light.getTexture().setRepeat(false);
+	//light.getTexture().setRepeat(false);
 
 	// shader prog
 	const ShaderProg* shdr;

+ 2 - 2
src/Renderer/MainRenderer.cpp

@@ -101,8 +101,8 @@ void MainRenderer::render(Camera& cam_)
 	glDisable(GL_BLEND);
 	sProg->bind();
 	//sProg->findUniVar("rasterImage")->set(ms.getNormalFai(), 0);
-	sProg->findUniVar("rasterImage")->set(pps.getSsao().ssaoFai, 0);
-	//sProg->findUniVar("rasterImage")->set(pps.getPostPassFai(), 0);
+	//sProg->findUniVar("rasterImage")->set(pps.getSsao().getFai(), 0);
+	sProg->findUniVar("rasterImage")->set(pps.getPostPassFai(), 0);
 	drawQuad();
 }
 

+ 6 - 14
src/Renderer/Ms.cpp

@@ -27,28 +27,20 @@ void Ms::init(const RendererInitializer& initializer)
 		fbo.bind();
 
 		// inform in what buffers we draw
-		fbo.setNumOfColorAttachements(4);
+		fbo.setNumOfColorAttachements(3);
 
 		// create the FAIs
-		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);
 
-		posFai.createEmpty2D(r.getWidth(), r.getHeight(), GL_RGB16F, GL_RGB, GL_FLOAT);
-
-		normalFai.setRepeat(false);
-		diffuseFai.setRepeat(false);
-		specularFai.setRepeat(false);
-		depthFai.setRepeat(false);
-		posFai.setRepeat(false);
+		Renderer::createFai(r.getWidth(), r.getHeight(), GL_RG16F, GL_RG, GL_FLOAT, normalFai);
+		Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGB16F, GL_RGB, GL_FLOAT, diffuseFai);
+		Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGBA16F, GL_RGBA, GL_FLOAT, specularFai);
+		Renderer::createFai(r.getWidth(), r.getHeight(), GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL,
+		                    GL_UNSIGNED_INT_24_8, depthFai);
 
 		// attach the buffers to the FBO
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, normalFai.getGlId(), 0);
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, diffuseFai.getGlId(), 0);
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, specularFai.getGlId(), 0);
-		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, posFai.getGlId(), 0);
 
 		//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthFai.getGlId(), 0);
 		//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthFai.getGlId(), 0);

+ 0 - 2
src/Renderer/Ms.h

@@ -15,8 +15,6 @@ class RendererInitializer;
 class Ms: public RenderingPass
 {
 	public:
-		Texture posFai; ///< @todo remove it
-
 		Ms(Renderer& r_);
 
 		/// @name Accessors

+ 1 - 2
src/Renderer/Pps.cpp

@@ -24,8 +24,7 @@ void Pps::initPassFbo(Fbo& fbo, Texture& fai)
 
 	fbo.setNumOfColorAttachements(1);
 
-	fai.createEmpty2D(r.getWidth(), r.getHeight(), GL_RGB, GL_RGB, GL_FLOAT);
-	fai.setRepeat(false);
+	Renderer::createFai(r.getWidth(), r.getHeight(), GL_RGB, GL_RGB, GL_FLOAT, fai);
 
 	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fai.getGlId(), 0);
 

+ 22 - 0
src/Renderer/Renderer.cpp

@@ -110,3 +110,25 @@ Vec3 Renderer::unproject(const Vec3& windowCoords, const Mat4& modelViewMat, con
 	return Vec3(final);
 }
 
+
+//======================================================================================================================
+// createFai                                                                                                           =
+//======================================================================================================================
+void Renderer::createFai(uint width, uint height, int internalFormat, int format, int type, Texture& fai)
+{
+	Texture::Initializer init;
+	init.width = width;
+	init.height = height;
+	init.internalFormat = internalFormat;
+	init.format = format;
+	init.type = type;
+	init.data = NULL;
+	init.mipmapping = false;
+	init.filteringType = Texture::TFT_LINEAR;
+	init.repeat = false;
+	init.anisotropyLevel = 0;
+
+	fai.create(init);
+}
+
+

+ 3 - 0
src/Renderer/Renderer.h

@@ -80,6 +80,9 @@ class Renderer
 		/// Draws a quad. Actually it draws 2 triangles because OpenGL will no longer support quads
 		void drawQuad();
 
+		/// Create FAI texture
+		static void createFai(uint width, uint height, int internalFormat, int format, int type, Texture& fai);
+
 	//==================================================================================================================
 	// Protected                                                                                                       =
 	//==================================================================================================================

+ 1 - 1
src/Renderer/Sm.cpp

@@ -29,7 +29,7 @@ void Sm::init(const RendererInitializer& initializer)
 		fbo.bind();
 
 		// texture
-		shadowMap.createEmpty2D(resolution, resolution, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT);
+		Renderer::createFai(resolution, resolution, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT, shadowMap);
 		if(bilinearEnabled)
 		{
 			shadowMap.setFiltering(Texture::TFT_LINEAR);

+ 23 - 56
src/Renderer/Ssao.cpp

@@ -24,10 +24,7 @@ void Ssao::createFbo(Fbo& fbo, Texture& fai)
 		fbo.setNumOfColorAttachements(1);
 
 		// create the texes
-		fai.createEmpty2D(width, height, GL_RED, GL_RED, GL_FLOAT);
-		fai.setRepeat(false);
-		fai.setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-		fai.setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		Renderer::createFai(width, height, GL_RED, GL_RED, GL_FLOAT, fai);
 
 		// attach
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fai.getGlId(), 0);
@@ -68,7 +65,7 @@ void Ssao::init(const RendererInitializer& initializer)
 	//
 
 	// first pass prog
-	ssaoSProg.loadRsrc("shaders/PpsSsao-2.glsl");
+	ssaoSProg.loadRsrc("shaders/PpsSsao.glsl");
 
 	// blurring progs
 	const char* SHADER_FILENAME = "shaders/GaussianBlurGeneric.glsl";
@@ -98,23 +95,6 @@ void Ssao::init(const RendererInitializer& initializer)
 	//noise_map->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 	Texture::compressionEnabled = texCompr;
 	Texture::mipmappingEnabled = mipmaping;
-	
-	//
-	// Geom
-	//
-	
-	float quadVertCoords[][2] = {{1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}, {1.0, 0.0}};
-	quadPositionsVbo.create(GL_ARRAY_BUFFER, sizeof(quadVertCoords), quadVertCoords, GL_STATIC_DRAW);
-
-	ushort quadVertIndeces[2][3] = {{0, 1, 3}, {1, 2, 3}};
-	quadVertIndecesVbo.create(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadVertIndeces), quadVertIndeces, GL_STATIC_DRAW);
-
-	viewVectorsVbo.create(GL_ARRAY_BUFFER, 4 * sizeof(Vec3), NULL, GL_DYNAMIC_DRAW);
-
-	vao.create();
-	vao.attachArrayBufferVbo(quadPositionsVbo, 0, 2, GL_FLOAT, false, 0, NULL);
-	vao.attachArrayBufferVbo(viewVectorsVbo, 1, 3, GL_FLOAT, false, 0, NULL);
-	vao.attachElementArrayBufferVbo(quadVertIndecesVbo);
 }
 
 
@@ -137,57 +117,44 @@ void Ssao::run()
 	// 1st pass
 	//
 	
-	boost::array<Vec3, 4> viewVectors;
-	boost::array<float, 2> gScreenSize = {{width, height}};
-	Is::calcViewVectors(gScreenSize, cam.getInvProjectionMatrix(), viewVectors);
-	viewVectorsVbo.write(&viewVectors[0]);
-	
-	/*BOOST_FOREACH(Vec3 v, viewVectors)
-	{
-		std::cout << v << std::endl;
-	}
-	std::cout << "----------------" << std::endl;*/
-	
-	//std::cout << planes << std::endl;
-
 	ssaoFbo.bind();
 	ssaoSProg->bind();
 	
+	// planes
 	Vec2 planes;
 	Is::calcPlanes(Vec2(r.getCamera().getZNear(), r.getCamera().getZFar()), planes);
-	if(ssaoSProg->uniVarExists("planes"))
-		ssaoSProg->findUniVar("planes")->set(&planes);
+	ssaoSProg->findUniVar("planes")->set(&planes);
 
+	// limitsOfNearPlane
 	Vec2 limitsOfNearPlane;
+	ASSERT(cam.getType() == Camera::CT_PERSPECTIVE);
 	const PerspectiveCamera& pcam = static_cast<const PerspectiveCamera&>(cam);
 	limitsOfNearPlane.y() = cam.getZNear() * tan(0.5 * pcam.getFovY());
 	limitsOfNearPlane.x() = limitsOfNearPlane.y() * (pcam.getFovX() / pcam.getFovY());
-	if(ssaoSProg->uniVarExists("limitsOfNearPlane"))
-		ssaoSProg->findUniVar("limitsOfNearPlane")->set(&limitsOfNearPlane);
+	ssaoSProg->findUniVar("limitsOfNearPlane")->set(&limitsOfNearPlane);
 
-	if(ssaoSProg->uniVarExists("msDepthFai"))
-		ssaoSProg->findUniVar("msDepthFai")->set(r.getMs().getDepthFai(), 0);
+	// zNear
+	float zNear = cam.getZNear();
+	ssaoSProg->findUniVar("zNear")->set(&zNear);
 
-	if(ssaoSProg->uniVarExists("noiseMap"))
-		ssaoSProg->findUniVar("noiseMap")->set(*noiseMap, 1);
+	// msDepthFai
+	ssaoSProg->findUniVar("msDepthFai")->set(r.getMs().getDepthFai(), 0);
 
-	if(ssaoSProg->uniVarExists("msNormalFai"))
-		ssaoSProg->findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 2);
-
-	Vec2 screenSize(width, height);
-	if(ssaoSProg->uniVarExists("screenSize"))
-		ssaoSProg->findUniVar("screenSize")->set(&screenSize);
+	// noiseMap
+	ssaoSProg->findUniVar("noiseMap")->set(*noiseMap, 1);
 
+	// noiseMapSize
 	float noiseMapSize = noiseMap->getWidth();
-	if(ssaoSProg->uniVarExists("noiseMapSize"))
-		ssaoSProg->findUniVar("noiseMapSize")->set(&noiseMapSize);
+	ssaoSProg->findUniVar("noiseMapSize")->set(&noiseMapSize);
+
+	// screenSize
+	Vec2 screenSize(width, height);
+	ssaoSProg->findUniVar("screenSize")->set(&screenSize);
 
-	if(ssaoSProg->uniVarExists("msPosFai"))
-		ssaoSProg->findUniVar("msPosFai")->set(r.getMs().posFai, 3);
+	// msNormalFai
+	ssaoSProg->findUniVar("msNormalFai")->set(r.getMs().getNormalFai(), 2);
 
-	vao.bind();
-	glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_SHORT, 0);
-	vao.unbind();
+	r.drawQuad();
 
 
 	//

+ 1 - 9
src/Renderer/Ssao.h

@@ -30,7 +30,7 @@ class Ssao: private RenderingPass
 		GETTER_R(Texture, fai, getFai)
 		/// @}
 
-	public: /// @todo make private
+	private:
 		Texture ssaoFai; ///< It contains the unblurred SSAO factor
 		Texture hblurFai;
 		Texture fai;  ///< AKA vblurFai The final FAI
@@ -44,14 +44,6 @@ class Ssao: private RenderingPass
 		RsrcPtr<ShaderProg> ssaoSProg;
 		RsrcPtr<ShaderProg> hblurSProg;
 		RsrcPtr<ShaderProg> vblurSProg;
-		
-		/// @name For the quad drawing in light passes
-		/// @{
-		Vbo quadPositionsVbo; ///< The VBO for quad positions
-		Vbo viewVectorsVbo; ///< The VBO to pass the @ref viewVectors.
-		Vbo quadVertIndecesVbo; ///< The VBO for quad array buffer elements
-		Vao vao; ///< This VAO is used in light passes only
-		/// @}
 
 		void createFbo(Fbo& fbo, Texture& fai);
 };

+ 56 - 73
src/Resources/Texture/Texture.cpp

@@ -14,7 +14,7 @@
 //======================================================================================================================
 int Texture::textureUnitsNum = -1;
 bool Texture::mipmappingEnabled = true;
-bool Texture::compressionEnabled = false;
+bool Texture::compressionEnabled = true;
 int Texture::anisotropyLevel = 8;
 
 
@@ -60,111 +60,94 @@ void Texture::load(const char* filename)
 //======================================================================================================================
 void Texture::load(const Image& img)
 {
-	target = GL_TEXTURE_2D;
-	if(isLoaded())
-	{
-		throw EXCEPTION("Texture already loaded");
-	}
-
-	// bind the texture
-	glGenTextures(1, &glId);
-	bind(LAST_TEX_UNIT);
-	if(mipmappingEnabled)
-	{
-		setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-	}
-	else
-	{
-		setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	}
+	Initializer init;
+	init.width = img.getWidth();
+	init.height = img.getHeight();
 
-	setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
-	setTexParameter(GL_TEXTURE_MAX_ANISOTROPY_EXT, float(anisotropyLevel));
-
-	// leave to GL_REPEAT. There is not real performance hit
-	setRepeat(true);
-
-	// chose formats
-	int internalFormat;
-	int format;
-	int type;
 	switch(img.getColorType())
 	{
 		case Image::CT_R:
-			internalFormat = (compressionEnabled) ? GL_COMPRESSED_RED : GL_RED;
-			format = GL_RED;
-			type = GL_UNSIGNED_BYTE;
+			init.internalFormat = (compressionEnabled) ? GL_COMPRESSED_RED : GL_RED;
+			init.format = GL_RED;
+			init.type = GL_UNSIGNED_BYTE;
 			break;
 
 		case Image::CT_RGB:
-			internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGB : GL_RGB;
-			format = GL_RGB;
-			type = GL_UNSIGNED_BYTE;
+			init.internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGB : GL_RGB;
+			init.format = GL_RGB;
+			init.type = GL_UNSIGNED_BYTE;
 			break;
 
 		case Image::CT_RGBA:
-			internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGBA : GL_RGBA;
-			format = GL_RGBA;
-			type = GL_UNSIGNED_BYTE;
+			init.internalFormat = (compressionEnabled) ? GL_COMPRESSED_RGBA : GL_RGBA;
+			init.format = GL_RGBA;
+			init.type = GL_UNSIGNED_BYTE;
 			break;
 
 		default:
 			throw EXCEPTION("See file");
 	}
 
-	glTexImage2D(target, 0, internalFormat, img.getWidth(), img.getHeight(), 0, format, type, &img.getData()[0]);
-	if(mipmappingEnabled)
-	{
-		glGenerateMipmap(target);
-	}
+	init.data = &img.getData()[0];
+	init.mipmapping = mipmappingEnabled;
+	init.filteringType = TFT_TRILINEAR;
+	init.repeat = true;
+	init.anisotropyLevel = anisotropyLevel;
 
-	ON_GL_FAIL_THROW_EXCEPTION();
+	create(init);
 }
 
 
 //======================================================================================================================
-// createEmpty2D                                                                                                       =
+// create                                                                                                              =
 //======================================================================================================================
-void Texture::createEmpty2D(float width_, float height_, int internalFormat, int format_, uint type_)
+void Texture::create(const Initializer& init)
 {
-	target = GL_TEXTURE_2D;
-	ASSERT(internalFormat <= 0 || internalFormat > 4); // deprecated internal format
-	ASSERT(!isLoaded());
+	//
+	// Sanity checks
+	//
+	if(init.internalFormat <= 4)
+	{
+		throw EXCEPTION("Deprecated internal format");
+	}
 
-	// GL stuff
+	if(isLoaded())
+	{
+		throw EXCEPTION("Already loaded");
+	}
+
+	//
+	// Create
+	//
 	glGenTextures(1, &glId);
 	bind(LAST_TEX_UNIT);
+	target = GL_TEXTURE_2D;
 
-	setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	setRepeat(true);
-
-	// allocate to vram
-	glTexImage2D(target, 0, internalFormat, width_, height_, 0, format_, type_, NULL);
-
-	ON_GL_FAIL_THROW_EXCEPTION();
-}
+	glTexImage2D(target, 0, init.internalFormat, init.width, init.height, 0, init.format, init.type, init.data);
 
+	setRepeat(init.repeat);
 
-//======================================================================================================================
-// createEmpty2DMSAA                                                                                                   =
-//======================================================================================================================
-void Texture::createEmpty2DMsaa(int samplesNum, int internalFormat, int width_, int height_, bool mimapping)
-{
-	target = GL_TEXTURE_2D_MULTISAMPLE;
-	ASSERT(!isLoaded());
+	if(init.mipmapping)
+	{
+		glGenerateMipmap(target);
+	}
 
-	glGenTextures(1, &glId);
-	bind(LAST_TEX_UNIT);
-	
-	// allocate
-	glTexImage2DMultisample(target, samplesNum, internalFormat, width_, height_, false);
+	// If not mipmapping then the filtering cannot be trilinear
+	if(init.filteringType == TFT_TRILINEAR && !init.mipmapping)
+	{
+		setFiltering(TFT_LINEAR);
+	}
+	else
+	{
+		setFiltering(init.filteringType);
+	}
 
-	if(mimapping)
+	if(init.anisotropyLevel > 1)
 	{
-		glGenerateMipmap(target);
+		setTexParameter(GL_TEXTURE_MAX_ANISOTROPY_EXT, float(init.anisotropyLevel));
 	}
+
+	ON_GL_FAIL_THROW_EXCEPTION();
 }
 
 

+ 17 - 7
src/Resources/Texture/Texture.h

@@ -29,6 +29,21 @@ class Texture
 			TFT_TRILINEAR
 		};
 
+		/// Texture initializer struct
+		struct Initializer
+		{
+			float width;
+			float height;
+			int internalFormat;
+			int format;
+			uint type;
+			const void* data;
+			bool mipmapping;
+			TextureFilteringType filteringType;
+			bool repeat;
+			int anisotropyLevel;
+		};
+
 		Texture();
 		~Texture();
 		uint getGlId() const;
@@ -43,13 +58,8 @@ class Texture
 		/// @exception Exception
 		void load(const Image& img);
 
-		/// Create empty texture.
-		/// Used by the Renderer
-		void createEmpty2D(float width, float height, int internalFormat, int format, uint type_);
-
-		/// Create empty texture with MSAA.
-		/// Used by the Renderer
-		void createEmpty2DMsaa(int samplesNum, int internalFormat, int width_, int height_, bool mimapping);
+		/// Create a texture
+		void create(const Initializer& init);
 		/// @}
 
 		void bind(uint texUnit = 0) const;