Преглед изворни кода

Made HDR into a rendering pass, added comms between rendering passes

Made HDR mapping into a separate rendering pass, so it's easier to work on it, as it's decoupled now.
Added data sharing between rendering passes.
Added input/output buffer locations that are shared between rendering passes, so separate passes can be added/removed without modifying the buffer locations in subsequent passes.
Added emissive color mulptiplyer, HDR adaption rate and HDR intended brightness values to config and uniforms, so they can be modified without recompiling.
Added a post process rendering pass as a placeholder for future effects, which now just acts as pass-through.
Adjusted HDR mapping values for a better looking visual effect and faster eye adaption.
Paulcodedev пре 7 година
родитељ
комит
2ab8e13740

+ 2 - 0
.gitignore

@@ -18,3 +18,5 @@ Builds/x64/Release 64bit/Praxis3D\.ipdb
 *.dae
 *.dae
 
 
 Praxis3D/x64/
 Praxis3D/x64/
+
+Praxis3D/Data/Maps/default_lite backup\.pmap

+ 30 - 5
Praxis3D/Data/Maps/default_lite.pmap

@@ -21,7 +21,32 @@
 					"Name": "DirectionalLight 1",
 					"Name": "DirectionalLight 1",
 					"Color": "1.0f, 1.0f, 1.0f",
 					"Color": "1.0f, 1.0f, 1.0f",
 					"Direction": "0.006461f, -0.707092f, -0.707092f",
 					"Direction": "0.006461f, -0.707092f, -0.707092f",
-					"Intensity": "0.5f"
+					"Intensity": "0.1f"
+				},
+				{
+					"Type": "EnvironmentMapStatic",
+					"Position": "0.0f, 0.0f, 0.0f",
+					"Materials": 
+					[
+						{
+							"Filename": "posx.jpg"
+						},
+						{
+							"Filename": "negx.jpg"
+						},
+						{
+							"Filename": "posy.jpg"
+						},
+						{
+							"Filename": "negy.jpg"
+						},
+						{
+							"Filename": "posz.jpg"
+						},
+						{
+							"Filename": "negz.jpg"
+						}
+					]
 				},
 				},
 				{
 				{
 					"Type": "ModelObject",
 					"Type": "ModelObject",
@@ -871,7 +896,7 @@
 					"CutoffAngle": "60.0f",
 					"CutoffAngle": "60.0f",
 					"Color": "1.0f, 1.0f, 1.0f",
 					"Color": "1.0f, 1.0f, 1.0f",
 					"Direction": "-1.0f, 0.0f, 0.0f",
 					"Direction": "-1.0f, 0.0f, 0.0f",
-					"Intensity": "20000.0f",
+					"Intensity": "500.0f",
 					"OffsetPosition": "0.0f, 0.0f, 0.0f",
 					"OffsetPosition": "0.0f, 0.0f, 0.0f",
 					"OffsetRotation": "0.0f, 0.0f, 0.0f",
 					"OffsetRotation": "0.0f, 0.0f, 0.0f",
 					"Position": "60.0f, 3.0f, 60.0f"
 					"Position": "60.0f, 3.0f, 60.0f"
@@ -883,7 +908,7 @@
 					"CutoffAngle": "60.0f",
 					"CutoffAngle": "60.0f",
 					"Color": "0.0f, 1.0f, 0.0f",
 					"Color": "0.0f, 1.0f, 0.0f",
 					"Direction": "-0.145991f, 0.0f, 0.989286f",
 					"Direction": "-0.145991f, 0.0f, 0.989286f",
-					"Intensity": "500.0f",
+					"Intensity": "300.0f",
 					"OffsetPosition": "0.0f, 0.0f, 0.0f",
 					"OffsetPosition": "0.0f, 0.0f, 0.0f",
 					"OffsetRotation": "0.0f, 0.0f, 0.0f",
 					"OffsetRotation": "0.0f, 0.0f, 0.0f",
 					"Position": "-40.0f, 3.0f, 1.96449f"
 					"Position": "-40.0f, 3.0f, 1.96449f"
@@ -895,7 +920,7 @@
 					"CutoffAngle": "60.0f",
 					"CutoffAngle": "60.0f",
 					"Color": "1.0f, 0.0f, 0.0f",
 					"Color": "1.0f, 0.0f, 0.0f",
 					"Direction": "0.145991f, 0.0f, -0.989286f",
 					"Direction": "0.145991f, 0.0f, -0.989286f",
-					"Intensity": "500.0f",
+					"Intensity": "300.0f",
 					"OffsetPosition": "0.0f, 0.0f, 0.0f",
 					"OffsetPosition": "0.0f, 0.0f, 0.0f",
 					"OffsetRotation": "0.0f, 0.0f, 0.0f",
 					"OffsetRotation": "0.0f, 0.0f, 0.0f",
 					"Position": "-40.0f, 3.0f, 1.96449f"
 					"Position": "-40.0f, 3.0f, 1.96449f"
@@ -907,7 +932,7 @@
 					"CutoffAngle": "60.0f",
 					"CutoffAngle": "60.0f",
 					"Color": "1.0f, 1.0f, 1.0f",
 					"Color": "1.0f, 1.0f, 1.0f",
 					"Direction": "0.707107f, 0.0f, 0.707107f",
 					"Direction": "0.707107f, 0.0f, 0.707107f",
-					"Intensity": "200.0f",
+					"Intensity": "500.0f",
 					"OffsetPosition": "0.0f, 0.0f, 0.0f",
 					"OffsetPosition": "0.0f, 0.0f, 0.0f",
 					"OffsetRotation": "0.0f, 0.0f, 0.0f",
 					"OffsetRotation": "0.0f, 0.0f, 0.0f",
 					"Position": "-20.0f, 3.0f, -20.0f"
 					"Position": "-20.0f, 3.0f, -20.0f"

+ 9 - 8
Praxis3D/Data/Shaders/finalPass.frag

@@ -8,8 +8,9 @@ out vec4 outputColor;
 
 
 uniform ivec2 screenSize;
 uniform ivec2 screenSize;
 uniform float gamma;
 uniform float gamma;
+
 uniform sampler2D emissiveMap;
 uniform sampler2D emissiveMap;
-uniform sampler2D finalColorMap;
+uniform sampler2D inputColorMap;
 
 
 vec3 gammaCorrection(vec3 p_color, float p_gamma)
 vec3 gammaCorrection(vec3 p_color, float p_gamma)
 {
 {
@@ -51,29 +52,29 @@ void main(void)
 	vec2 texCoord = calcTexCoord();
 	vec2 texCoord = calcTexCoord();
 	
 	
 	// Perform gamma correction on the color from the final framebuffer
 	// Perform gamma correction on the color from the final framebuffer
-	vec3 color = texture(finalColorMap, texCoord).xyz;
+	vec3 fragmentColor = texture(inputColorMap, texCoord).xyz;
 	
 	
 	// Add emissive color (which is generated in a blur pass)
 	// Add emissive color (which is generated in a blur pass)
-	color += texture(emissiveMap, texCoord).xyz;
+	fragmentColor += texture(emissiveMap, texCoord).xyz;
 		
 		
 	#ifdef ENABLE_TONE_MAPPING
 	#ifdef ENABLE_TONE_MAPPING
 	// Perform simple tonemapping on the final color
 	// Perform simple tonemapping on the final color
-	color = simpleToneMapping(color);
+	fragmentColor = simpleToneMapping(fragmentColor);
 	#endif
 	#endif
 	
 	
 	#ifdef ENABLE_REINHARD_TONE_MAPPING
 	#ifdef ENABLE_REINHARD_TONE_MAPPING
 	// Perform reinhard tonemapping on the final color
 	// Perform reinhard tonemapping on the final color
-	color = reinhardToneMapping(color);
+	fragmentColor = reinhardToneMapping(fragmentColor);
 	#endif
 	#endif
 	
 	
 	#ifdef ENABLE_FILMIC_TONE_MAPPING
 	#ifdef ENABLE_FILMIC_TONE_MAPPING
 	// Perform filmic tonemapping on the final color
 	// Perform filmic tonemapping on the final color
-	color = filmicToneMapping(color);
+	fragmentColor = filmicToneMapping(fragmentColor);
 	#endif
 	#endif
 	
 	
 	// Perform gamma correction as the last step of the fragment color
 	// Perform gamma correction as the last step of the fragment color
-	color = gammaCorrection(color, gamma);
+	fragmentColor = gammaCorrection(fragmentColor, gamma);
 	
 	
 	// Write the color to the framebuffer
 	// Write the color to the framebuffer
-	outputColor = vec4(color, 1.0);
+	outputColor = vec4(fragmentColor, 1.0);
 }
 }

+ 1 - 47
Praxis3D/Data/Shaders/finalPass.vert

@@ -1,53 +1,7 @@
 #version 430 core
 #version 430 core
 
 
-#define ENABLE_HDR
-
-layout(std430, binding = 0) buffer HDRBuffer
-{
-	float screenBrightness;
-};
-
-uniform float eyeAdaptionRate;
-uniform float deltaTimeS;
-uniform ivec2 screenSize;
-uniform sampler2D finalColorMap;
-
-// Calculates the maximum texture mipmap level
-float calcMaxMipmapLevel(vec2 p_textureSize)
-{
-	return 1 + floor(log2(max(p_textureSize.x, p_textureSize.y)));
-}
-
-// Averages RGB color into a single brightness value
-float calcAverageBrightness(vec3 p_color)
-{
-	return (p_color.x + p_color.y + p_color.z) / 3.0;
-}
-
-// Calculates a brightness value from a color
-float calcBrightness(vec3 p_color)
-{
-	return dot(p_color, vec3(0.2126, 0.7152, 0.0722));
-}
-
 void main(void) 
 void main(void) 
-{
-	#ifdef ENABLE_HDR
-	
-	// Get maximum mipmap level (1x1) of a framebuffer
-	float exposureMipmapLevel = calcMaxMipmapLevel(screenSize);
-	// Get the current (previous frame) average brightness
-	float avgBrightnessPrevFrame = calcAverageBrightness(textureLod(finalColorMap, vec2(0.0), exposureMipmapLevel).xyz);
-	// Perform a linear interpolation between current and previous brightness based on delta time
-	screenBrightness = mix(screenBrightness, avgBrightnessPrevFrame, deltaTimeS * eyeAdaptionRate);
-	
-	#else
-	
-	// Set the average brightness to 0.5 so it does not affect the scene
-	screenBrightness = 0.5;
-	
-	#endif
-	
+{	
 	// Determine texture coordinates
 	// Determine texture coordinates
 	vec2 texCoord = vec2((gl_VertexID == 2) ?  2.0 :  0.0, (gl_VertexID == 1) ?  2.0 :  0.0);
 	vec2 texCoord = vec2((gl_VertexID == 2) ?  2.0 :  0.0, (gl_VertexID == 1) ?  2.0 :  0.0);
 	
 	

+ 4 - 4
Praxis3D/Data/Shaders/gaussianBlurHorizontal.frag

@@ -5,7 +5,7 @@ in vec2 blurTexCoords[14];
 
 
 out vec4 outputColor;
 out vec4 outputColor;
 
 
-uniform sampler2D blurMap;
+uniform sampler2D inputColorMap;
 uniform ivec2 screenSize;
 uniform ivec2 screenSize;
 
 
 uniform float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
 uniform float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
@@ -25,12 +25,12 @@ void main(void)
 	float blurOffset = 1.0;
 	float blurOffset = 1.0;
 	
 	
 	vec2 tex_offset = 1.0 / screenSize; // gets size of single texel
 	vec2 tex_offset = 1.0 / screenSize; // gets size of single texel
-    fragColor = texture(blurMap, texCoord).rgb * weight[0]; // current fragment's contribution
+    fragColor = texture(inputColorMap, texCoord).rgb * weight[0]; // current fragment's contribution
 	
 	
 	for(int i = 1; i < 5; ++i)
 	for(int i = 1; i < 5; ++i)
 	{
 	{
-		fragColor += texture(blurMap, texCoord + vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
-		fragColor += texture(blurMap, texCoord - vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
+		fragColor += texture(inputColorMap, texCoord + vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
+		fragColor += texture(inputColorMap, texCoord - vec2(tex_offset.x * i, 0.0)).rgb * weight[i];
 	}
 	}
 		
 		
 	/*
 	/*

+ 4 - 4
Praxis3D/Data/Shaders/gaussianBlurVertical.frag

@@ -7,7 +7,7 @@ in vec2 blurTexCoords[14];
 out vec4 outputColor;
 out vec4 outputColor;
 //layout(location = 0) out vec4 blurBuffer;
 //layout(location = 0) out vec4 blurBuffer;
 
 
-uniform sampler2D emissiveMap;
+uniform sampler2D inputColorMap;
 uniform ivec2 screenSize;
 uniform ivec2 screenSize;
 
 
 uniform float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
 uniform float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216);
@@ -27,12 +27,12 @@ void main(void)
 	float blurOffset = 1.0;
 	float blurOffset = 1.0;
 	
 	
 	vec2 tex_offset = 1.0 / screenSize; // gets size of single texel
 	vec2 tex_offset = 1.0 / screenSize; // gets size of single texel
-    fragColor = texture(emissiveMap, texCoord).rgb * weight[0]; // current fragment's contribution
+    fragColor = texture(inputColorMap, texCoord).rgb * weight[0]; // current fragment's contribution
 	
 	
 	for(int i = 1; i < 5; ++i)
 	for(int i = 1; i < 5; ++i)
 	{
 	{
-		fragColor += texture(emissiveMap, texCoord + vec2(0.0, tex_offset.y * i)).rgb * weight[i];
-		fragColor += texture(emissiveMap, texCoord - vec2(0.0, tex_offset.y * i)).rgb * weight[i];
+		fragColor += texture(inputColorMap, texCoord + vec2(0.0, tex_offset.y * i)).rgb * weight[i];
+		fragColor += texture(inputColorMap, texCoord - vec2(0.0, tex_offset.y * i)).rgb * weight[i];
 	}
 	}
 		
 		
 	/*
 	/*

+ 9 - 8
Praxis3D/Data/Shaders/geometryPass.frag

@@ -3,8 +3,8 @@
 #define MIN_LOD_PARALLAX 0.0
 #define MIN_LOD_PARALLAX 0.0
 #define MAX_LOD_PARALLAX 10.0
 #define MAX_LOD_PARALLAX 10.0
 #define LOD_PARALLAX_THRESHOLD 0.0
 #define LOD_PARALLAX_THRESHOLD 0.0
-#define HEIGHT_SCALE_THRESHOLD 0.001
-#define ROUGHNESS_MIN 0.001
+#define PARALLAX_SCALE_THRESHOLD 0.001
+#define MIN_ROUGHNESS 0.001
 
 
 // Some drivers require the following
 // Some drivers require the following
 //precision highp float;
 //precision highp float;
@@ -44,6 +44,7 @@ uniform sampler2D normalTexture;
 uniform sampler2D emissiveTexture;
 uniform sampler2D emissiveTexture;
 
 
 uniform float alphaThreshold;
 uniform float alphaThreshold;
+uniform float emissiveMultiplier;
 uniform float emissiveThreshold;
 uniform float emissiveThreshold;
 
 
 /*
 /*
@@ -89,7 +90,7 @@ float getHeight(const vec2 p_texCoords, const vec2 p_dPdx, const vec2 p_dPdy)
 
 
 float getRoughness(const vec2 p_texCoords)
 float getRoughness(const vec2 p_texCoords)
 {
 {
-	return max(texture(combinedTexture, p_texCoords).r, ROUGHNESS_MIN);
+	return max(texture(combinedTexture, p_texCoords).r, MIN_ROUGHNESS);
 }
 }
 float getMetalness(const vec2 p_texCoords)
 float getMetalness(const vec2 p_texCoords)
 {
 {
@@ -325,14 +326,13 @@ void main(void)
 	
 	
 	// This is to save performance by not performing the
 	// This is to save performance by not performing the
 	// parallax mapping for objects that it was not intended for
 	// parallax mapping for objects that it was not intended for
-	if((1.0 - height) * parallaxScale > HEIGHT_SCALE_THRESHOLD)
+	if((1.0 - height) * parallaxScale > PARALLAX_SCALE_THRESHOLD)
 	{
 	{
 		vec3 viewDir = tangentCameraPos - tangentFragPos;
 		vec3 viewDir = tangentCameraPos - tangentFragPos;
 		float distanceToFrag = length(viewDir);
 		float distanceToFrag = length(viewDir);
 		viewDir = normalize(viewDir);
 		viewDir = normalize(viewDir);
-		float LOD = min(((10.0 - distanceToFrag) / 10.0), 1.0);
 		
 		
-		LOD = clamp(1.0 - ((distanceToFrag * distanceToFrag) / parallaxLOD), MIN_LOD_PARALLAX, MAX_LOD_PARALLAX);
+		float LOD = clamp(1.0 - ((distanceToFrag * distanceToFrag) / parallaxLOD), MIN_LOD_PARALLAX, MAX_LOD_PARALLAX);
 		
 		
 		if(LOD > LOD_PARALLAX_THRESHOLD)
 		if(LOD > LOD_PARALLAX_THRESHOLD)
 			newCoords = parallaxOcclusionMapping(texCoord, viewDir, LOD);
 			newCoords = parallaxOcclusionMapping(texCoord, viewDir, LOD);
@@ -343,7 +343,7 @@ void main(void)
 		//float LOD = min(((10.0 - distanceToFrag) / 10.0), 1.0);
 		//float LOD = min(((10.0 - distanceToFrag) / 10.0), 1.0);
 		//float LOD2 = clamp((distanceToFrag - 8.0) / 2.0, 0.0, 1.0);
 		//float LOD2 = clamp((distanceToFrag - 8.0) / 2.0, 0.0, 1.0);
 	
 	
-		//if(parallaxScale > HEIGHT_SCALE_THRESHOLD)
+		//if(parallaxScale > PARALLAX_SCALE_THRESHOLD)
 		//	newCoords = mix(parallaxOcclusionMapping(texCoord, viewDir, LOD), texCoord, 1.0 - LOD);
 		//	newCoords = mix(parallaxOcclusionMapping(texCoord, viewDir, LOD), texCoord, 1.0 - LOD);
 	//}
 	//}
 	
 	
@@ -362,13 +362,14 @@ void main(void)
 	// Get roughness and metalness values, and emissive color
 	// Get roughness and metalness values, and emissive color
 	float roughness = getRoughness(newCoords);
 	float roughness = getRoughness(newCoords);
 	float metalness = getMetalness(newCoords);
 	float metalness = getMetalness(newCoords);
+	//vec4 emissiveColor = pow(texture(emissiveTexture, newCoords), vec4(gamma, gamma, gamma, 1.0));
 	vec4 emissiveColor = texture(emissiveTexture, newCoords).rgba;
 	vec4 emissiveColor = texture(emissiveTexture, newCoords).rgba;
 	
 	
 	// Apply emissive color only if it's above the threshold
 	// Apply emissive color only if it's above the threshold
 	if(emissiveColor.a > emissiveThreshold)
 	if(emissiveColor.a > emissiveThreshold)
 	{
 	{
 		// Use emissive alpha channel as an intensity multiplier
 		// Use emissive alpha channel as an intensity multiplier
-		emissiveColor *= emissiveColor.a * 10.0;
+		emissiveColor *= emissiveColor.a * emissiveMultiplier;
 	}
 	}
 	else
 	else
 	{
 	{

+ 79 - 0
Praxis3D/Data/Shaders/hdrMappingPass.frag

@@ -0,0 +1,79 @@
+#version 430 core
+
+//#define AVG_INTENDED_BRIGHTNESS 0.2
+#define MIN_INTENDED_BRIGHTNESS 0.01
+#define MAX_INTENDED_BRIGHTNESS 10.0
+
+#define MAX_NUM_POINT_LIGHTS 20
+#define MAX_NUM_SPOT_LIGHTS 10
+#define PI 3.1415926535
+
+/*
+layout(std430, binding = 0) buffer HDRBuffer
+{
+	float screenBrightness;
+};*/
+
+layout(location = 0) out vec4 emissiveBuffer;
+layout(location = 1) out vec4 colorBuffer;
+
+in float avgBrightness;
+
+uniform sampler2D emissiveMap;
+uniform sampler2D inputColorMap;
+
+uniform mat4 modelViewMat;
+uniform mat4 viewMat;
+uniform vec3 cameraPosVec;
+uniform ivec2 screenSize;
+uniform float eyeAdaptionIntBrightness;
+uniform float gamma;
+
+float getBrightestColor(vec3 p_color)
+{
+	return max(p_color.x, max(p_color.y, p_color.z));
+}
+
+// Calculates a brightness value from a color
+float calcBrightness(vec3 p_color)
+{
+	return dot(p_color, vec3(0.2126, 0.7152, 0.0722));
+}
+
+// Adjusts an RGB color based on the average brightness (exposure)
+// by making overall brightness match the average intended brightness (eyeAdaptionIntBrightness)
+vec3 brightnessMapping(vec3 p_color, float p_exposure)
+{
+	return p_color * clamp(eyeAdaptionIntBrightness / p_exposure, MIN_INTENDED_BRIGHTNESS, MAX_INTENDED_BRIGHTNESS);
+}
+
+float saturate(float p_value)
+{
+	return clamp(p_value, 0.0f, 1.0f);
+}
+
+vec2 calcTexCoord(void)
+{
+    return gl_FragCoord.xy / screenSize;
+}
+
+void main(void) 
+{
+	// Calculate screen-space texture coordinates, for buffer access
+	vec2 texCoord = calcTexCoord();
+	// Get the emissive texture color
+	vec3 emissiveColor = /*pow(*/texture(emissiveMap, texCoord).xyz/*, vec3(gamma))*/;
+	// Get the emissive texture color
+	vec3 fragmentColor = texture(inputColorMap, texCoord).xyz;
+	
+	// Adjust the fragment brightness based on average
+	fragmentColor = brightnessMapping(fragmentColor, avgBrightness);
+	
+	// If a fragment brightness exceeds a value of 1.0 after an HDR Mapping, 
+	// add it to the emissive buffer, as a bloom effect
+	if(calcBrightness(fragmentColor) > 1.0)
+		emissiveColor += fragmentColor;
+	
+	emissiveBuffer = vec4(emissiveColor, 1.0);
+	colorBuffer = vec4(fragmentColor, 1.0);
+}

+ 68 - 0
Praxis3D/Data/Shaders/hdrMappingPass.vert

@@ -0,0 +1,68 @@
+#version 430 core
+
+#define ENABLE_HDR
+
+layout(std430, binding = 0) buffer HDRBuffer
+{
+	float screenBrightness;
+};
+
+out float avgBrightness;
+
+uniform float eyeAdaptionRate;
+uniform float deltaTimeS;
+uniform ivec2 screenSize;
+
+uniform sampler2D finalColorMap;
+
+// Calculates the maximum texture mipmap level
+float calcMaxMipmapLevel(vec2 p_textureSize)
+{
+	return 1 + floor(log2(max(p_textureSize.x, p_textureSize.y)));
+}
+
+// Returns the single brightest color
+float getBrightestColor(vec3 p_color)
+{
+	return max(p_color.r, max(p_color.g, p_color.b));
+}
+
+// Averages RGB color into a single brightness value
+float calcBrightnessLinear(vec3 p_color)
+{
+	return (p_color.x + p_color.y + p_color.z) / 3.0;
+}
+
+// Calculates a brightness value from a color
+float calcBrightness(vec3 p_color)
+{
+	return dot(p_color, vec3(0.2126, 0.7152, 0.0722));
+}
+
+void main(void) 
+{
+	#ifdef ENABLE_HDR
+	
+	// Get maximum mipmap level (1x1) of a framebuffer
+	float exposureMipmapLevel = calcMaxMipmapLevel(screenSize);
+	// Get the current (previous frame) average brightness
+	float avgBrightnessPrevFrame = calcBrightness(textureLod(finalColorMap, vec2(0.0), exposureMipmapLevel).xyz);
+	// Perform a linear interpolation between current and previous brightness based on delta time
+	screenBrightness = mix(screenBrightness, avgBrightnessPrevFrame, deltaTimeS / eyeAdaptionRate);
+	
+	#else
+	
+	// Set the average brightness to 0.5 so it does not affect the scene
+	screenBrightness = 0.5;
+	
+	#endif
+	
+	// Send the average brightness value to the fragment shader
+	avgBrightness = screenBrightness;
+	
+	// Determine texture coordinates
+	vec2 texCoord = vec2((gl_VertexID == 2) ?  2.0 :  0.0, (gl_VertexID == 1) ?  2.0 :  0.0);
+	
+	// Calculate the position, so that the triangle fills the whole screen
+	gl_Position = vec4(texCoord * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 1.0, 1.0);
+}

+ 1 - 1
Praxis3D/Data/Shaders/lightPass.vert

@@ -18,5 +18,5 @@ void main(void)
 	vec2 texCoord = vec2((gl_VertexID == 2) ?  2.0 :  0.0, (gl_VertexID == 1) ?  2.0 :  0.0);
 	vec2 texCoord = vec2((gl_VertexID == 2) ?  2.0 :  0.0, (gl_VertexID == 1) ?  2.0 :  0.0);
 	
 	
 	// Calculate the position, so that the triangle fills the whole screen
 	// Calculate the position, so that the triangle fills the whole screen
-	gl_Position = vec4(texCoord * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0);
+	gl_Position = vec4(texCoord * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 1.0, 1.0);
 }
 }

+ 24 - 0
Praxis3D/Data/Shaders/postProcessPass.frag

@@ -0,0 +1,24 @@
+#version 430 core
+
+out vec4 outputColor;
+
+uniform ivec2 screenSize;
+
+uniform sampler2D inputColorMap;
+
+vec2 calcTexCoord(void)
+{
+    return gl_FragCoord.xy / screenSize;
+}
+
+void main(void)
+{
+	// Calculate screen-space texture coordinates, for buffer access
+	vec2 texCoord = calcTexCoord();
+	
+	// Get the current fragment color
+	vec3 fragmentColor = texture(inputColorMap, texCoord).xyz;
+	
+	// Write the color to the framebuffer
+	outputColor = vec4(fragmentColor, 1.0);
+}

+ 10 - 0
Praxis3D/Data/Shaders/postProcessPass.vert

@@ -0,0 +1,10 @@
+#version 430 core
+
+void main(void) 
+{	
+	// Determine texture coordinates
+	vec2 texCoord = vec2((gl_VertexID == 2) ?  2.0 :  0.0, (gl_VertexID == 1) ?  2.0 :  0.0);
+	
+	// Calculate the position, so that the triangle fills the whole screen
+	gl_Position = vec4(texCoord * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 1.0, 1.0);
+}

+ 3 - 0
Praxis3D/Praxis3D.vcxproj

@@ -362,6 +362,7 @@
     <ClInclude Include="Source\GeometryBuffer.h" />
     <ClInclude Include="Source\GeometryBuffer.h" />
     <ClInclude Include="Source\GeometryPass.h" />
     <ClInclude Include="Source\GeometryPass.h" />
     <ClInclude Include="Source\GraphicsDataSets.h" />
     <ClInclude Include="Source\GraphicsDataSets.h" />
+    <ClInclude Include="Source\HdrMappingPass.h" />
     <ClInclude Include="Source\Input.h" />
     <ClInclude Include="Source\Input.h" />
     <ClInclude Include="Source\KeyCommand.h" />
     <ClInclude Include="Source\KeyCommand.h" />
     <ClInclude Include="Source\LightingGraphicsObjects.h" />
     <ClInclude Include="Source\LightingGraphicsObjects.h" />
@@ -376,6 +377,7 @@
     <ClInclude Include="Source\ObjectPool.h" />
     <ClInclude Include="Source\ObjectPool.h" />
     <ClInclude Include="Source\ObserverBase.h" />
     <ClInclude Include="Source\ObserverBase.h" />
     <ClInclude Include="Source\PlayState.h" />
     <ClInclude Include="Source\PlayState.h" />
+    <ClInclude Include="Source\PostProcessPass.h" />
     <ClInclude Include="Source\PropertyLoader.h" />
     <ClInclude Include="Source\PropertyLoader.h" />
     <ClInclude Include="Source\PropertySet.h" />
     <ClInclude Include="Source\PropertySet.h" />
     <ClInclude Include="Source\ReflectionPass.h" />
     <ClInclude Include="Source\ReflectionPass.h" />
@@ -397,6 +399,7 @@
     <ClInclude Include="Source\ShaderLoader.h" />
     <ClInclude Include="Source\ShaderLoader.h" />
     <ClInclude Include="Source\ShaderUniforms.h" />
     <ClInclude Include="Source\ShaderUniforms.h" />
     <ClInclude Include="Source\ShaderUniformUpdater.h" />
     <ClInclude Include="Source\ShaderUniformUpdater.h" />
+    <ClInclude Include="Source\SkyPass.h" />
     <ClInclude Include="Source\SolarTimeScript.h" />
     <ClInclude Include="Source\SolarTimeScript.h" />
     <ClInclude Include="Source\SpinWait.h" />
     <ClInclude Include="Source\SpinWait.h" />
     <ClInclude Include="Source\System.h" />
     <ClInclude Include="Source\System.h" />

+ 9 - 0
Praxis3D/Praxis3D.vcxproj.filters

@@ -500,6 +500,15 @@
     <ClInclude Include="Source\DebugRotateScript.h">
     <ClInclude Include="Source\DebugRotateScript.h">
       <Filter>Scripting\Objects\Header Files</Filter>
       <Filter>Scripting\Objects\Header Files</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Source\SkyPass.h">
+      <Filter>Renderer\Render Passes\Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\HdrMappingPass.h">
+      <Filter>Renderer\Render Passes\Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Source\PostProcessPass.h">
+      <Filter>Renderer\Render Passes\Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <None Include="Data\config.ini" />
     <None Include="Data\config.ini" />

+ 6 - 6
Praxis3D/Source/BlurPass.h

@@ -53,18 +53,18 @@ public:
 		return returnError;
 		return returnError;
 	}
 	}
 
 
-	void update(const SceneObjects &p_sceneObjects, const float p_deltaTime)
+	void update(RenderPassData &p_renderPassData, const SceneObjects &p_sceneObjects, const float p_deltaTime)
 	{
 	{
 		glDisable(GL_DEPTH_TEST);
 		glDisable(GL_DEPTH_TEST);
-
+		
 		// Set the default framebuffer to be drawn to
 		// Set the default framebuffer to be drawn to
 		//m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferDefault);
 		//m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferDefault);
-
+		
 		// Bind emissive texture for reading so it can be accessed in the shaders
 		// Bind emissive texture for reading so it can be accessed in the shaders
-		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferEmissive, GeometryBuffer::GBufferEmissive);
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(p_renderPassData.getEmissiveInputMap(), GeometryBuffer::GBufferInputTexture);
 
 
 		// Bind blur texture for writing to, so it can be used as an intermediate buffer between blur passes
 		// Bind blur texture for writing to, so it can be used as an intermediate buffer between blur passes
-		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(GeometryBuffer::GBufferBlur);
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getColorOutputMap());
 
 
 		// Perform verical blur. Queue and render a full screen quad using a vertical blur shader
 		// Perform verical blur. Queue and render a full screen quad using a vertical blur shader
 		m_renderer.queueForDrawing(m_blurVerticalShader->getShaderHandle(), m_blurVerticalShader->getUniformUpdater(), p_sceneObjects.m_camera->getBaseObjectData().m_modelMat);
 		m_renderer.queueForDrawing(m_blurVerticalShader->getShaderHandle(), m_blurVerticalShader->getUniformUpdater(), p_sceneObjects.m_camera->getBaseObjectData().m_modelMat);
@@ -72,7 +72,7 @@ public:
 
 
 
 
 		// Bind intermediate blur texture for reading so it can be accessed in the shaders
 		// Bind intermediate blur texture for reading so it can be accessed in the shaders
-		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferBlur, GeometryBuffer::GBufferBlur);
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(p_renderPassData.getColorOutputMap(), GeometryBuffer::GBufferInputTexture);
 
 
 		// Bind emissive texture for writing to, so the second pass populates it with the final blur result
 		// Bind emissive texture for writing to, so the second pass populates it with the final blur result
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(GeometryBuffer::GBufferEmissive);
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(GeometryBuffer::GBufferEmissive);

+ 9 - 1
Praxis3D/Source/Config.cpp

@@ -113,8 +113,10 @@ void Config::init()
 	AddVariablePredef(m_graphicsVar, multisample_buffers);
 	AddVariablePredef(m_graphicsVar, multisample_buffers);
 	AddVariablePredef(m_graphicsVar, multisample_samples);
 	AddVariablePredef(m_graphicsVar, multisample_samples);
 	AddVariablePredef(m_graphicsVar, alpha_threshold);
 	AddVariablePredef(m_graphicsVar, alpha_threshold);
+	AddVariablePredef(m_graphicsVar, emissive_multiplier);
 	AddVariablePredef(m_graphicsVar, emissive_threshold);
 	AddVariablePredef(m_graphicsVar, emissive_threshold);
 	AddVariablePredef(m_graphicsVar, eye_adaption_rate);
 	AddVariablePredef(m_graphicsVar, eye_adaption_rate);
+	AddVariablePredef(m_graphicsVar, eye_adaption_intended_brightness);
 	AddVariablePredef(m_graphicsVar, fog_color_x);
 	AddVariablePredef(m_graphicsVar, fog_color_x);
 	AddVariablePredef(m_graphicsVar, fog_color_y);
 	AddVariablePredef(m_graphicsVar, fog_color_y);
 	AddVariablePredef(m_graphicsVar, fog_color_z);
 	AddVariablePredef(m_graphicsVar, fog_color_z);
@@ -223,6 +225,8 @@ void Config::init()
 	AddVariablePredef(m_rendererVar, light_pass_frag_shader);
 	AddVariablePredef(m_rendererVar, light_pass_frag_shader);
 	AddVariablePredef(m_rendererVar, final_pass_vert_shader);
 	AddVariablePredef(m_rendererVar, final_pass_vert_shader);
 	AddVariablePredef(m_rendererVar, final_pass_frag_shader);
 	AddVariablePredef(m_rendererVar, final_pass_frag_shader);
+	AddVariablePredef(m_rendererVar, final_pass_vert_shader);
+	AddVariablePredef(m_rendererVar, final_pass_frag_shader);
 	AddVariablePredef(m_rendererVar, reflection_pass_vert_shader);
 	AddVariablePredef(m_rendererVar, reflection_pass_vert_shader);
 	AddVariablePredef(m_rendererVar, reflection_pass_frag_shader);
 	AddVariablePredef(m_rendererVar, reflection_pass_frag_shader);
 	AddVariablePredef(m_rendererVar, dir_light_quad_offset_x);
 	AddVariablePredef(m_rendererVar, dir_light_quad_offset_x);
@@ -256,6 +260,7 @@ void Config::init()
 	AddVariablePredef(m_shaderVar, gammaUniform);
 	AddVariablePredef(m_shaderVar, gammaUniform);
 	AddVariablePredef(m_shaderVar, alphaCullingUniform);
 	AddVariablePredef(m_shaderVar, alphaCullingUniform);
 	AddVariablePredef(m_shaderVar, alphaThresholdUniform);
 	AddVariablePredef(m_shaderVar, alphaThresholdUniform);
+	AddVariablePredef(m_shaderVar, emissiveMultiplierUniform);
 	AddVariablePredef(m_shaderVar, emissiveThresholdUniform);
 	AddVariablePredef(m_shaderVar, emissiveThresholdUniform);
 	AddVariablePredef(m_shaderVar, heightScaleUniform);
 	AddVariablePredef(m_shaderVar, heightScaleUniform);
 	AddVariablePredef(m_shaderVar, combinedTextureUniform);
 	AddVariablePredef(m_shaderVar, combinedTextureUniform);
@@ -280,8 +285,10 @@ void Config::init()
 	AddVariablePredef(m_shaderVar, normalMapUniform);
 	AddVariablePredef(m_shaderVar, normalMapUniform);
 	AddVariablePredef(m_shaderVar, emissiveMapUniform);
 	AddVariablePredef(m_shaderVar, emissiveMapUniform);
 	AddVariablePredef(m_shaderVar, matPropertiesMapUniform);
 	AddVariablePredef(m_shaderVar, matPropertiesMapUniform);
-	AddVariablePredef(m_shaderVar, blurMapUniform);
+	AddVariablePredef(m_shaderVar, intermediateMapUniform);
 	AddVariablePredef(m_shaderVar, finalMapUniform);
 	AddVariablePredef(m_shaderVar, finalMapUniform);
+	AddVariablePredef(m_shaderVar, inputColorMapUniform);
+	AddVariablePredef(m_shaderVar, outputColorMapUniform);
 	AddVariablePredef(m_shaderVar, sunGlowTextureUniform);
 	AddVariablePredef(m_shaderVar, sunGlowTextureUniform);
 	AddVariablePredef(m_shaderVar, skyMapTextureUniform);
 	AddVariablePredef(m_shaderVar, skyMapTextureUniform);
 	AddVariablePredef(m_shaderVar, dirShadowMapTextureUniform);
 	AddVariablePredef(m_shaderVar, dirShadowMapTextureUniform);
@@ -296,6 +303,7 @@ void Config::init()
 	AddVariablePredef(m_shaderVar, billboardScaleUniform);
 	AddVariablePredef(m_shaderVar, billboardScaleUniform);
 	AddVariablePredef(m_shaderVar, depthTypeUniform);
 	AddVariablePredef(m_shaderVar, depthTypeUniform);
 	AddVariablePredef(m_shaderVar, eyeAdaptionRateUniform);
 	AddVariablePredef(m_shaderVar, eyeAdaptionRateUniform);
+	AddVariablePredef(m_shaderVar, eyeAdaptionIntBrightnessUniform);
 	AddVariablePredef(m_shaderVar, HDRSSBuffer);
 	AddVariablePredef(m_shaderVar, HDRSSBuffer);
 	AddVariablePredef(m_shaderVar, testMatUniform);
 	AddVariablePredef(m_shaderVar, testMatUniform);
 	AddVariablePredef(m_shaderVar, testVecUniform);
 	AddVariablePredef(m_shaderVar, testVecUniform);

+ 23 - 5
Praxis3D/Source/Config.h

@@ -557,8 +557,10 @@ public:
 			rendering_res_x = 1600;
 			rendering_res_x = 1600;
 			rendering_res_y = 900;
 			rendering_res_y = 900;
 			alpha_threshold = 0.0f;
 			alpha_threshold = 0.0f;
+			emissive_multiplier = 10.0f;
 			emissive_threshold = 0.01f;
 			emissive_threshold = 0.01f;
-			eye_adaption_rate = 0.5f;
+			eye_adaption_rate = 0.25f;
+			eye_adaption_intended_brightness = 0.2f;
 			fog_color_x = 0.55f;
 			fog_color_x = 0.55f;
 			fog_color_y = 0.55f;
 			fog_color_y = 0.55f;
 			fog_color_z = 0.55f;
 			fog_color_z = 0.55f;
@@ -593,8 +595,10 @@ public:
 		int rendering_res_x;
 		int rendering_res_x;
 		int rendering_res_y;
 		int rendering_res_y;
 		float alpha_threshold;
 		float alpha_threshold;
+		float emissive_multiplier;
 		float emissive_threshold;
 		float emissive_threshold;
 		float eye_adaption_rate;
 		float eye_adaption_rate;
+		float eye_adaption_intended_brightness;
 		float fog_color_x;
 		float fog_color_x;
 		float fog_color_y;
 		float fog_color_y;
 		float fog_color_z;
 		float fog_color_z;
@@ -775,12 +779,16 @@ public:
 			gaussian_blur_vertical_vert_shader = "gaussianBlurVertical.vert";
 			gaussian_blur_vertical_vert_shader = "gaussianBlurVertical.vert";
 			gaussian_blur_horizontal_frag_shader = "gaussianBlurHorizontal.frag";
 			gaussian_blur_horizontal_frag_shader = "gaussianBlurHorizontal.frag";
 			gaussian_blur_horizontal_vert_shader = "gaussianBlurHorizontal.vert";
 			gaussian_blur_horizontal_vert_shader = "gaussianBlurHorizontal.vert";
+			hdr_mapping_pass_frag_shader = "hdrMappingPass.frag";
+			hdr_mapping_pass_vert_shader = "hdrMappingPass.vert";
 			blur_pass_vert_shader = "blurPass.vert";
 			blur_pass_vert_shader = "blurPass.vert";
 			blur_pass_frag_shader = "blurPass.frag";
 			blur_pass_frag_shader = "blurPass.frag";
 			light_pass_vert_shader = "lightPass.vert";
 			light_pass_vert_shader = "lightPass.vert";
 			light_pass_frag_shader = "lightPass.frag";
 			light_pass_frag_shader = "lightPass.frag";
 			final_pass_vert_shader = "finalPass.vert";
 			final_pass_vert_shader = "finalPass.vert";
 			final_pass_frag_shader = "finalPass.frag";
 			final_pass_frag_shader = "finalPass.frag";
+			postProcess_pass_vert_shader = "postProcessPass.vert";
+			postProcess_pass_frag_shader = "postProcessPass.frag";
 			reflection_pass_vert_shader = "reflectionPass.vert";
 			reflection_pass_vert_shader = "reflectionPass.vert";
 			reflection_pass_frag_shader = "reflectionPass.frag";
 			reflection_pass_frag_shader = "reflectionPass.frag";
 			dir_light_quad_offset_x = 0.0f;
 			dir_light_quad_offset_x = 0.0f;
@@ -821,12 +829,16 @@ public:
 		std::string gaussian_blur_vertical_vert_shader;
 		std::string gaussian_blur_vertical_vert_shader;
 		std::string gaussian_blur_horizontal_frag_shader;
 		std::string gaussian_blur_horizontal_frag_shader;
 		std::string gaussian_blur_horizontal_vert_shader;
 		std::string gaussian_blur_horizontal_vert_shader;
+		std::string hdr_mapping_pass_frag_shader;
+		std::string hdr_mapping_pass_vert_shader;
 		std::string blur_pass_vert_shader;
 		std::string blur_pass_vert_shader;
 		std::string blur_pass_frag_shader;
 		std::string blur_pass_frag_shader;
 		std::string light_pass_vert_shader;
 		std::string light_pass_vert_shader;
 		std::string light_pass_frag_shader;
 		std::string light_pass_frag_shader;
 		std::string final_pass_vert_shader;
 		std::string final_pass_vert_shader;
 		std::string final_pass_frag_shader;
 		std::string final_pass_frag_shader;
+		std::string postProcess_pass_vert_shader;
+		std::string postProcess_pass_frag_shader;
 		std::string reflection_pass_vert_shader;
 		std::string reflection_pass_vert_shader;
 		std::string reflection_pass_frag_shader;
 		std::string reflection_pass_frag_shader;
 		float dir_light_quad_offset_x;
 		float dir_light_quad_offset_x;
@@ -863,6 +875,7 @@ public:
 			gammaUniform = "gamma";
 			gammaUniform = "gamma";
 			alphaCullingUniform = "alphaCulling";
 			alphaCullingUniform = "alphaCulling";
 			alphaThresholdUniform = "alphaThreshold";
 			alphaThresholdUniform = "alphaThreshold";
+			emissiveMultiplierUniform = "emissiveMultiplier";
 			emissiveThresholdUniform = "emissiveThreshold";
 			emissiveThresholdUniform = "emissiveThreshold";
 			heightScaleUniform = "heightScale";
 			heightScaleUniform = "heightScale";
 			textureTilingFactorUniform = "textureTilingFactor";
 			textureTilingFactorUniform = "textureTilingFactor";
@@ -892,8 +905,10 @@ public:
 			normalMapUniform = "normalMap";
 			normalMapUniform = "normalMap";
 			emissiveMapUniform = "emissiveMap";
 			emissiveMapUniform = "emissiveMap";
 			matPropertiesMapUniform = "matPropertiesMap";
 			matPropertiesMapUniform = "matPropertiesMap";
-			blurMapUniform = "blurMap";
+			intermediateMapUniform = "intermediateMap";
 			finalMapUniform = "finalColorMap";
 			finalMapUniform = "finalColorMap";
+			inputColorMapUniform = "inputColorMap";
+			outputColorMapUniform = "outputColorMap";
 
 
 			sunGlowTextureUniform = "sunGlowMap";
 			sunGlowTextureUniform = "sunGlowMap";
 			skyMapTextureUniform = "skyMap";
 			skyMapTextureUniform = "skyMap";
@@ -902,7 +917,6 @@ public:
 			normalTextureUniform = "normalTexture";
 			normalTextureUniform = "normalTexture";
 			specularTextureUniform = "specularTexture";
 			specularTextureUniform = "specularTexture";
 			emissiveTextureUniform = "emissiveTexture";
 			emissiveTextureUniform = "emissiveTexture";
-			blurTextureUniform = "blurTexture";
 			glossTextureUniform = "glossTexture";
 			glossTextureUniform = "glossTexture";
 			heightTextureUniform = "heightTexture";
 			heightTextureUniform = "heightTexture";
 			combinedTextureUniform = "combinedTexture";
 			combinedTextureUniform = "combinedTexture";
@@ -916,6 +930,7 @@ public:
 			depthTypeUniform = "depthType";
 			depthTypeUniform = "depthType";
 
 
 			eyeAdaptionRateUniform = "eyeAdaptionRate";
 			eyeAdaptionRateUniform = "eyeAdaptionRate";
+			eyeAdaptionIntBrightnessUniform = "eyeAdaptionIntBrightness";
 			HDRSSBuffer = "HDRBuffer";
 			HDRSSBuffer = "HDRBuffer";
 
 
 			testMatUniform = "testMat";
 			testMatUniform = "testMat";
@@ -936,6 +951,7 @@ public:
 		std::string gammaUniform;
 		std::string gammaUniform;
 		std::string alphaCullingUniform;
 		std::string alphaCullingUniform;
 		std::string alphaThresholdUniform;
 		std::string alphaThresholdUniform;
+		std::string emissiveMultiplierUniform;
 		std::string emissiveThresholdUniform;
 		std::string emissiveThresholdUniform;
 		std::string heightScaleUniform;
 		std::string heightScaleUniform;
 		std::string textureTilingFactorUniform;
 		std::string textureTilingFactorUniform;
@@ -965,8 +981,10 @@ public:
 		std::string normalMapUniform;
 		std::string normalMapUniform;
 		std::string emissiveMapUniform;
 		std::string emissiveMapUniform;
 		std::string matPropertiesMapUniform;
 		std::string matPropertiesMapUniform;
-		std::string blurMapUniform;
+		std::string intermediateMapUniform;
 		std::string finalMapUniform;
 		std::string finalMapUniform;
+		std::string inputColorMapUniform;
+		std::string outputColorMapUniform;
 
 
 		std::string sunGlowTextureUniform;
 		std::string sunGlowTextureUniform;
 		std::string skyMapTextureUniform;
 		std::string skyMapTextureUniform;
@@ -975,7 +993,6 @@ public:
 		std::string normalTextureUniform;
 		std::string normalTextureUniform;
 		std::string specularTextureUniform;
 		std::string specularTextureUniform;
 		std::string emissiveTextureUniform;
 		std::string emissiveTextureUniform;
-		std::string blurTextureUniform;
 		std::string glossTextureUniform;
 		std::string glossTextureUniform;
 		std::string heightTextureUniform;
 		std::string heightTextureUniform;
 		std::string combinedTextureUniform;
 		std::string combinedTextureUniform;
@@ -989,6 +1006,7 @@ public:
 		std::string depthTypeUniform;
 		std::string depthTypeUniform;
 
 
 		std::string eyeAdaptionRateUniform;
 		std::string eyeAdaptionRateUniform;
+		std::string eyeAdaptionIntBrightnessUniform;
 		std::string HDRSSBuffer;
 		std::string HDRSSBuffer;
 
 
 		std::string testMatUniform;
 		std::string testMatUniform;

+ 8 - 32
Praxis3D/Source/FinalPass.h

@@ -7,8 +7,7 @@ class FinalPass : public RenderPass
 {
 {
 public:
 public:
 	FinalPass(RendererFrontend &p_renderer) : 
 	FinalPass(RendererFrontend &p_renderer) : 
-		RenderPass(p_renderer),
-		m_HDRSSBuffer(BufferType_ShaderStorage, BufferUsageHint_DynamicCopy) { }
+		RenderPass(p_renderer) { }
 
 
 	~FinalPass() { }
 	~FinalPass() { }
 
 
@@ -18,14 +17,6 @@ public:
 
 
 		m_name = "Final Rendering Pass";
 		m_name = "Final Rendering Pass";
 		
 		
-		// SetHDR binding index
-		m_HDRSSBuffer.m_bindingIndex = SSBOBinding_HDR;
-		
-		m_HDRSSBuffer.m_data = &m_HDRDataSet;
-
-		// Set the HDR buffer size
-		m_HDRSSBuffer.m_size = sizeof(HDRDataSet);
-
 		// Create a property-set used to load geometry shader
 		// Create a property-set used to load geometry shader
 		PropertySet finalShaderProperties(Properties::Shaders);
 		PropertySet finalShaderProperties(Properties::Shaders);
 		finalShaderProperties.addProperty(Properties::VertexShader, Config::rendererVar().final_pass_vert_shader);
 		finalShaderProperties.addProperty(Properties::VertexShader, Config::rendererVar().final_pass_vert_shader);
@@ -42,14 +33,11 @@ public:
 			// Queue the shaders to be loaded to GPU
 			// Queue the shaders to be loaded to GPU
 			m_renderer.queueForLoading(*m_shaderFinalPass);
 			m_renderer.queueForLoading(*m_shaderFinalPass);
 		}
 		}
-
-		// Queue HDR buffer to be created
-		m_renderer.queueForLoading(m_HDRSSBuffer);
-
+		
 		return returnError;
 		return returnError;
 	}
 	}
 
 
-	void update(const SceneObjects &p_sceneObjects, const float p_deltaTime)
+	void update(RenderPassData &p_renderPassData, const SceneObjects &p_sceneObjects, const float p_deltaTime)
 	{
 	{
 #ifdef SETTING_USE_BLIT_FRAMEBUFFER
 #ifdef SETTING_USE_BLIT_FRAMEBUFFER
 
 
@@ -68,34 +56,22 @@ public:
 		//m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferFinal, GeometryBuffer::GBufferFinal);
 		//m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferFinal, GeometryBuffer::GBufferFinal);
 
 
 		glDisable(GL_DEPTH_TEST);
 		glDisable(GL_DEPTH_TEST);
-
-		if(Config::graphicsVar().eye_adaption)
-		{
-			// Generate mipmaps for the final buffer, for use in tone mapping
-			m_renderer.m_backend.getGeometryBuffer()->generateMipmap(GeometryBuffer::GBufferFinal);
-		}
-
+		
 		// Bind final texture for reading so it can be accessed in the shaders
 		// Bind final texture for reading so it can be accessed in the shaders
-		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferFinal, GeometryBuffer::GBufferFinal);
-
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferEmissive, GeometryBuffer::GBufferEmissive);
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferEmissive, GeometryBuffer::GBufferEmissive);
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(p_renderPassData.getColorInputMap(), GeometryBuffer::GBufferInputTexture);
+		//m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferNormal, GeometryBuffer::GBufferInputTexture);
 
 
 		// Set the default framebuffer to be drawn to
 		// Set the default framebuffer to be drawn to
 		m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferDefault);
 		m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferDefault);
 
 
-
-#endif // SETTING_USE_BLIT_FRAMEBUFFER
-
 		// Queue and render a full screen quad using a final pass shader
 		// Queue and render a full screen quad using a final pass shader
 		m_renderer.queueForDrawing(m_shaderFinalPass->getShaderHandle(), m_shaderFinalPass->getUniformUpdater(), p_sceneObjects.m_camera->getBaseObjectData().m_modelMat);
 		m_renderer.queueForDrawing(m_shaderFinalPass->getShaderHandle(), m_shaderFinalPass->getUniformUpdater(), p_sceneObjects.m_camera->getBaseObjectData().m_modelMat);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
+
+#endif // SETTING_USE_BLIT_FRAMEBUFFER
 	}
 	}
 
 
 private:
 private:
 	ShaderLoader::ShaderProgram	*m_shaderFinalPass;
 	ShaderLoader::ShaderProgram	*m_shaderFinalPass;
-
-	HDRDataSet m_HDRDataSet;
-
-	// HDR shader storage buffer
-	RendererFrontend::ShaderBuffer m_HDRSSBuffer;
 };
 };

+ 34 - 31
Praxis3D/Source/GeometryBuffer.cpp

@@ -4,7 +4,7 @@
 GeometryBuffer::GeometryBuffer(unsigned int p_bufferWidth, unsigned int p_bufferHeight) : Framebuffer(p_bufferWidth, p_bufferHeight)
 GeometryBuffer::GeometryBuffer(unsigned int p_bufferWidth, unsigned int p_bufferHeight) : Framebuffer(p_bufferWidth, p_bufferHeight)
 {
 {
 
 
-	m_blurBuffer = 0;
+	m_intermediateBuffer = 0;
 	m_depthBuffer = 0;
 	m_depthBuffer = 0;
 	m_finalBuffer = 0;
 	m_finalBuffer = 0;
 	m_finalPassBuffer = GBufferFinal;
 	m_finalPassBuffer = GBufferFinal;
@@ -30,8 +30,8 @@ GeometryBuffer::~GeometryBuffer()
 	if(m_depthBuffer != 0)
 	if(m_depthBuffer != 0)
 		glDeleteTextures(1, &m_depthBuffer);
 		glDeleteTextures(1, &m_depthBuffer);
 
 
-	if(m_blurBuffer != 0)
-		glDeleteTextures(1, &m_blurBuffer);
+	if(m_intermediateBuffer != 0)
+		glDeleteTextures(1, &m_intermediateBuffer);
 
 
 	if(m_finalBuffer != 0)
 	if(m_finalBuffer != 0)
 		glDeleteTextures(1, &m_finalBuffer);
 		glDeleteTextures(1, &m_finalBuffer);
@@ -50,7 +50,7 @@ ErrorCode GeometryBuffer::init()
 		// Create geometry pass buffers
 		// Create geometry pass buffers
 		glGenTextures(GBufferNumTextures, m_GBTextures);
 		glGenTextures(GBufferNumTextures, m_GBTextures);
 		glGenTextures(1, &m_depthBuffer);
 		glGenTextures(1, &m_depthBuffer);
-		glGenTextures(1, &m_blurBuffer);
+		glGenTextures(1, &m_intermediateBuffer);
 		glGenTextures(1, &m_finalBuffer);
 		glGenTextures(1, &m_finalBuffer);
 
 
 		// Set up texture formats
 		// Set up texture formats
@@ -95,15 +95,15 @@ ErrorCode GeometryBuffer::init()
 					 Config::FramebfrVariables().gl_depth_buffer_texture_format, Config::FramebfrVariables().gl_depth_buffer_texture_type, NULL);
 					 Config::FramebfrVariables().gl_depth_buffer_texture_format, Config::FramebfrVariables().gl_depth_buffer_texture_type, NULL);
 		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0);
 		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0);
 
 
-		// Create the blur buffer, that acts as an intermediate buffer between vertical and horizontal blur passes
-		glBindTexture(GL_TEXTURE_2D, m_blurBuffer);
+		// Create the intermediate buffer, that acts as an intermediate buffer between vertical and horizontal blur passes
+		glBindTexture(GL_TEXTURE_2D, m_intermediateBuffer);
 		glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_blur_buffer_internal_format, m_bufferWidth, m_bufferHeight, 0, 
 		glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_blur_buffer_internal_format, m_bufferWidth, m_bufferHeight, 0, 
 					 Config::FramebfrVariables().gl_blur_buffer_texture_format, Config::FramebfrVariables().gl_blur_buffer_texture_type, NULL);
 					 Config::FramebfrVariables().gl_blur_buffer_texture_format, Config::FramebfrVariables().gl_blur_buffer_texture_type, NULL);
-		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Config::FramebfrVariables().gl_blur_buffer_min_filter);
-		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Config::FramebfrVariables().gl_blur_buffer_mag_filter);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, Config::FramebfrVariables().gl_blur_buffer_wrap_s_method);
-		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, Config::FramebfrVariables().gl_blur_buffer_wrap_t_method);
-		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBufferBlur, GL_TEXTURE_2D, m_blurBuffer, 0);
+		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Config::FramebfrVariables().gl_buffers_min_filter);
+		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Config::FramebfrVariables().gl_buffers_mag_filter);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, Config::FramebfrVariables().gl_buffers_wrap_s_method);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, Config::FramebfrVariables().gl_buffers_wrap_t_method);
+		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBufferIntermediate, GL_TEXTURE_2D, m_intermediateBuffer, 0);
 
 
 		// Create the final buffer, that gets renderred to the screen
 		// Create the final buffer, that gets renderred to the screen
 		glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 		glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
@@ -115,6 +115,8 @@ ErrorCode GeometryBuffer::init()
 		else
 		else
 			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Config::FramebfrVariables().gl_final_buffer_min_filter);
 			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Config::FramebfrVariables().gl_final_buffer_min_filter);
 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Config::FramebfrVariables().gl_final_buffer_mag_filter);
 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Config::FramebfrVariables().gl_final_buffer_mag_filter);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, Config::FramebfrVariables().gl_buffers_wrap_s_method);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, Config::FramebfrVariables().gl_buffers_wrap_t_method);
 		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBufferFinal, GL_TEXTURE_2D, m_finalBuffer, 0);
 		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + GBufferFinal, GL_TEXTURE_2D, m_finalBuffer, 0);
 		
 		
 		// Check for errors and return an error in case of one
 		// Check for errors and return an error in case of one
@@ -125,7 +127,7 @@ ErrorCode GeometryBuffer::init()
 		// Restore the default FBO, so it doesn't get changed from the outside of the class
 		// Restore the default FBO, so it doesn't get changed from the outside of the class
 		//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
 		//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
 
 
-		glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
+		//glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
 	}
 	}
 	return returnCode;
 	return returnCode;
 }
 }
@@ -145,14 +147,8 @@ void GeometryBuffer::setBufferSize(unsigned int p_bufferWidth, unsigned int p_bu
 			glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormats[i], m_bufferWidth, m_bufferHeight, 0, m_textureFormats[i], m_textureTypes[i], NULL);
 			glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormats[i], m_bufferWidth, m_bufferHeight, 0, m_textureFormats[i], m_textureTypes[i], NULL);
 		}
 		}
 
 
-		// Create depth buffer
-		glBindTexture(GL_TEXTURE_2D, m_depthBuffer);
-		glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_bufferWidth, m_bufferHeight, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
-		glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_depth_buffer_internal_format, m_bufferWidth, m_bufferHeight, 0,
-			Config::FramebfrVariables().gl_depth_buffer_texture_format, Config::FramebfrVariables().gl_depth_buffer_texture_type, NULL);
-
-		// Create the blur buffer, that acts as an intermediate buffer between vertical and horizontal blur passes
-		glBindTexture(GL_TEXTURE_2D, m_blurBuffer);
+		// Create the intermediate buffer, that acts as an intermediate buffer between vertical and horizontal blur passes
+		glBindTexture(GL_TEXTURE_2D, m_intermediateBuffer);
 		glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_blur_buffer_internal_format, m_bufferWidth, m_bufferHeight, 0,
 		glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_blur_buffer_internal_format, m_bufferWidth, m_bufferHeight, 0,
 			Config::FramebfrVariables().gl_blur_buffer_texture_format, Config::FramebfrVariables().gl_blur_buffer_texture_type, NULL);
 			Config::FramebfrVariables().gl_blur_buffer_texture_format, Config::FramebfrVariables().gl_blur_buffer_texture_type, NULL);
 
 
@@ -160,6 +156,13 @@ void GeometryBuffer::setBufferSize(unsigned int p_bufferWidth, unsigned int p_bu
 		glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 		glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 		glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_final_buffer_internal_format, m_bufferWidth, m_bufferHeight, 0,
 		glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_final_buffer_internal_format, m_bufferWidth, m_bufferHeight, 0,
 			Config::FramebfrVariables().gl_final_buffer_texture_format, Config::FramebfrVariables().gl_final_buffer_texture_type, NULL);
 			Config::FramebfrVariables().gl_final_buffer_texture_format, Config::FramebfrVariables().gl_final_buffer_texture_type, NULL);
+		
+		// Create depth buffer
+		glBindTexture(GL_TEXTURE_2D, m_depthBuffer);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_bufferWidth, m_bufferHeight, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
+		glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_depth_buffer_internal_format, m_bufferWidth, m_bufferHeight, 0,
+			Config::FramebfrVariables().gl_depth_buffer_texture_format, Config::FramebfrVariables().gl_depth_buffer_texture_type, NULL);
+
 	}
 	}
 }
 }
 void GeometryBuffer::setBufferSize(GLuint p_buffer, unsigned int p_bufferWidth, unsigned int p_bufferHeight)
 void GeometryBuffer::setBufferSize(GLuint p_buffer, unsigned int p_bufferWidth, unsigned int p_bufferHeight)
@@ -194,9 +197,9 @@ void GeometryBuffer::setBufferSize(GLuint p_buffer, unsigned int p_bufferWidth,
 			m_bufferHeight = p_bufferHeight;
 			m_bufferHeight = p_bufferHeight;
 
 
 			break;
 			break;
-		case GBufferBlur:
+		case GBufferIntermediate:
 			// Resize the blur buffer
 			// Resize the blur buffer
-			glBindTexture(GL_TEXTURE_2D, m_blurBuffer);
+			glBindTexture(GL_TEXTURE_2D, m_intermediateBuffer);
 			glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_blur_buffer_internal_format, p_bufferWidth, p_bufferHeight, 0, 
 			glTexImage2D(GL_TEXTURE_2D, 0, Config::FramebfrVariables().gl_blur_buffer_internal_format, p_bufferWidth, p_bufferHeight, 0, 
 						 Config::FramebfrVariables().gl_blur_buffer_texture_format, Config::FramebfrVariables().gl_blur_buffer_texture_type, NULL);
 						 Config::FramebfrVariables().gl_blur_buffer_texture_format, Config::FramebfrVariables().gl_blur_buffer_texture_type, NULL);
 			
 			
@@ -210,14 +213,14 @@ void GeometryBuffer::setBufferSize(GLuint p_buffer, unsigned int p_bufferWidth,
 void GeometryBuffer::initFrame()
 void GeometryBuffer::initFrame()
 {
 {
 	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
 	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
-	glDrawBuffer(GL_COLOR_ATTACHMENT0 + GBufferBlur);	// Bind blur buffer
-	glClear(GL_COLOR_BUFFER_BIT);						// and clear it
-	glDrawBuffer(GL_COLOR_ATTACHMENT0 + GBufferFinal);	// Bind final buffer
-	glClear(GL_COLOR_BUFFER_BIT);						// and clear it
+	glDrawBuffer(GL_COLOR_ATTACHMENT0 + GBufferIntermediate);	// Bind intermediate buffer
+	glClear(GL_COLOR_BUFFER_BIT);								// and clear it
+	glDrawBuffer(GL_COLOR_ATTACHMENT0 + GBufferFinal);			// Bind final buffer
+	glClear(GL_COLOR_BUFFER_BIT);								// and clear it
 }
 }
 void GeometryBuffer::initGeometryPass()
 void GeometryBuffer::initGeometryPass()
 {
 {
-	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
+	//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
 	glDrawBuffers(GBufferNumTextures, m_texBuffers);		// Bind geometry pass buffers to write to
 	glDrawBuffers(GBufferNumTextures, m_texBuffers);		// Bind geometry pass buffers to write to
 	glClear(GL_COLOR_BUFFER_BIT);
 	glClear(GL_COLOR_BUFFER_BIT);
 }
 }
@@ -271,8 +274,8 @@ void GeometryBuffer::bindForReading(GBufferTextureType p_buffer, int p_activeTex
 	case GeometryBuffer::GBufferFinal:
 	case GeometryBuffer::GBufferFinal:
 		glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 		glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 		break;
 		break;
-	case GeometryBuffer::GBufferBlur:
-		glBindTexture(GL_TEXTURE_2D, m_blurBuffer);
+	case GeometryBuffer::GBufferIntermediate:
+		glBindTexture(GL_TEXTURE_2D, m_intermediateBuffer);
 		break;
 		break;
 	}
 	}
 }
 }
@@ -290,8 +293,8 @@ void GeometryBuffer::bindForReading(GBufferTextureType p_buffer)
 	case GeometryBuffer::GBufferFinal:
 	case GeometryBuffer::GBufferFinal:
 		glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 		glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 		break;
 		break;
-	case GeometryBuffer::GBufferBlur:
-		glBindTexture(GL_TEXTURE_2D, m_blurBuffer);
+	case GeometryBuffer::GBufferIntermediate:
+		glBindTexture(GL_TEXTURE_2D, m_intermediateBuffer);
 		break;
 		break;
 	}
 	}
 }
 }

+ 9 - 7
Praxis3D/Source/GeometryBuffer.h

@@ -21,8 +21,10 @@ public:
 		GBufferMatProperties,
 		GBufferMatProperties,
 		GBufferNumTextures,
 		GBufferNumTextures,
 		GBufferFinal = GBufferNumTextures,
 		GBufferFinal = GBufferNumTextures,
-		GBufferBlur,
-		GBufferTotalNumTextures
+		GBufferIntermediate,
+		GBufferTotalNumTextures,
+		GBufferInputTexture = GBufferTotalNumTextures,
+		GbufferOutputTexture
 	};
 	};
 
 
 	typedef unsigned int GBufferTexture;
 	typedef unsigned int GBufferTexture;
@@ -60,8 +62,8 @@ public:
 		case GeometryBuffer::GBufferFinal:
 		case GeometryBuffer::GBufferFinal:
 			glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 			glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 			break;
 			break;
-		case GeometryBuffer::GBufferBlur:
-			glBindTexture(GL_TEXTURE_2D, m_blurBuffer);
+		case GeometryBuffer::GBufferIntermediate:
+			glBindTexture(GL_TEXTURE_2D, m_intermediateBuffer);
 			break;
 			break;
 		}
 		}
 	}
 	}
@@ -82,8 +84,8 @@ public:
 		case GeometryBuffer::GBufferFinal:
 		case GeometryBuffer::GBufferFinal:
 			glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 			glBindTexture(GL_TEXTURE_2D, m_finalBuffer);
 			break;
 			break;
-		case GeometryBuffer::GBufferBlur:
-			glBindTexture(GL_TEXTURE_2D, m_blurBuffer);
+		case GeometryBuffer::GBufferIntermediate:
+			glBindTexture(GL_TEXTURE_2D, m_intermediateBuffer);
 			break;
 			break;
 		}
 		}
 	}
 	}
@@ -144,7 +146,7 @@ public:
 protected:
 protected:
 
 
 	GLuint  m_GBTextures[GBufferNumTextures],	// Geometry pass textures
 	GLuint  m_GBTextures[GBufferNumTextures],	// Geometry pass textures
-			m_blurBuffer,						// Intermediate buffer between vertical and horizontal blur passes
+			m_intermediateBuffer,				// Intermediate buffer between vertical and horizontal blur passes
 			m_finalBuffer,						// Final buffer that gets copied to the screen
 			m_finalBuffer,						// Final buffer that gets copied to the screen
 			m_depthBuffer,
 			m_depthBuffer,
 			m_internalFormats[GBufferNumTextures];
 			m_internalFormats[GBufferNumTextures];

+ 5 - 1
Praxis3D/Source/GeometryPass.h

@@ -35,8 +35,12 @@ public:
 		return returnError;
 		return returnError;
 	}
 	}
 
 
-	void update(const SceneObjects &p_sceneObjects, const float p_deltaTime)
+	void update(RenderPassData &p_renderPassData, const SceneObjects &p_sceneObjects, const float p_deltaTime)
 	{
 	{
+		// Set input and output color maps for this frame
+		p_renderPassData.setColorInputMap(GeometryBuffer::GBufferIntermediate);
+		p_renderPassData.setColorOutputMap(GeometryBuffer::GBufferFinal);
+
 		// Bind the geometry framebuffer to be used
 		// Bind the geometry framebuffer to be used
 		m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferGeometry);
 		m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferGeometry);
 
 

+ 110 - 0
Praxis3D/Source/HdrMappingPass.h

@@ -0,0 +1,110 @@
+#pragma once
+
+#include "GraphicsDataSets.h"
+#include "RenderPassBase.h"
+
+class HdrMappingPass : public RenderPass
+{
+public:
+	HdrMappingPass(RendererFrontend &p_renderer) :
+		RenderPass(p_renderer),
+		m_HDRSSBuffer(BufferType_ShaderStorage, BufferUsageHint_DynamicCopy) { }
+
+	~HdrMappingPass() { }
+
+	ErrorCode init()
+	{
+		ErrorCode returnError = ErrorCode::Success;
+		ErrorCode shaderError;
+
+		m_name = "HDR Mapping Pass";
+
+		// Set HDR buffer binding index
+		m_HDRSSBuffer.m_bindingIndex = SSBOBinding_HDR;
+
+		// Assign HDR buffer data
+		m_HDRSSBuffer.m_data = &m_HDRDataSet;
+
+		// Set the HDR buffer size
+		m_HDRSSBuffer.m_size = sizeof(HDRDataSet);
+
+		// Set buffer values
+		m_emissiveAndOutputBuffers.resize(2);
+		m_emissiveAndOutputBuffers[0] = m_renderer.m_backend.getGeometryBuffer()->getBufferLocation(GeometryBuffer::GBufferDiffuse);
+		m_emissiveAndOutputBuffers[1] = m_renderer.m_backend.getGeometryBuffer()->getBufferLocation(GeometryBuffer::GBufferFinal);
+
+		// Create a property-set used to load blur vertical shaders
+		PropertySet hdrMappingShaderProperties(Properties::Shaders);
+		hdrMappingShaderProperties.addProperty(Properties::VertexShader, Config::rendererVar().hdr_mapping_pass_vert_shader);
+		hdrMappingShaderProperties.addProperty(Properties::FragmentShader, Config::rendererVar().hdr_mapping_pass_frag_shader);
+
+		// Create shaders
+		m_hdrMappingShader = Loaders::shader().load(hdrMappingShaderProperties);
+
+		//		 _______________________________
+		//		| LOAD HDR MAPPING PASS SHADER	|
+		//		|_______________________________|
+		shaderError = m_hdrMappingShader->loadToMemory();		// Load shader to memory
+		if(shaderError == ErrorCode::Success)					// Check if shader was loaded successfully
+			m_renderer.queueForLoading(*m_hdrMappingShader);	// Queue the shader to be loaded to GPU
+		else
+			returnError = shaderError;
+
+		// Queue HDR buffer to be created
+		m_renderer.queueForLoading(m_HDRSSBuffer);
+
+		return returnError;
+	}
+
+	void update(RenderPassData &p_renderPassData, const SceneObjects &p_sceneObjects, const float p_deltaTime)
+	{
+		glDisable(GL_DEPTH_TEST);
+
+		if(Config::graphicsVar().eye_adaption)
+		{
+			// Generate mipmaps for the final buffer, for use in tone mapping
+			m_renderer.m_backend.getGeometryBuffer()->generateMipmap(GeometryBuffer::GBufferFinal);
+		}
+
+		p_renderPassData.setEmissiveInputMap(GeometryBuffer::GBufferDiffuse);
+
+		m_emissiveAndOutputBuffers[0] = m_renderer.m_backend.getGeometryBuffer()->getBufferLocation(p_renderPassData.getEmissiveInputMap());
+		m_emissiveAndOutputBuffers[1] = m_renderer.m_backend.getGeometryBuffer()->getBufferLocation(p_renderPassData.getColorOutputMap());
+
+		m_renderer.m_backend.getGeometryBuffer()->generateMipmap(GeometryBuffer::GBufferFinal);
+
+		// Set the default framebuffer to be drawn to
+		//m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferDefault);
+		
+		// Bind final texture for reading so it can be accessed in the shaders
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferFinal, GeometryBuffer::GBufferFinal);
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferEmissive, GeometryBuffer::GBufferEmissive);
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(p_renderPassData.getColorInputMap(), GeometryBuffer::GBufferInputTexture);
+
+		// Bind intermediate texture for writing to, so HDR mapping is outputed to it
+		//m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(GeometryBuffer::GBufferEmissive);
+		//m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(GeometryBuffer::GBufferIntermediate);
+
+		// Bind textures for writing
+		m_renderer.m_backend.getGeometryBuffer()->bindBuffersForWriting(m_emissiveAndOutputBuffers);
+
+		// Perform HDR mapping. Queue and render a full screen quad using an HDR pass shader
+		m_renderer.queueForDrawing(m_hdrMappingShader->getShaderHandle(), m_hdrMappingShader->getUniformUpdater(), p_sceneObjects.m_camera->getBaseObjectData().m_modelMat);
+		m_renderer.passScreenSpaceDrawCommandsToBackend();
+		
+		p_renderPassData.swapColorInputOutputMaps();
+	}
+
+private:
+	// Buffer handles used for binding
+	std::vector<GeometryBuffer::GBufferTexture> m_emissiveAndOutputBuffers;
+
+	// HDR shader
+	ShaderLoader::ShaderProgram	*m_hdrMappingShader;
+
+	// HDR shader storage buffer
+	RendererFrontend::ShaderBuffer m_HDRSSBuffer;
+
+	// HDR shader storage buffer data set
+	HDRDataSet m_HDRDataSet;
+};

+ 13 - 7
Praxis3D/Source/LightingPass.h

@@ -27,9 +27,9 @@ public:
 		m_spotLightBuffer.m_size = sizeof(SpotLightDataSet) * Config::graphicsVar().max_num_spot_lights;
 		m_spotLightBuffer.m_size = sizeof(SpotLightDataSet) * Config::graphicsVar().max_num_spot_lights;
 		
 		
 		// Set buffer values
 		// Set buffer values
-		m_emissiveAndFinalBuffers.resize(2);
-		m_emissiveAndFinalBuffers[0] = m_renderer.m_backend.getGeometryBuffer()->getBufferLocation(GeometryBuffer::GBufferEmissive);
-		m_emissiveAndFinalBuffers[1] = m_renderer.m_backend.getGeometryBuffer()->getBufferLocation(GeometryBuffer::GBufferFinal);
+		m_emissiveAndOutputBuffers.resize(2);
+		m_emissiveAndOutputBuffers[0] = m_renderer.m_backend.getGeometryBuffer()->getBufferLocation(GeometryBuffer::GBufferEmissive);
+		m_emissiveAndOutputBuffers[1] = m_renderer.m_backend.getGeometryBuffer()->getBufferLocation(GeometryBuffer::GBufferFinal);
 
 
 		// Create a property-set used to load lighting shader
 		// Create a property-set used to load lighting shader
 		PropertySet lightShaderProperties(Properties::Shaders);
 		PropertySet lightShaderProperties(Properties::Shaders);
@@ -55,8 +55,12 @@ public:
 		return returnError;
 		return returnError;
 	}
 	}
 
 
-	void update(const SceneObjects &p_sceneObjects, const float p_deltaTime)
+	void update(RenderPassData &p_renderPassData, const SceneObjects &p_sceneObjects, const float p_deltaTime)
 	{
 	{
+		glDisable(GL_DEPTH_TEST);
+		//glEnable(GL_DEPTH_TEST);
+		//glDepthFunc(GL_NOTEQUAL);
+
 		// Setup point light buffer values
 		// Setup point light buffer values
 		m_pointLightBuffer.m_size = sizeof(PointLightDataSet) * p_sceneObjects.m_pointLights.size();
 		m_pointLightBuffer.m_size = sizeof(PointLightDataSet) * p_sceneObjects.m_pointLights.size();
 		m_pointLightBuffer.m_data = (void*)p_sceneObjects.m_pointLights.data();
 		m_pointLightBuffer.m_data = (void*)p_sceneObjects.m_pointLights.data();
@@ -72,8 +76,8 @@ public:
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferEmissive, GeometryBuffer::GBufferEmissive);
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferEmissive, GeometryBuffer::GBufferEmissive);
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferMatProperties, GeometryBuffer::GBufferMatProperties);
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferMatProperties, GeometryBuffer::GBufferMatProperties);
 
 
-		// Bind textures for writing
-		m_renderer.m_backend.getGeometryBuffer()->bindBuffersForWriting(m_emissiveAndFinalBuffers);
+		// Bind texture for writing
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getColorOutputMap());
 
 
 		// Queue light buffer updates (so that new values that were just setup are sent to the GPU)
 		// Queue light buffer updates (so that new values that were just setup are sent to the GPU)
 		m_renderer.queueForUpdate(m_pointLightBuffer);
 		m_renderer.queueForUpdate(m_pointLightBuffer);
@@ -87,13 +91,15 @@ public:
 
 
 		// Pass the draw command so it is executed
 		// Pass the draw command so it is executed
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
+
+		p_renderPassData.swapColorInputOutputMaps();
 	}
 	}
 
 
 private:
 private:
 	ShaderLoader::ShaderProgram	*m_shaderLightPass;
 	ShaderLoader::ShaderProgram	*m_shaderLightPass;
 
 
 	// Buffer handles used for binding
 	// Buffer handles used for binding
-	std::vector<GeometryBuffer::GBufferTexture> m_emissiveAndFinalBuffers;
+	std::vector<GeometryBuffer::GBufferTexture> m_emissiveAndOutputBuffers;
 
 
 	// Light buffers
 	// Light buffers
 	RendererFrontend::ShaderBuffer	m_pointLightBuffer, 
 	RendererFrontend::ShaderBuffer	m_pointLightBuffer, 

+ 60 - 0
Praxis3D/Source/PostProcessPass.h

@@ -0,0 +1,60 @@
+#pragma once
+
+#include "GraphicsDataSets.h"
+#include "RenderPassBase.h"
+
+class PostProcessPass : public RenderPass
+{
+public:
+	PostProcessPass(RendererFrontend &p_renderer) :
+		RenderPass(p_renderer) { }
+
+	~PostProcessPass() { }
+
+	ErrorCode init()
+	{
+		ErrorCode returnError = ErrorCode::Success;
+		ErrorCode shaderError;
+
+		m_name = "Post Process Rendering Pass";
+
+		// Create a property-set used to load blur vertical shaders
+		PropertySet postProcessShaderProperties(Properties::Shaders);
+		postProcessShaderProperties.addProperty(Properties::VertexShader, Config::rendererVar().postProcess_pass_vert_shader);
+		postProcessShaderProperties.addProperty(Properties::FragmentShader, Config::rendererVar().postProcess_pass_frag_shader);
+
+		// Create shaders
+		m_postProcessShader = Loaders::shader().load(postProcessShaderProperties);
+
+		//		 _______________________________
+		//		|	LOAD POST PROCESS SHADER	|
+		//		|_______________________________|
+		shaderError = m_postProcessShader->loadToMemory();		// Load shader to memory
+		if(shaderError == ErrorCode::Success)					// Check if shader was loaded successfully
+			m_renderer.queueForLoading(*m_postProcessShader);	// Queue the shader to be loaded to GPU
+		else
+			returnError = shaderError;
+
+		return returnError;
+	}
+
+	void update(RenderPassData &p_renderPassData, const SceneObjects &p_sceneObjects, const float p_deltaTime)
+	{
+		glDisable(GL_DEPTH_TEST);
+
+		// Bind input color texture for reading so it can be accessed in the shaders
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(p_renderPassData.getColorInputMap(), GeometryBuffer::GBufferInputTexture);
+
+		// Bind output color texture for writing to, so it can be used as an intermediate buffer between blur passes
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getColorOutputMap());
+
+		// Perform various visual effects in the post process shader
+		m_renderer.queueForDrawing(m_postProcessShader->getShaderHandle(), m_postProcessShader->getUniformUpdater(), p_sceneObjects.m_camera->getBaseObjectData().m_modelMat);
+		m_renderer.passScreenSpaceDrawCommandsToBackend();
+
+		p_renderPassData.swapColorInputOutputMaps();
+	}
+
+private:
+	ShaderLoader::ShaderProgram	*m_postProcessShader;
+};

+ 34 - 1
Praxis3D/Source/RenderPassBase.h

@@ -4,6 +4,39 @@
 #include "Config.h"
 #include "Config.h"
 #include "RendererFrontend.h"
 #include "RendererFrontend.h"
 
 
+// Used to share data between rendering passes
+struct RenderPassData
+{
+	RenderPassData()
+	{
+		m_colorInputMap = GeometryBuffer::GBufferDiffuse;
+		m_colorOutputMap = GeometryBuffer::GBufferFinal;
+		m_emissiveInputMap = GeometryBuffer::GBufferEmissive;
+	}
+
+	inline void swapColorInputOutputMaps()
+	{
+		auto inputColorMap = getColorInputMap();
+		setColorInputMap(getColorOutputMap());
+		setColorOutputMap(inputColorMap);
+	}
+
+	// Setters
+	inline void setColorInputMap(GeometryBuffer::GBufferTextureType p_inputColorMap)		{ m_colorInputMap = p_inputColorMap;		}
+	inline void setColorOutputMap(GeometryBuffer::GBufferTextureType p_outputColorMap)		{ m_colorOutputMap = p_outputColorMap;		}
+	inline void setEmissiveInputMap(GeometryBuffer::GBufferTextureType p_emissiveInputMap)	{ m_emissiveInputMap = p_emissiveInputMap;	}
+
+	// Getters
+	const inline GeometryBuffer::GBufferTextureType getColorInputMap() const	{ return m_colorInputMap;		}
+	const inline GeometryBuffer::GBufferTextureType getColorOutputMap() const	{ return m_colorOutputMap;		}
+	const inline GeometryBuffer::GBufferTextureType getEmissiveInputMap() const { return m_emissiveInputMap;	}
+
+	// Remember which color maps to write to and read from, in different rendering passes.
+	GeometryBuffer::GBufferTextureType	m_colorInputMap,
+										m_colorOutputMap,
+										m_emissiveInputMap;
+};
+
 class RenderPass
 class RenderPass
 {
 {
 public:
 public:
@@ -12,7 +45,7 @@ public:
 
 
 	virtual ErrorCode init() = 0;
 	virtual ErrorCode init() = 0;
 
 
-	virtual void update(const SceneObjects &p_sceneObjects, const float p_deltaTime) = 0;
+	virtual void update(RenderPassData &p_renderPassData, const SceneObjects &p_sceneObjects, const float p_deltaTime) = 0;
 
 
 	inline CommandBuffer::Commands &getCommands() { return m_commandBuffer.getCommands(); }
 	inline CommandBuffer::Commands &getCommands() { return m_commandBuffer.getCommands(); }
 
 

+ 1 - 1
Praxis3D/Source/Renderer.h

@@ -95,7 +95,7 @@ public:
 	const virtual Math::Vec3f getFogColor()				const { return m_emptyVec; }
 	const virtual Math::Vec3f getFogColor()				const { return m_emptyVec; }
 	const virtual float getFogDensity()					const { return 0.0f; }
 	const virtual float getFogDensity()					const { return 0.0f; }
 
 
-	const unsigned int getBlurMapPosition()				const { return GeometryBuffer::GBufferTextureType::GBufferBlur;			 }
+	const unsigned int getBlurMapPosition()				const { return GeometryBuffer::GBufferTextureType::GBufferIntermediate;			 }
 	const unsigned int getDiffuseMapPosition()			const { return GeometryBuffer::GBufferTextureType::GBufferDiffuse;		 }
 	const unsigned int getDiffuseMapPosition()			const { return GeometryBuffer::GBufferTextureType::GBufferDiffuse;		 }
 	const unsigned int getEmissiveMapPosition()			const { return GeometryBuffer::GBufferTextureType::GBufferEmissive;		 }
 	const unsigned int getEmissiveMapPosition()			const { return GeometryBuffer::GBufferTextureType::GBufferEmissive;		 }
 	const unsigned int getMatPropertiesMapPosition()	const { return GeometryBuffer::GBufferTextureType::GBufferMatProperties; }
 	const unsigned int getMatPropertiesMapPosition()	const { return GeometryBuffer::GBufferTextureType::GBufferMatProperties; }

+ 17 - 2
Praxis3D/Source/RendererFrontend.cpp

@@ -3,6 +3,8 @@
 #include "GeometryPass.h"
 #include "GeometryPass.h"
 #include "LightingPass.h"
 #include "LightingPass.h"
 #include "FinalPass.h"
 #include "FinalPass.h"
+#include "HdrMappingPass.h"
+#include "PostProcessPass.h"
 #include "ReflectionPass.h"
 #include "ReflectionPass.h"
 #include "RendererFrontend.h"
 #include "RendererFrontend.h"
 
 
@@ -33,6 +35,9 @@ ErrorCode RendererFrontend::init()
 	if(!ErrHandlerLoc::get().ifSuccessful(m_backend.init(m_frameData), returnCode))
 	if(!ErrHandlerLoc::get().ifSuccessful(m_backend.init(m_frameData), returnCode))
 		return returnCode;
 		return returnCode;
 
 
+	// Create the render pass data struct
+	m_renderPassData = new RenderPassData();
+
 	// Add geometry rendering pass, if it was initialized successfuly
 	// Add geometry rendering pass, if it was initialized successfuly
 	GeometryPass *geometryPass = new GeometryPass(*this);
 	GeometryPass *geometryPass = new GeometryPass(*this);
 	if(geometryPass->init() == ErrorCode::Success)
 	if(geometryPass->init() == ErrorCode::Success)
@@ -43,11 +48,21 @@ ErrorCode RendererFrontend::init()
 	if(lightingPass->init() == ErrorCode::Success)
 	if(lightingPass->init() == ErrorCode::Success)
 		m_renderingPasses.push_back(lightingPass);
 		m_renderingPasses.push_back(lightingPass);
 
 
+	// Add HDR mapping rendering pass, if it was initialized successfully
+	HdrMappingPass *hdrPass = new HdrMappingPass(*this);
+	if(hdrPass->init() == ErrorCode::Success)
+		m_renderingPasses.push_back(hdrPass);
+
 	// Add blur rendering pass, if it was initialized successfully
 	// Add blur rendering pass, if it was initialized successfully
 	BlurPass *blurPass = new BlurPass(*this);
 	BlurPass *blurPass = new BlurPass(*this);
 	if(blurPass->init() == ErrorCode::Success)
 	if(blurPass->init() == ErrorCode::Success)
 		m_renderingPasses.push_back(blurPass);
 		m_renderingPasses.push_back(blurPass);
 
 
+	// Add post process rendering pass, if it was initialized successfully
+	PostProcessPass *postProcessPass = new PostProcessPass(*this);
+	if(postProcessPass->init() == ErrorCode::Success)
+		m_renderingPasses.push_back(postProcessPass);
+
 	// Add final rendering pass, if it was initialized successfuly
 	// Add final rendering pass, if it was initialized successfuly
 	FinalPass *finalPass = new FinalPass(*this);
 	FinalPass *finalPass = new FinalPass(*this);
 	if(finalPass->init() == ErrorCode::Success)
 	if(finalPass->init() == ErrorCode::Success)
@@ -110,7 +125,7 @@ void RendererFrontend::renderFrame(const SceneObjects &p_sceneObjects, const flo
 	
 	
 	// Prepare the geometry buffer for a new frame and a geometry pass
 	// Prepare the geometry buffer for a new frame and a geometry pass
 	m_backend.getGeometryBuffer()->initFrame();
 	m_backend.getGeometryBuffer()->initFrame();
-	m_backend.getGeometryBuffer()->initGeometryPass();
+	//m_backend.getGeometryBuffer()->initGeometryPass();
 
 
 	glEnable(GL_DEPTH_TEST);		// Enable depth testing, as this is much like a regular forward render pass
 	glEnable(GL_DEPTH_TEST);		// Enable depth testing, as this is much like a regular forward render pass
 	glClear(GL_DEPTH_BUFFER_BIT);	// Make sure to clear the depth buffer for the new frame
 	glClear(GL_DEPTH_BUFFER_BIT);	// Make sure to clear the depth buffer for the new frame
@@ -120,7 +135,7 @@ void RendererFrontend::renderFrame(const SceneObjects &p_sceneObjects, const flo
 
 
 	for(decltype(m_renderingPasses.size()) i = 0, size = m_renderingPasses.size(); i < size; i++)
 	for(decltype(m_renderingPasses.size()) i = 0, size = m_renderingPasses.size(); i < size; i++)
 	{
 	{
-		m_renderingPasses[i]->update(p_sceneObjects, p_deltaTime);
+		m_renderingPasses[i]->update(*m_renderPassData, p_sceneObjects, p_deltaTime);
 	}
 	}
 }
 }
 
 

+ 11 - 1
Praxis3D/Source/RendererFrontend.h

@@ -5,14 +5,18 @@
 #include "RendererScene.h"
 #include "RendererScene.h"
 
 
 class RenderPass;
 class RenderPass;
+struct RenderPassData;
 
 
 class RendererFrontend
 class RendererFrontend
 {
 {
 	friend class BlurPass;
 	friend class BlurPass;
 	friend class GeometryPass;
 	friend class GeometryPass;
+	friend class HdrMappingPass;
 	friend class LightingPass;
 	friend class LightingPass;
+	friend class PostProcessPass;
 	friend class FinalPass;
 	friend class FinalPass;
 	friend class ReflectionPass;
 	friend class ReflectionPass;
+	friend class SkyPass;
 public:
 public:
 	// A handle for a uniform or shader storage buffer
 	// A handle for a uniform or shader storage buffer
 	struct ShaderBuffer
 	struct ShaderBuffer
@@ -43,7 +47,7 @@ public:
 
 
 	// Renders a complete frame
 	// Renders a complete frame
 	void renderFrame(const SceneObjects &p_sceneObjects, const float p_deltaTime);
 	void renderFrame(const SceneObjects &p_sceneObjects, const float p_deltaTime);
-
+	
 protected:
 protected:
 	inline void queueForDrawing(const RenderableObjectData &p_object, const unsigned int p_shaderHandle, const ShaderUniformUpdater &p_uniformUpdater, const Math::Mat4f &p_viewProjMatrix)
 	inline void queueForDrawing(const RenderableObjectData &p_object, const unsigned int p_shaderHandle, const ShaderUniformUpdater &p_uniformUpdater, const Math::Mat4f &p_viewProjMatrix)
 	{
 	{
@@ -231,6 +235,7 @@ protected:
 	// Renderer backend, serves as an interface layer to GPU
 	// Renderer backend, serves as an interface layer to GPU
 	RendererBackend m_backend;
 	RendererBackend m_backend;
 	
 	
+	// Holds information about the current frame, that is used in the shaders
 	UniformFrameData m_frameData;
 	UniformFrameData m_frameData;
 	
 	
 	// Renderer commands
 	// Renderer commands
@@ -239,7 +244,12 @@ protected:
 	RendererBackend::BufferUpdateCommands m_bufferUpdateCommands;
 	RendererBackend::BufferUpdateCommands m_bufferUpdateCommands;
 	RendererBackend::ScreenSpaceDrawCommands m_screenSpaceDrawCommands;
 	RendererBackend::ScreenSpaceDrawCommands m_screenSpaceDrawCommands;
 
 
+	// An array of all active rendering passes
 	std::vector<RenderPass*> m_renderingPasses;
 	std::vector<RenderPass*> m_renderingPasses;
 
 
+	// Holds info used between rendering passses
+	RenderPassData *m_renderPassData;
+
+	// View - projection matrix
 	Math::Mat4f m_viewProjMatrix;
 	Math::Mat4f m_viewProjMatrix;
 };
 };

+ 5 - 2
Praxis3D/Source/ShaderUniformUpdater.cpp

@@ -48,9 +48,10 @@ ErrorCode ShaderUniformUpdater::generateTextureUpdateList()
 	uniformList.push_back(new NormalMapUniform(m_shaderHandle));
 	uniformList.push_back(new NormalMapUniform(m_shaderHandle));
 	uniformList.push_back(new EmissiveMapUniform(m_shaderHandle));
 	uniformList.push_back(new EmissiveMapUniform(m_shaderHandle));
 	uniformList.push_back(new MatPropertiesMapUniform(m_shaderHandle));
 	uniformList.push_back(new MatPropertiesMapUniform(m_shaderHandle));
-	uniformList.push_back(new BlurMapUniform(m_shaderHandle));
+	uniformList.push_back(new IntermediateMapUniform(m_shaderHandle));
 	uniformList.push_back(new FinalMapUniform(m_shaderHandle));
 	uniformList.push_back(new FinalMapUniform(m_shaderHandle));
-	uniformList.push_back(new BlurTextureUniform(m_shaderHandle));
+	uniformList.push_back(new InputMapUniform(m_shaderHandle));
+	uniformList.push_back(new OutputMapUniform(m_shaderHandle));
 
 
 	// Cubemap texture uniforms
 	// Cubemap texture uniforms
 	uniformList.push_back(new DynamicEnvironmentMapUniform(m_shaderHandle));
 	uniformList.push_back(new DynamicEnvironmentMapUniform(m_shaderHandle));
@@ -119,6 +120,8 @@ ErrorCode ShaderUniformUpdater::generatePerFrameList()
 	uniformList.push_back(new ElapsedTimeUniform(m_shaderHandle));
 	uniformList.push_back(new ElapsedTimeUniform(m_shaderHandle));
 	uniformList.push_back(new GammaUniform(m_shaderHandle));
 	uniformList.push_back(new GammaUniform(m_shaderHandle));
 	uniformList.push_back(new EyeAdaptionRateUniform(m_shaderHandle));
 	uniformList.push_back(new EyeAdaptionRateUniform(m_shaderHandle));
+	uniformList.push_back(new EyeAdaptionIntendedBrightnessUniform(m_shaderHandle));
+	uniformList.push_back(new EmissiveMultiplierUniform(m_shaderHandle));
 	uniformList.push_back(new LODParallaxMappingUniform(m_shaderHandle));
 	uniformList.push_back(new LODParallaxMappingUniform(m_shaderHandle));
 
 
 	// Go through each uniform and check if it is valid
 	// Go through each uniform and check if it is valid

+ 62 - 15
Praxis3D/Source/ShaderUniforms.h

@@ -275,6 +275,25 @@ public:
 private:
 private:
 	float m_currentAlphaThreshold;
 	float m_currentAlphaThreshold;
 };
 };
+class EmissiveMultiplierUniform : public BaseUniform
+{
+public:
+	EmissiveMultiplierUniform(unsigned int p_shaderHandle) : BaseUniform(Config::shaderVar().emissiveMultiplierUniform, p_shaderHandle), m_currentEmissiveMultiplier(-1.0) { }
+
+	void update(const UniformData &p_uniformData)
+	{
+		// Check if the same value is not already assigned (a small optimization)
+		if(m_currentEmissiveMultiplier != Config::graphicsVar().emissive_multiplier)
+		{
+			m_currentEmissiveMultiplier = Config::graphicsVar().emissive_multiplier;
+
+			glUniform1f(m_uniformHandle, m_currentEmissiveMultiplier);
+		}
+	}
+
+private:
+	float m_currentEmissiveMultiplier;
+};
 class EmissiveThresholdUniform : public BaseUniform
 class EmissiveThresholdUniform : public BaseUniform
 {
 {
 public:
 public:
@@ -351,6 +370,25 @@ public:
 private:
 private:
 	float eyeAdaptionRateUniform;
 	float eyeAdaptionRateUniform;
 };
 };
+class EyeAdaptionIntendedBrightnessUniform : public BaseUniform
+{
+public:
+	EyeAdaptionIntendedBrightnessUniform(unsigned int p_shaderHandle) : BaseUniform(Config::shaderVar().eyeAdaptionIntBrightnessUniform, p_shaderHandle), eyeAdaptionIntendedBrightnessUniform(-1.0f) { }
+
+	void update(const UniformData &p_uniformData)
+	{
+		// Check if the same value is not already assigned (a small optimization)
+		if(eyeAdaptionIntendedBrightnessUniform != Config::graphicsVar().eye_adaption_intended_brightness)
+		{
+			eyeAdaptionIntendedBrightnessUniform = Config::graphicsVar().eye_adaption_intended_brightness;
+
+			glUniform1f(m_uniformHandle, eyeAdaptionIntendedBrightnessUniform);
+		}
+	}
+
+private:
+	float eyeAdaptionIntendedBrightnessUniform;
+};
 class LODParallaxMappingUniform : public BaseUniform
 class LODParallaxMappingUniform : public BaseUniform
 {
 {
 public:
 public:
@@ -371,7 +409,6 @@ private:
 	float parallaxLOD;
 	float parallaxLOD;
 };
 };
 
 
-
 class DirLightColorUniform : public BaseUniform
 class DirLightColorUniform : public BaseUniform
 {
 {
 public:
 public:
@@ -584,14 +621,14 @@ public:
 		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GBufferMatProperties);
 		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GBufferMatProperties);
 	}
 	}
 };
 };
-class BlurMapUniform : public BaseUniform
+class IntermediateMapUniform : public BaseUniform
 {
 {
 public:
 public:
-	BlurMapUniform(unsigned int p_shaderHandle) : BaseUniform(Config::shaderVar().blurMapUniform, p_shaderHandle) { }
+	IntermediateMapUniform(unsigned int p_shaderHandle) : BaseUniform(Config::shaderVar().intermediateMapUniform, p_shaderHandle) { }
 
 
 	void update(const UniformData &p_uniformData)
 	void update(const UniformData &p_uniformData)
 	{
 	{
-		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GBufferBlur);
+		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GBufferIntermediate);
 	}
 	}
 };
 };
 class FinalMapUniform : public BaseUniform
 class FinalMapUniform : public BaseUniform
@@ -604,6 +641,26 @@ public:
 		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GBufferFinal);
 		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GBufferFinal);
 	}
 	}
 };
 };
+class InputMapUniform : public BaseUniform
+{
+public:
+	InputMapUniform(unsigned int p_shaderHandle) : BaseUniform(Config::shaderVar().inputColorMapUniform, p_shaderHandle) { }
+
+	void update(const UniformData &p_uniformData)
+	{
+		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GBufferInputTexture);
+	}
+};
+class OutputMapUniform : public BaseUniform
+{
+public:
+	OutputMapUniform(unsigned int p_shaderHandle) : BaseUniform(Config::shaderVar().outputColorMapUniform, p_shaderHandle) { }
+
+	void update(const UniformData &p_uniformData)
+	{
+		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GbufferOutputTexture);
+	}
+};
 
 
 /* Unused */ class SunGlowTextureUniform : public BaseUniform
 /* Unused */ class SunGlowTextureUniform : public BaseUniform
 {
 {
@@ -667,16 +724,6 @@ public:
 		glUniform1i(m_uniformHandle, MaterialType_Emissive);
 		glUniform1i(m_uniformHandle, MaterialType_Emissive);
 	}
 	}
 };
 };
-class BlurTextureUniform : public BaseUniform
-{
-public:
-	BlurTextureUniform(unsigned int p_shaderHandle) : BaseUniform(Config::shaderVar().blurTextureUniform, p_shaderHandle) { }
-
-	void update(const UniformData &p_uniformData)
-	{
-		glUniform1i(m_uniformHandle, GeometryBuffer::GBufferTextureType::GBufferBlur);
-	}
-};
 class CombinedTextureUniform : public BaseUniform
 class CombinedTextureUniform : public BaseUniform
 {
 {
 public:
 public:
@@ -706,7 +753,7 @@ public:
 
 
 	void update(const UniformData &p_uniformData)
 	void update(const UniformData &p_uniformData)
 	{
 	{
-		glUniform1i(m_uniformHandle, p_uniformData.getStaticEnvMapPos());
+//		glUniform1i(m_uniformHandle, p_uniformData.m_objectData.);
 	}
 	}
 };
 };
 
 

+ 62 - 0
Praxis3D/Source/SkyPass.h

@@ -0,0 +1,62 @@
+#pragma once
+
+#include "GraphicsDataSets.h"
+#include "RenderPassBase.h"
+
+class SkyPass : public RenderPass
+{
+public:
+	SkyPass(RendererFrontend &p_renderer) :
+		RenderPass(p_renderer) { }
+
+	~SkyPass() { }
+
+	ErrorCode init()
+	{
+		ErrorCode returnError = ErrorCode::Success;
+		ErrorCode shaderError;
+
+		m_name = "Blur Rendering Pass";
+
+		// Create a property-set used to load blur vertical shaders
+		PropertySet skyPassShaderShaderProperties(Properties::Shaders);
+		skyPassShaderShaderProperties.addProperty(Properties::VertexShader, Config::rendererVar().gaussian_blur_vertical_vert_shader);
+		skyPassShaderShaderProperties.addProperty(Properties::FragmentShader, Config::rendererVar().gaussian_blur_vertical_frag_shader);
+
+		// Create shaders
+		m_skyPassShader = Loaders::shader().load(skyPassShaderShaderProperties);
+
+		//		 _______________________________
+		//		|	  LOAD SKY PASS SHADER		|
+		//		|_______________________________|
+		shaderError = m_skyPassShader->loadToMemory();		// Load shader to memory
+		if(shaderError == ErrorCode::Success)					// Check if shader was loaded successfully
+			m_renderer.queueForLoading(*m_skyPassShader);	// Queue the shader to be loaded to GPU
+		else
+			returnError = shaderError;
+
+
+		return returnError;
+	}
+
+	void update(const SceneObjects &p_sceneObjects, const float p_deltaTime)
+	{
+		glDisable(GL_DEPTH_TEST);
+
+		// Set the default framebuffer to be drawn to
+		//m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferDefault);
+
+		// Bind final texture for reading so it can be accessed in the shaders
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferFinal, GeometryBuffer::GBufferFinal);
+
+		// Bind intermediate texture for writing to, so HDR mapping is outputed to it
+		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(GeometryBuffer::GBufferIntermediate);
+
+		// Perform HDR mapping. Queue and render a full screen quad using an HDR pass shader
+		m_renderer.queueForDrawing(m_skyPassShader->getShaderHandle(), m_skyPassShader->getUniformUpdater(), p_sceneObjects.m_camera->getBaseObjectData().m_modelMat);
+		m_renderer.passScreenSpaceDrawCommandsToBackend();
+	}
+
+private:
+	ShaderLoader::ShaderProgram	*m_skyPassShader;
+};