| 
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -22,7 +22,6 @@ varying vec3 fragNormal; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			varying vec4 shadowPos; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			varying mat3 TBN; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Input uniform values | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			uniform int numOfLights; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			uniform sampler2D albedoMap; | 
			
		
		
	
	
		
			
				| 
				
					
						
					
				
				
					
						
					
				
				
				 | 
			
			 | 
			
			@ -53,102 +52,108 @@ uniform vec3 viewPos; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			uniform vec3 ambientColor; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			uniform float ambient; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// refl in range  0 to 1 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// returns base reflectivity to 1 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// incrase reflectivity when surface view at larger angle | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			vec3 schlickFresnel(float hDotV,vec3 refl) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// Reflectivity in range 0.0 to 1.0 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			// NOTE: Reflectivity is increased when surface view at larger angle | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			vec3 SchlickFresnel(float hDotV,vec3 refl) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return refl + (1.0 - refl) * pow(1.0 - err">hDotV,5.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return refl + (1.0 - refl)*pow(1.0 - nf">hDotV, 5.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			float ggxDistribution(float nDotH,float roughness) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			float GgxDistribution(float nDotH,float roughness) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float a = nf">roughness * roughness * roughness * roughness; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float d = nDotH * nDotH * (a - 1.0) + 1.0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        d = nf">PI * d * d; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return a / max(d,0.0000001); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float a = err">roughness*roughness*roughness*roughness; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float d = nDotH*nDotH*(a - 1.0) + 1.0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    d = err">PI*d*d; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return (a/max(d,0.0000001)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			float geomSmith(float nDotV,float nDotL,float roughness) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			float GeomSmith(float nDotV,float nDotL,float roughness) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float r = roughness + 1.0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float k = nf">r * r / 8.0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float ik = 1.0 - k; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float ggx1 = nDotV</span> / (nDotV * ik + k); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float ggx2 = nDotL</span> / (nDotL * ik + k); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return ggx1 * ggx2; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float r = roughness + 1.0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float k = err">r*r/8.0; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float ik = 1.0 - k; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float ggx1 = nDotV/(nDotV*ik + k); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float ggx2 = nDotL/(nDotL*ik + k); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return ggx1*ggx2; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			vec3 pbr(){ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 albedo = texture2D(albedoMap,vec2(fragTexCoord.x*tiling.x+offset.x,fragTexCoord.y*tiling.y+offset.y)).rgb; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        albedo = vec3(albedoColor.x*albedo.x,albedoColor.y*albedo.y,albedoColor.z*albedo.z); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float metallic = clamp(metallicValue,0.0,1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float roughness = clamp(roughnessValue,0.0,1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float ao = clamp(aoValue,0.0,1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        if(useTexMRA == 1) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x * tiling.x + offset.x, fragTexCoord.y * tiling.y + offset.y)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            metallic = clamp(mra.r+metallicValue,0.04,1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            roughness = clamp(mra.g+roughnessValue,0.04,1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            ao = (mra.b+aoValue)*0.5; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 N = normalize(fragNormal); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        if(useTexNormal == 1) { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            N = texture2D(normalMap, vec2(fragTexCoord.x * tiling.x + offset.y, fragTexCoord.y * tiling.y + offset.y)).rgb; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            N = normalize(N * 2.0 - 1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            N = normalize(N * TBN); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 V = normalize(viewPos - fragPosition); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			vec3 ComputePBR() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    vec3 albedo = texture2D(albedoMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    albedo = vec3(albedoColor.x*albedo.x, albedoColor.y*albedo.y, albedoColor.z*albedo.z); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float metallic = clamp(metallicValue, 0.0, 1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float roughness = clamp(roughnessValue, 0.0, 1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    float ao = clamp(aoValue, 0.0, 1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (useTexMRA == 1) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec4 mra = texture2D(mraMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        metallic = clamp(mra.r + metallicValue, 0.04, 1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        roughness = clamp(mra.g + roughnessValue, 0.04, 1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        ao = (mra.b + aoValue)*0.5; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    vec3 N = normalize(fragNormal); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    if (useTexNormal == 1) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        N = texture2D(normalMap, vec2(fragTexCoord.x*tiling.x + offset.y, fragTexCoord.y*tiling.y + offset.y)).rgb; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        N = normalize(N*2.0 - 1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        N = normalize(N*TBN); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    vec3 V = normalize(viewPos - fragPosition); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    vec3 emissive = vec3(0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    emissive = (texture2D(emissiveMap, vec2(fragTexCoord.x*tiling.x + offset.x, fragTexCoord.y*tiling.y + offset.y)).rgb).g*emissiveColor.rgb*emissivePower*float(useTexEmissive); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // return N;//vec3(metallic,metallic,metallic); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // If  dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    vec3 baseRefl = mix(vec3(0.04), albedo.rgb, metallic); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    vec3 lightAccum = vec3(0.0);  // Acumulate lighting lum | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    for (int i = 0; i < 4; i++) | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    { | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 L = normalize(lights[i].position - fragPosition);      // Compute light vector | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 H = normalize(V + L);                                  // Compute halfway bisecting vector | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float dist = length(lights[i].position - fragPosition);     // Compute distance to light | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float attenuation = 1.0/(dist*dist*0.23);                   // Compute attenuation | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 radiance = lights[i].color.rgb*lights[i].intensity*attenuation; // Compute input radiance, light energy comming in | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        // Cook-Torrance BRDF distribution function | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float nDotV = max(dot(N,V), 0.0000001); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float nDotL = max(dot(N,L), 0.0000001); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float hDotV = max(dot(H,V), 0.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float nDotH = max(dot(N,H), 0.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float D = GgxDistribution(nDotH, roughness);    // Larger the more micro-facets aligned to H | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        float G = GeomSmith(nDotV, nDotL, roughness);   // Smaller the more micro-facets shadow | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 F = SchlickFresnel(hDotV, baseRefl);       // Fresnel proportion of specular reflectance | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 spec = (D*G*F)/(4.0*nDotV*nDotL); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 e = vec3(0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        e = (texture2D(emissiveMap, vec2(fragTexCoord.x*tiling.x+offset.x, fragTexCoord.y*tiling.y+offset.y)).rgb).g * emissiveColor.rgb*emissivePower * float(useTexEmissive); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        // Difuse and spec light can't be above 1.0 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        // kD = 1.0 - kS  diffuse component is equal 1.0 - spec comonent | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 kD = vec3(1.0) - F; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        //return N;//vec3(metallic,metallic,metallic); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        //if  dia-electric use base reflectivity of 0.04 otherwise ut is a metal use albedo as base reflectivity | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 baseRefl = mix(vec3(0.04),albedo.rgb,metallic); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 Lo = vec3(0.0);  // acumulate lighting lum | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        for(int i=0;i<numOfLights;++i){ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            vec3 L = normalize(lights[i].position - fragPosition);  // calc light vector | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            vec3 H = normalize(V + L);                              // calc halfway bisecting vector | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            float dist = length(lights[i].position - fragPosition); // calc distance to light | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            float attenuation = 1.0 / (dist * dist * 0.23);                // calc attenuation | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            vec3 radiance = lights[i].color.rgb * lights[i].intensity * attenuation;         // calc input radiance,light energy comming in | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            //Cook-Torrance BRDF distribution function | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            float nDotV = max(dot(N,V),0.0000001); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            float nDotL = max(dot(N,L),0.0000001); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            float hDotV = max(dot(H,V),0.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            float nDotH = max(dot(N,H),0.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            float D = ggxDistribution(nDotH,roughness); // larger the more micro-facets aligned to H | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            float G = geomSmith(nDotV,nDotL,roughness); // smaller the more micro-facets shadow | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            vec3 F = schlickFresnel(hDotV, baseRefl);  // fresnel proportion of specular reflectance | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            vec3 spec = (D * G * F) / (4.0 * nDotV * nDotL); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            // difuse and spec light can't be above 1.0 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            // kD = 1.0 - kS  diffuse component is equal 1.0 - spec comonent | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            vec3 kD = vec3(1.0) - F; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            //mult kD by the inverse of metallnes , only non-metals should have diffuse light | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            kD *= 1.0 - metallic; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			            Lo += ((kD * albedo.rgb / PI + spec) * radiance * nDotL)*float(lights[i].enabled); // angle of light has impact on result | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        vec3 ambient_final = (ambientColor + albedo)* ambient * 0.5; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        return ambient_final+Lo*ao+e; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        // Mult kD by the inverse of metallnes, only non-metals should have diffuse light | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        kD *= 1.0 - metallic; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        lightAccum += ((kD*albedo.rgb/PI + spec)*radiance*nDotL)*float(lights[i].enabled); // Angle of light has impact on result | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    } | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    vec3 ambientFinal = (ambientColor + albedo)*ambient*0.5; | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    return (ambientFinal + lightAccum*ao + emissive); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			void main() | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			{ | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			       vec3 color = pbr(); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        //HDR tonemapping | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        color = pow(color,color + vec3(1.0)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        //gamma correction | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        color = pow(color,vec3(1.0/2.2)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    vec3 color = ComputePBR(); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			        gl_FragColor = vec4(color,1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			         | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // HDR tonemapping | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    color = pow(color, color + vec3(1.0)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			     | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    // Gamma correction | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    color = pow(color, vec3(1.0/2.2)); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			
 | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			    gl_FragColor = vec4(color,1.0); | 
			
		
		
	
		
			
			 | 
			 | 
			
			 | 
			
			} |