|
@@ -0,0 +1,202 @@
|
|
|
+#import "Common/ShaderLib/Lighting.glsllib"
|
|
|
+#import "Common/ShaderLib/PBR.glsllib"
|
|
|
+
|
|
|
+//declare PBR Lighting vars
|
|
|
+uniform vec4 g_LightData[NB_LIGHTS];
|
|
|
+uniform vec3 g_CameraPosition;
|
|
|
+uniform vec4 g_AmbientLightColor;
|
|
|
+
|
|
|
+#if NB_PROBES >= 1
|
|
|
+ uniform samplerCube g_PrefEnvMap;
|
|
|
+ uniform vec3 g_ShCoeffs[9];
|
|
|
+ uniform mat4 g_LightProbeData;
|
|
|
+#endif
|
|
|
+#if NB_PROBES >= 2
|
|
|
+ uniform samplerCube g_PrefEnvMap2;
|
|
|
+ uniform vec3 g_ShCoeffs2[9];
|
|
|
+ uniform mat4 g_LightProbeData2;
|
|
|
+#endif
|
|
|
+#if NB_PROBES == 3
|
|
|
+ uniform samplerCube g_PrefEnvMap3;
|
|
|
+ uniform vec3 g_ShCoeffs3[9];
|
|
|
+ uniform mat4 g_LightProbeData3;
|
|
|
+#endif
|
|
|
+
|
|
|
+// Specular-AA
|
|
|
+#ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
|
|
|
+ uniform float m_SpecularAASigma;
|
|
|
+#endif
|
|
|
+#ifdef SPECULAR_AA_THRESHOLD
|
|
|
+ uniform float m_SpecularAAKappa;
|
|
|
+#endif
|
|
|
+
|
|
|
+vec3 calculatePBRLighting(in vec4 albedo, in float Metallic, in float Roughness, in vec3 lightMapColor, in vec3 ao, in float indoorSunLightExposure, in vec3 normal, in vec3 norm, in vec3 viewDir){
|
|
|
+ vec3 finalLightingValue;
|
|
|
+
|
|
|
+ #ifdef SPECGLOSSPIPELINE
|
|
|
+
|
|
|
+ #ifdef USE_PACKED_SG
|
|
|
+ vec4 specularColor = texture2D(m_SpecularGlossinessMap, newTexCoord);
|
|
|
+ float glossiness = specularColor.a * m_Glossiness;
|
|
|
+ specularColor *= m_Specular;
|
|
|
+ #else
|
|
|
+ #ifdef SPECULARMAP
|
|
|
+ vec4 specularColor = texture2D(m_SpecularMap, newTexCoord);
|
|
|
+ #else
|
|
|
+ vec4 specularColor = vec4(1.0);
|
|
|
+ #endif
|
|
|
+ #ifdef GLOSSINESSMAP
|
|
|
+ float glossiness = texture2D(m_GlossinessMap, newTexCoord).r * m_Glossiness;
|
|
|
+ #else
|
|
|
+ float glossiness = m_Glossiness;
|
|
|
+ #endif
|
|
|
+ specularColor *= m_Specular;
|
|
|
+ #endif
|
|
|
+ vec4 diffuseColor = albedo;// * (1.0 - max(max(specularColor.r, specularColor.g), specularColor.b));
|
|
|
+ Roughness = 1.0 - glossiness;
|
|
|
+ vec3 fZero = specularColor.xyz;
|
|
|
+ #else
|
|
|
+ float specular = 0.5;
|
|
|
+ float nonMetalSpec = 0.08 * specular;
|
|
|
+ vec4 specularColor = (nonMetalSpec - nonMetalSpec * Metallic) + albedo * Metallic;
|
|
|
+ vec4 diffuseColor = albedo - albedo * Metallic;
|
|
|
+ vec3 fZero = vec3(specular);
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #ifdef LIGHTMAP
|
|
|
+ #if !defined(AO_MAP)
|
|
|
+ finalLightingValue.rgb += diffuseColor.rgb * lightMapColor;
|
|
|
+ #endif
|
|
|
+ specularColor.rgb *= lightMapColor;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #ifdef SPECULAR_AA
|
|
|
+ float sigma = 1.0;
|
|
|
+ float kappa = 0.18;
|
|
|
+ #ifdef SPECULAR_AA_SCREEN_SPACE_VARIANCE
|
|
|
+ sigma = m_SpecularAASigma;
|
|
|
+ #endif
|
|
|
+ #ifdef SPECULAR_AA_THRESHOLD
|
|
|
+ kappa = m_SpecularAAKappa;
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
+ float finalLightingScale = 1.0;
|
|
|
+ float brightestPointLight = 1.0;
|
|
|
+
|
|
|
+ float ndotv = max( dot( normal, viewDir ),0.0);
|
|
|
+ for( int i = 0;i < NB_LIGHTS; i+=3){
|
|
|
+ vec4 lightColor = g_LightData[i];
|
|
|
+ vec4 lightData1 = g_LightData[i+1];
|
|
|
+ vec4 lightDir;
|
|
|
+ vec3 lightVec;
|
|
|
+ lightComputeDir(wPosition, lightColor.w, lightData1, lightDir, lightVec);
|
|
|
+
|
|
|
+ float fallOff = 1.0;
|
|
|
+ #if __VERSION__ >= 110
|
|
|
+ // allow use of control flow
|
|
|
+ if(lightColor.w > 1.0){
|
|
|
+ #endif
|
|
|
+ fallOff = computeSpotFalloff(g_LightData[i+2], lightVec);
|
|
|
+ #if __VERSION__ >= 110
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+ //point light attenuation
|
|
|
+ fallOff *= lightDir.w;
|
|
|
+
|
|
|
+ lightDir.xyz = normalize(lightDir.xyz);
|
|
|
+ vec3 directDiffuse;
|
|
|
+ vec3 directSpecular;
|
|
|
+
|
|
|
+ #ifdef SPECULAR_AA
|
|
|
+ float hdotv = PBR_ComputeDirectLightWithSpecularAA(
|
|
|
+ normal, lightDir.xyz, viewDir,
|
|
|
+ lightColor.rgb, fZero, Roughness, sigma, kappa, ndotv,
|
|
|
+ directDiffuse, directSpecular);
|
|
|
+ #else
|
|
|
+ float hdotv = PBR_ComputeDirectLight(
|
|
|
+ normal, lightDir.xyz, viewDir,
|
|
|
+ lightColor.rgb, fZero, Roughness, ndotv,
|
|
|
+ directDiffuse, directSpecular);
|
|
|
+ #endif
|
|
|
+
|
|
|
+ vec3 directLighting = diffuseColor.rgb *directDiffuse + directSpecular;
|
|
|
+
|
|
|
+ #if defined(USE_VERTEX_COLORS_AS_SUN_INTENSITY) || defined(STATIC_SUN_INTENSITY)
|
|
|
+ if(fallOff == 1.0){
|
|
|
+ directLighting.rgb *= indoorSunLightExposure;// used to scale down how intense just the sun is indoors, and so the ambientLighting can be scaled back up indoors based on nearest pointlight intensity (ambient and direct light are 1.0 fallOff)
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ brightestPointLight = max(fallOff, brightestPointLight);
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ finalLightingValue.rgb += directLighting * fallOff;
|
|
|
+ }
|
|
|
+
|
|
|
+ float minVertLighting;
|
|
|
+ #ifdef BRIGHTEN_INDOOR_SHADOWS
|
|
|
+ minVertLighting = 0.0833; //enable this when using shadows, in order to brighten indoor areas (which are naturally covered from the DL shadows) so that indoor areas are not way too dark when using IndoorLighting with shadows compared to when shadows are off
|
|
|
+ #else
|
|
|
+ minVertLighting = 0.0533;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ finalLightingScale = max(finalLightingScale, brightestPointLight);
|
|
|
+ finalLightingScale = max(finalLightingScale, minVertLighting); //essentially just the vertColors.r (aka indoor light exposure) multiplied by the time of day scale.
|
|
|
+
|
|
|
+ #if NB_PROBES >= 1
|
|
|
+ vec3 color1 = vec3(0.0);
|
|
|
+ vec3 color2 = vec3(0.0);
|
|
|
+ vec3 color3 = vec3(0.0);
|
|
|
+ float weight1 = 1.0;
|
|
|
+ float weight2 = 0.0;
|
|
|
+ float weight3 = 0.0;
|
|
|
+
|
|
|
+ float ndf = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData, g_ShCoeffs, g_PrefEnvMap, color1);
|
|
|
+ #if NB_PROBES >= 2
|
|
|
+ float ndf2 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData2, g_ShCoeffs2, g_PrefEnvMap2, color2);
|
|
|
+ #endif
|
|
|
+ #if NB_PROBES == 3
|
|
|
+ float ndf3 = renderProbe(viewDir, wPosition, normal, norm, Roughness, diffuseColor, specularColor, ndotv, ao, g_LightProbeData3, g_ShCoeffs3, g_PrefEnvMap3, color3);
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #if NB_PROBES >= 2
|
|
|
+ float invNdf = max(1.0 - ndf,0.0);
|
|
|
+ float invNdf2 = max(1.0 - ndf2,0.0);
|
|
|
+ float sumNdf = ndf + ndf2;
|
|
|
+ float sumInvNdf = invNdf + invNdf2;
|
|
|
+ #if NB_PROBES == 3
|
|
|
+ float invNdf3 = max(1.0 - ndf3,0.0);
|
|
|
+ sumNdf += ndf3;
|
|
|
+ sumInvNdf += invNdf3;
|
|
|
+ weight3 = ((1.0 - (ndf3 / sumNdf)) / (NB_PROBES - 1)) * (invNdf3 / sumInvNdf);
|
|
|
+ #endif
|
|
|
+
|
|
|
+ weight1 = ((1.0 - (ndf / sumNdf)) / (NB_PROBES - 1)) * (invNdf / sumInvNdf);
|
|
|
+ weight2 = ((1.0 - (ndf2 / sumNdf)) / (NB_PROBES - 1)) * (invNdf2 / sumInvNdf);
|
|
|
+
|
|
|
+ float weightSum = weight1 + weight2 + weight3;
|
|
|
+
|
|
|
+ weight1 /= weightSum;
|
|
|
+ weight2 /= weightSum;
|
|
|
+ weight3 /= weightSum;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #ifdef USE_AMBIENT_LIGHT
|
|
|
+ color1.rgb *= g_AmbientLightColor.rgb;
|
|
|
+ color2.rgb *= g_AmbientLightColor.rgb;
|
|
|
+ color3.rgb *= g_AmbientLightColor.rgb;
|
|
|
+ #endif
|
|
|
+
|
|
|
+ // multiply probes by the finalLightingScale, as determined by pixel's
|
|
|
+ // sunlightExposure and adjusted for nearby point/spot lights
|
|
|
+ color1.rgb *= finalLightingScale;
|
|
|
+ color2.rgb *= finalLightingScale;
|
|
|
+ color3.rgb *= finalLightingScale;
|
|
|
+
|
|
|
+ finalLightingValue.rgb += color1 * clamp(weight1,0.0,1.0) + color2 * clamp(weight2,0.0,1.0) + color3 * clamp(weight3,0.0,1.0);
|
|
|
+
|
|
|
+ #endif
|
|
|
+
|
|
|
+ return finalLightingValue;
|
|
|
+}
|