| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- #ifdef TEXTURELODSUPPORT
- #extension GL_EXT_shader_texture_lod : enable
- #endif
- precision highp float;
- #include<__decl__backgroundFragment>
- #define RECIPROCAL_PI2 0.15915494
- // Constants
- uniform vec3 vEyePosition;
- // Input
- varying vec3 vPositionW;
- #ifdef MAINUV1
- varying vec2 vMainUV1;
- #endif
- #ifdef MAINUV2
- varying vec2 vMainUV2;
- #endif
- #ifdef NORMAL
- varying vec3 vNormalW;
- #endif
- #ifdef DIFFUSE
- #if DIFFUSEDIRECTUV == 1
- #define vDiffuseUV vMainUV1
- #elif DIFFUSEDIRECTUV == 2
- #define vDiffuseUV vMainUV2
- #else
- varying vec2 vDiffuseUV;
- #endif
- uniform sampler2D diffuseSampler;
- #endif
- // Reflection
- #ifdef REFLECTION
- #ifdef REFLECTIONMAP_3D
- #define sampleReflection(s, c) textureCube(s, c)
- uniform samplerCube reflectionSampler;
-
- #ifdef TEXTURELODSUPPORT
- #define sampleReflectionLod(s, c, l) textureCubeLodEXT(s, c, l)
- #else
- uniform samplerCube reflectionSamplerLow;
- uniform samplerCube reflectionSamplerHigh;
- #endif
- #else
- #define sampleReflection(s, c) texture2D(s, c)
- uniform sampler2D reflectionSampler;
- #ifdef TEXTURELODSUPPORT
- #define sampleReflectionLod(s, c, l) texture2DLodEXT(s, c, l)
- #else
- uniform samplerCube reflectionSamplerLow;
- uniform samplerCube reflectionSamplerHigh;
- #endif
- #endif
- #ifdef REFLECTIONMAP_SKYBOX
- varying vec3 vPositionUVW;
- #else
- #if defined(REFLECTIONMAP_EQUIRECTANGULAR_FIXED) || defined(REFLECTIONMAP_MIRROREDEQUIRECTANGULAR_FIXED)
- varying vec3 vDirectionW;
- #endif
- #endif
- #include<reflectionFunction>
- #endif
- // Forces linear space for image processing
- #ifndef FROMLINEARSPACE
- #define FROMLINEARSPACE;
- #endif
- // Prevent expensive light computations
- #ifndef SHADOWONLY
- #define SHADOWONLY;
- #endif
- #include<imageProcessingDeclaration>
- // Lights
- #include<__decl__lightFragment>[0..maxSimultaneousLights]
- #include<helperFunctions>
- #include<lightsFragmentFunctions>
- #include<shadowsFragmentFunctions>
- #include<imageProcessingFunctions>
- #include<clipPlaneFragmentDeclaration>
- // Fog
- #include<fogFragmentDeclaration>
- #ifdef REFLECTIONFRESNEL
- #define FRESNEL_MAXIMUM_ON_ROUGH 0.25
- vec3 fresnelSchlickEnvironmentGGX(float VdotN, vec3 reflectance0, vec3 reflectance90, float smoothness)
- {
- // Schlick fresnel approximation, extended with basic smoothness term so that rough surfaces do not approach reflectance90 at grazing angle
- float weight = mix(FRESNEL_MAXIMUM_ON_ROUGH, 1.0, smoothness);
- return reflectance0 + weight * (reflectance90 - reflectance0) * pow(clamp(1.0 - VdotN, 0., 1.), 5.0);
- }
- #endif
- void main(void) {
- #include<clipPlaneFragment>
- vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
- // _____________________________ Normal Information ______________________________
- #ifdef NORMAL
- vec3 normalW = normalize(vNormalW);
- #else
- vec3 normalW = vec3(0.0, 1.0, 0.0);
- #endif
- // _____________________________ Light Information _______________________________
- float shadow = 1.;
- float globalShadow = 0.;
- float shadowLightCount = 0.;
- #include<lightFragment>[0..maxSimultaneousLights]
- #ifdef SHADOWINUSE
- globalShadow /= shadowLightCount;
- #else
- globalShadow = 1.0;
- #endif
- // _____________________________ REFLECTION ______________________________________
- vec3 reflectionColor = vec3(1., 1., 1.);
- #ifdef REFLECTION
- vec3 reflectionVector = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
- #ifdef REFLECTIONMAP_OPPOSITEZ
- reflectionVector.z *= -1.0;
- #endif
- // _____________________________ 2D vs 3D Maps ________________________________
- #ifdef REFLECTIONMAP_3D
- vec3 reflectionCoords = reflectionVector;
- #else
- vec2 reflectionCoords = reflectionVector.xy;
- #ifdef REFLECTIONMAP_PROJECTION
- reflectionCoords /= reflectionVector.z;
- #endif
- reflectionCoords.y = 1.0 - reflectionCoords.y;
- #endif
- #ifdef REFLECTIONBLUR
- float reflectionLOD = vReflectionInfos.y;
- #ifdef TEXTURELODSUPPORT
- // Apply environment convolution scale/offset filter tuning parameters to the mipmap LOD selection
- reflectionLOD = reflectionLOD * log2(vReflectionMicrosurfaceInfos.x) * vReflectionMicrosurfaceInfos.y + vReflectionMicrosurfaceInfos.z;
- reflectionColor = sampleReflectionLod(reflectionSampler, reflectionCoords, reflectionLOD).rgb;
- #else
- float lodReflectionNormalized = clamp(reflectionLOD, 0., 1.);
- float lodReflectionNormalizedDoubled = lodReflectionNormalized * 2.0;
- vec3 reflectionSpecularMid = sampleReflection(reflectionSampler, reflectionCoords).rgb;
- if(lodReflectionNormalizedDoubled < 1.0){
- reflectionColor = mix(
- sampleReflection(reflectionSamplerHigh, reflectionCoords).rgb,
- reflectionSpecularMid,
- lodReflectionNormalizedDoubled
- );
- } else {
- reflectionColor = mix(
- reflectionSpecularMid,
- sampleReflection(reflectionSamplerLow, reflectionCoords).rgb,
- lodReflectionNormalizedDoubled - 1.0
- );
- }
- #endif
- #else
- vec4 reflectionSample = sampleReflection(reflectionSampler, reflectionCoords);
- reflectionColor = reflectionSample.rgb;
- #endif
- #ifdef GAMMAREFLECTION
- reflectionColor = toLinearSpace(reflectionColor.rgb);
- #endif
- #ifdef REFLECTIONBGR
- reflectionColor = reflectionColor.bgr;
- #endif
- // _____________________________ Levels _____________________________________
- reflectionColor *= vReflectionInfos.x;
- #endif
- // _____________________________ Diffuse Information _______________________________
- vec3 diffuseColor = vec3(1., 1., 1.);
- float finalAlpha = alpha;
- #ifdef DIFFUSE
- vec4 diffuseMap = texture2D(diffuseSampler, vDiffuseUV);
- #ifdef GAMMADIFFUSE
- diffuseMap.rgb = toLinearSpace(diffuseMap.rgb);
- #endif
- // _____________________________ Levels _____________________________________
- diffuseMap.rgb *= vDiffuseInfos.y;
- #ifdef DIFFUSEHASALPHA
- finalAlpha *= diffuseMap.a;
- #endif
- diffuseColor = diffuseMap.rgb;
- #endif
- // _____________________________ MIX ________________________________________
- #ifdef REFLECTIONFRESNEL
- vec3 colorBase = diffuseColor;
- #else
- vec3 colorBase = reflectionColor * diffuseColor;
- #endif
- colorBase = max(colorBase, 0.0);
- // ___________________________ COMPOSE _______________________________________
- #ifdef USERGBCOLOR
- vec3 finalColor = colorBase;
- #else
- vec3 finalColor = colorBase.r * vPrimaryColor.rgb * vPrimaryColor.a;
- finalColor += colorBase.g * vSecondaryColor.rgb * vSecondaryColor.a;
- finalColor += colorBase.b * vTertiaryColor.rgb * vTertiaryColor.a;
- #endif
- // ___________________________ FRESNELS _______________________________________
- #ifdef REFLECTIONFRESNEL
- vec3 reflectionAmount = vReflectionControl.xxx;
- vec3 reflectionReflectance0 = vReflectionControl.yyy;
- vec3 reflectionReflectance90 = vReflectionControl.zzz;
- float VdotN = dot(normalize(vEyePosition), normalW);
- vec3 planarReflectionFresnel = fresnelSchlickEnvironmentGGX(clamp(VdotN, 0.0, 1.0), reflectionReflectance0, reflectionReflectance90, 1.0);
- reflectionAmount *= planarReflectionFresnel;
- #ifdef REFLECTIONFALLOFF
- float reflectionDistanceFalloff = 1.0 - clamp(length(vPositionW.xyz - vBackgroundCenter) * vReflectionControl.w, 0.0, 1.0);
- reflectionDistanceFalloff *= reflectionDistanceFalloff;
- reflectionAmount *= reflectionDistanceFalloff;
- #endif
- finalColor = mix(finalColor, reflectionColor, clamp(reflectionAmount, 0., 1.));
- #endif
- #ifdef OPACITYFRESNEL
- float viewAngleToFloor = dot(normalW, normalize(vEyePosition - vBackgroundCenter));
- // Fade out the floor plane as the angle between the floor and the camera tends to 0 (starting from startAngle)
- const float startAngle = 0.1;
- float fadeFactor = clamp(viewAngleToFloor/startAngle, 0.0, 1.0);
- finalAlpha *= fadeFactor * fadeFactor;
- #endif
- // ___________________________ SHADOWS _______________________________________
- #ifdef SHADOWINUSE
- finalColor = mix(finalColor * shadowLevel, finalColor, globalShadow);
- #endif
- // ___________________________ FINALIZE _______________________________________
- vec4 color = vec4(finalColor, finalAlpha);
- #include<fogFragment>
- #ifdef IMAGEPROCESSINGPOSTPROCESS
- // Sanitize output incase invalid normals or tangents have caused div by 0 or undefined behavior
- // this also limits the brightness which helpfully reduces over-sparkling in bloom (native handles this in the bloom blur shader)
- color.rgb = clamp(color.rgb, 0., 30.0);
- #else
- // Alway run even to ensure going back to gamma space.
- color = applyImageProcessing(color);
- #endif
- #ifdef PREMULTIPLYALPHA
- // Convert to associative (premultiplied) format if needed.
- color.rgb *= color.a;
- #endif
- #ifdef NOISE
- color.rgb += dither(vPositionW.xy, 0.5);
- color = max(color, 0.0);
- #endif
- gl_FragColor = color;
- }
|