Updated glsl shaders

Updated glsl shaders

diff --git a/src/engine/GPURenderer/renderProgs/esharpening.fragment b/src/engine/GPURenderer/renderProgs/esharpening.fragment
index 8d521f2..3765ae8 100644
--- a/src/engine/GPURenderer/renderProgs/esharpening.fragment
+++ b/src/engine/GPURenderer/renderProgs/esharpening.fragment
@@ -1,6 +1,3 @@
-#extension GL_EXT_gpu_shader4 : enable
-#extension GL_ARB_texture_rectangle : enable
-
 uniform sampler2D u_TextureMap;
 uniform sampler2D u_LevelsMap;
 uniform vec4      u_Color;
diff --git a/src/engine/GPURenderer/renderProgs/lightall.fragment b/src/engine/GPURenderer/renderProgs/lightall.fragment
index e986b0d..0f0cbec 100644
--- a/src/engine/GPURenderer/renderProgs/lightall.fragment
+++ b/src/engine/GPURenderer/renderProgs/lightall.fragment
@@ -187,7 +187,7 @@ float LightRay(vec2 dp, vec2 ds, sampler2D normalMap)
 }
 #endif
 
-vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness, float ao) 
+vec3 CalcDiffuse(vec3 diffuseAlbedo, float NE, float NL, float LH, float roughness, float ao )
 {
 	return diffuseAlbedo * ao;
 }
@@ -293,7 +293,7 @@ void main()
 {
 	vec3 viewDir, lightColor, ambientColor, reflectance;
 	vec3 L, N, E, H;
-	float NL, NH, NE, EH, attenuation;
+	float NL, NH, NE, EH, LH, attenuation;
 	vec4 specular = vec4(0.0);
 	
 	#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
@@ -484,18 +484,24 @@ void main()
 		diffuse.rgb *= vec3(1.0) - specular.rgb;
 	#endif
 	
-	reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness, ao);
+	H = normalize(L + E);
+	NE = abs(dot(N, E)) + 1e-5;
+	NL = clamp(dot(N, L), 0.0, 1.0);
+	LH = clamp(dot(L, H), 0.0, 1.0);
+	NH = clamp(dot(N, H), 0.0, 1.0);	
+	
+	vec3 Fd = CalcDiffuse(diffuse.rgb, NE, NL, LH, roughness, ao);
+	vec3 Fs = vec3(0.0);
 	
-	#if defined(USE_LIGHT_VECTOR) || defined(USE_DELUXEMAP)
-		H  = normalize(L + E);
-		NL = clamp(dot(N, L), 0.0, 1.0);
-		NL = max(1e-8, abs(NL) );
-		EH = max(1e-8, dot(E, H));
-		NH = max(1e-8, dot(N, H));
-		NE = abs(dot(N, E)) + 1e-5;
-
-		reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, roughness);
+	#if defined(USE_LIGHT_VECTOR)
+		Fs = CalcSpecular(specular.rgb, NH, NL, NE, LH, roughness);
 	#endif
+
+	#if defined(USE_LIGHTMAP) && defined(USE_DELUXEMAP) && defined(r_deluxeSpecular)
+		Fs = CalcSpecular(specular.rgb, NH, NL, NE, LH, roughness) * r_deluxeSpecular;
+	#endif
+
+	reflectance = Fd + Fs;
   
 	gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
 	gl_FragColor.rgb += ambientColor * diffuse.rgb;
@@ -533,7 +539,7 @@ void main()
 
 	#if defined(USE_PRIMARY_LIGHT) || defined(SHADOWMAP_MODULATE)
 		vec3 L2, H2;
-		float NL2, EH2, NH2;
+		float NL2, EH2, NH2, L2H2;
 
 		L2 = var_PrimaryLightDir.xyz;
 
@@ -541,18 +547,15 @@ void main()
 		//sqrLightDist = dot(L2, L2);
 		//L2 /= sqrt(sqrLightDist);
 
-		H2  = normalize(L2 + E);
-		NL2 = clamp(dot(N, L2), 0.0, 1.0);
-		NL2 = max(1e-8, abs(NL2) );
+		L2 = normalize(var_PrimaryLightDir.xyz);
+		H2 = normalize(L2 + E);
+		NL2 = clamp(dot(N,  L2), 0.0, 1.0);
 		EH2 = max(1e-8, dot(E, H2));
+		L2H2 = clamp(dot(L2, H2), 0.0, 1.0);
 		NH2 = max(1e-8, dot(N, H2));
 
-		reflectance = CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness);
-
-		// bit of a hack, with modulated shadowmaps, ignore diffuse
-		#if !defined(SHADOWMAP_MODULATE)
-			reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness, 1.0f);
-		#endif
+		reflectance = CalcDiffuse(diffuse.rgb, NE, NL2, L2H2, roughness, 1.0f);
+		reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness);
 
 		lightColor = u_PrimaryLightColor * var_Color.rgb;
 
diff --git a/src/engine/GPURenderer/renderProgs/prefilterEnvMap.fragment b/src/engine/GPURenderer/renderProgs/prefilterEnvMap.fragment
index 4b4747d..a7d134a 100644
--- a/src/engine/GPURenderer/renderProgs/prefilterEnvMap.fragment
+++ b/src/engine/GPURenderer/renderProgs/prefilterEnvMap.fragment
@@ -16,23 +16,32 @@ vec2 hammersley2D(uint i, uint N) {
      return vec2(float(i)/float(N), radicalInverse_VdC(i));
 }
 
+float spec_D( float NH, float roughness)
+{
+  // normal distribution
+  // from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
+  float alpha = roughness * roughness;
+  float quotient = alpha / max(1e-8,(NH*NH*(alpha*alpha-1.0)+1.0));
+  return (quotient * quotient) / M_PI;
+}
+
 vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N)
 {
 	float a = Roughness * Roughness;
-	float Phi = 2 * M_PI * Xi.x;
-	float CosTheta = sqrt((1-Xi.y) / (1+(a*a -1) * Xi.y));
-	float SinTheta = sqrt( 1 - CosTheta * CosTheta);
+	float Phi = 2.0 * M_PI * Xi.x;
+	float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
+	float SinTheta = sqrt( 1.0 - CosTheta * CosTheta);
 
 	vec3 H;
 	H.x = SinTheta * cos( Phi );
 	H.y = SinTheta * sin( Phi );
 	H.z = CosTheta;
 
-	vec3 UpVector = abs(N.z) < 0.999 ? vec3(0,0,1) : vec3(1,0,0);
-	vec3 TangentX = normalize(cross(UpVector , N));
-	vec3 TangentY = cross(N , TangentX);
+	vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0,0.0,1.0) : vec3(1.0,0.0,0.0);
+	vec3 TangentX = normalize(cross(UpVector, N));
+	vec3 TangentY = cross(N, TangentX);
 
-	return TangentX * H.x + TangentY * H.y + N * H.z;
+	return normalize(TangentX * H.x + TangentY * H.y + N * H.z);
 }
 
 vec3 PrefilterEnvMap( float Roughness, vec3 R )
@@ -40,21 +49,33 @@ vec3 PrefilterEnvMap( float Roughness, vec3 R )
 	vec3 N = R;
 	vec3 V = R;
 	vec3 PrefilteredColor = vec3(0.0);
+	vec3 TextureColor = vec3(0.0);
 	float TotalWeight = 0.0;
-	uint NumSamples = 1024u;
+	const uint NumSamples = 4096u;
 	for ( uint i = 0u; i < NumSamples; i++ )
 	{
 		vec2 Xi = hammersley2D( i, NumSamples );
 		vec3 H = ImportanceSampleGGX( Xi, Roughness, N );
-		vec3 L = 2 * dot( V, H ) * H - V;
-		float NoL = clamp((dot( N, L )),0.0,1.0);
-		if ( NoL > 0 )
+		vec3 L = 2.0 * dot( V, H ) * H - V;
+		float NoL = max((dot( N, L )), 0.0);
+		if ( NoL > 0.0 )
 		{
-			PrefilteredColor += textureLod(u_CubeMap, L, 0.0).rgb * NoL;
+			float NH = max(dot ( N, H ), 0.0);
+			float HV = max(dot ( H, V ), 0.0);
+			float D   = spec_D(NH, Roughness);
+			float pdf = (D * NH / (4.0 * HV)) + 0.0001; 
+
+			float saTexel  = 4.0 * M_PI / (6.0 * CUBEMAP_RESOLUTION * CUBEMAP_RESOLUTION);
+			float saSample = 1.0 / (float(NumSamples) * pdf + 0.0001);
+
+			float mipLevel = Roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); 
+
+			TextureColor = textureLod(u_CubeMap, L, mipLevel).rgb;
+			PrefilteredColor += TextureColor * TextureColor * NoL;
 			TotalWeight += NoL;
 		}
 	}
-	return PrefilteredColor / TotalWeight;
+	return PrefilteredColor / max(TotalWeight, 0.001);
 }
 
 void main()
@@ -79,5 +100,5 @@ void main()
 
 	vec3 result = PrefilterEnvMap(roughness, normal);
 			
-	gl_FragColor = vec4(result, 1.0);
+	gl_FragColor = vec4(sqrt(result), 1.0);
 }
\ No newline at end of file
diff --git a/src/engine/GPURenderer/renderProgs/water.vertex b/src/engine/GPURenderer/renderProgs/water.vertex
index 4668bad..0ddb427 100644
--- a/src/engine/GPURenderer/renderProgs/water.vertex
+++ b/src/engine/GPURenderer/renderProgs/water.vertex
@@ -1,5 +1,3 @@
-#extension GL_EXT_gpu_shader4 : enable
-
 attribute vec3 attr_Position;
 attribute vec3 attr_Normal;
 

GitHub
sha: e3a08fc8