#include "/lib/shaderSettings/mainLighting.glsl" #include "/lib/shaderSettings/cloudsAndLighting.glsl" #include "/lib/shaderSettings/shadowMainLighting.glsl" #include "/lib/shaderSettings/endFlash.glsl" #ifdef AURORA_INFLUENCE #include "/lib/atmospherics/auroraBorealis.glsl" #endif //Lighting Includes// #include "/lib/colors/lightAndAmbientColors.glsl" #include "/lib/lighting/ggx.glsl" #include "/lib/lighting/minimumLighting.glsl" #if SHADOW_QUALITY > -1 && (defined OVERWORLD || defined END) #include "/lib/lighting/shadowSampling.glsl" #endif #if HELD_LIGHTING_MODE >= 1 #include "/lib/lighting/heldLighting.glsl" #endif #ifdef CLOUD_SHADOWS #include "/lib/lighting/cloudShadows.glsl" #endif #ifdef LIGHT_COLOR_MULTS #include "/lib/colors/colorMultipliers.glsl" #endif #if defined MOON_PHASE_INF_LIGHT || defined MOON_PHASE_INF_REFLECTION #include "/lib/colors/moonPhaseInfluence.glsl" #endif #if COLORED_LIGHTING_INTERNAL > 0 #include "/lib/voxelization/lightVoxelization.glsl" #endif #if DRAGON_DEATH_EFFECT_INTERNAL > 0 #define ENDCRYSTAL_SAMPLER_DEFINE uniform isampler2D endcrystal_sampler; #endif vec3 highlightColor = normalize(pow(lightColor, vec3(0.37))) * (0.3 + 1.5 * sunVisibility2) * (1.0 - 0.85 * rainFactor); //Lighting// void DoLighting(inout vec4 color, inout vec3 shadowMult, vec3 playerPos, vec3 viewPos, float lViewPos, vec3 geoNormal, vec3 normalM, float dither, vec3 worldGeoNormal, vec2 lightmap, bool noSmoothLighting, bool noDirectionalShading, bool noVanillaAO, bool centerShadowBias, int subsurfaceMode, float smoothnessG, float highlightMult, float emission, inout float purkinjeOverwrite, bool isLightSource, inout float enderDragonDead) { #ifdef WORLD_CURVATURE playerPos.y += doWorldCurvature(playerPos.xz); #endif vec2 oldLightmap = lightmap.xy; #ifdef DO_PIXELATION_EFFECTS vec2 pixelationOffset = ComputeTexelOffset(tex, texCoord); #if defined PIXELATED_SHADOWS || defined PIXELATED_BLOCKLIGHT vec3 playerPosPixelated = TexelSnap(playerPos, pixelationOffset); #endif #ifdef PIXELATED_SHADOWS #ifdef GBUFFERS_ENTITIES if (entityId == 50076) { // Boats playerPosPixelated.y += 0.38; // consistentBOAT2176 } #endif #ifdef GBUFFERS_TERRAIN if (subsurfaceMode == 1) { playerPosPixelated.y += 0.05; // Fixes grounded foliage having dark bottom pixels depending on the random y-offset } #endif #endif #ifdef PIXELATED_BLOCKLIGHT if (!noSmoothLighting) { lightmap = clamp(TexelSnap(lightmap, pixelationOffset), 0.0, 1.0); } #endif #endif float NdotN = dot(normalM, northVec); float absNdotN = abs(NdotN); float NdotE = dot(normalM, eastVec); float absNdotE = abs(NdotE); float NdotL = dot(normalM, lightVec); float lightmapY2 = pow2(lightmap.y); float lightmapYM = smoothstep1(lightmap.y); float subsurfaceHighlight = 0.0; float ambientMult = 1.0; vec3 subsurfaceColor = vec3(1.0); #if defined AURORA_INFLUENCE && !(defined DEFERRED1 || defined COMPOSITE1) ambientColor = getAuroraAmbientColor(ambientColor, viewPos, 0.035, AURORA_TERRAIN_INFLUENCE_INTENSITY, 0.9); #endif #if BLOOD_MOON > 0 float bloodMoonFactor = getBloodMoon(sunVisibility); lightColor *= 1.0 + bloodMoonFactor * vec3(0.6, -0.3, -0.3); ambientColor *= 1.0 + bloodMoonFactor * vec3(0.6, -0.3, -0.3); subsurfaceColor = mix(vec3(1.0), vec3(1.3, 0.2, 0.2), bloodMoonFactor); #endif vec3 lightColorM = lightColor; vec3 ambientColorM = ambientColor; vec3 nViewPos = normalize(viewPos); #if defined LIGHT_COLOR_MULTS && !defined GBUFFERS_WATER // lightColorMult is defined early in gbuffers_water lightColorMult = GetLightColorMult(); #endif vec2 lightningAdd = vec2(0); vec2 deathFlashAdd = vec2(0); vec3 lightningPos = vec3(0); #ifdef RAIN_ATMOSPHERE float lightningDistance = 550.0; lightningPos = getLightningPos(playerPos, lightningBoltPosition.xyz, false); float lightningFadeOut = max(1.0 - length(lightningPos) / lightningDistance, 0.0); float lightningFadeOutExp = exp((1.0 - lightningFadeOut) * -15.0); vec3 normalLightning = mat3(gbufferModelViewInverse) * mix(geoNormal, normalM, 0.25); float lightningNormalGradient = 0.12; if (subsurfaceMode == 1) lightningNormalGradient = mix(lightningNormalGradient, 0.45, lightningFadeOutExp); lightningAdd = (lightningFlashEffect(lightningPos, normalLightning, lightningDistance, lightningNormalGradient, subsurfaceMode) * 10.0 + mix(0.1, 0.0 , lightningFadeOut)) * isLightningActive(); ambientColorM += lightningAdd.x; #endif #if DRAGON_DEATH_EFFECT_INTERNAL > 0 vec3 dragonPosition = vec3(0, 80, 0) - cameraPosition; int isDying = texelFetch(endcrystal_sampler, ivec2(35, 0), 0).r; float dragonDeathFactor = 0.0001 * isDying; float deathFadeFactor = exp(-3.0 * (1.0 - dragonDeathFactor)) * dragonDeathFactor; if (dragonDeathFactor < 0.99) { vec3 normalMDeath = mat3(gbufferModelViewInverse) * mix(geoNormal, normalM, 0.5); vec3 deathFlashPos = getLightningPos(playerPos, dragonPosition, true); float effectDistance = 800.0; deathFlashAdd = lightningFlashEffect(deathFlashPos, normalMDeath, effectDistance, 0.0, subsurfaceMode) * 35.0 * deathFadeFactor; ambientColorM *= mix(1.0, 0.0, deathFadeFactor) + deathFlashAdd.x * saturateColors(sqrt(endOrangeCol), 0.5); purkinjeOverwrite = 1.0 * deathFlashAdd.y; } #endif #if defined END && END_CENTER_LIGHTING > 0 && MC_VERSION >= 10900 && (defined GBUFFERS_BLOCK || defined GBUFFERS_ENTITIES || defined GBUFFERS_TERRAIN || defined GBUFFERS_HAND || defined GBUFFERS_WATER) enderDragonDead = 1.0 - texelFetch(colortex5, ivec2(viewWidth-1, viewHeight-1), 0).a; vec3 endCenterCol = saturateColors(vec3(END_CENTER_LIGHTING_R, END_CENTER_LIGHTING_G, END_CENTER_LIGHTING_B) * 0.8, 1.1); vec3 endCenterPos = vec3(0.5, 60.5, 0.5) - (playerPos + cameraPositionBest); endCenterPos.y *= 0.66; // Make it a pill-shaped point light float rawDistance = length(endCenterPos); float endCenterLightDist = exp(-rawDistance * 0.22); float endCenterTimeNoise = frameTimeCounter * 0.075; // Get the direction of the noise float centerDistance = max(abs(endCenterPos.x), abs(endCenterPos.z)); // Square distance float angleOffset = endCenterTimeNoise * 0.75; vec2 rotatingDir = vec2(cos(angleOffset), sin(angleOffset)); float blendFactor = smoothstep(0.5, 3.0, centerDistance); // Prevent artifacts at the center by creating square shape vec2 normalizedDir = mix(rotatingDir, normalize(endCenterPos.xz), blendFactor); // Blend square shape vec2 endCenterNoiseBase = endCenterPos.xz * 0.03 + endCenterPos.y * 0.015; vec2 endCenterNoisePos = endCenterNoiseBase - normalizedDir * 0.3 + endCenterTimeNoise * 0.15; float endCenterIntensityNoise = texture2DLod(noisetex, endCenterNoisePos, 0.0).r; float endCenterNoiseVariation = sin(endCenterTimeNoise * 6.0 + dot(endCenterPos.xy, endCenterPos.yz) * 0.01); float endCenterNoiseIntensity = 0.7 + 0.35 * endCenterIntensityNoise + 0.2 * endCenterNoiseVariation; // Hybrid lighting calculation - directional for walls, ambient for floors vec3 transformedNormal = mat3(gbufferModelViewInverse) * normalM; float normalDot = clamp01(dot(normalize(endCenterPos), transformedNormal)); float isFloor = clamp01(dot(transformedNormal, vec3(0.0, 1.0, 0.0)) * 2.0); // Strong directional lighting for walls, softer lighting for floors float directionalFactor = normalDot * 1.3; float floorFactor = 0.6 + 0.25 * normalDot; float endCenterLight = endCenterLightDist * mix(directionalFactor, floorFactor, isFloor); ambientColorM += endCenterLight * endCenterCol * endCenterNoiseIntensity * 5.0 * enderDragonDead; #else enderDragonDead = 1.0; #endif int oldSubsurfaceMode = subsurfaceMode; #if SSS_STRENGTH == 0 subsurfaceMode = 0; #endif #ifdef OVERWORLD float skyLightShadowMult = pow2(pow2(lightmapY2)); #else float skyLightShadowMult = 1.0; #endif #if defined CUSTOM_PBR || defined GENERATED_NORMALS float NPdotU = abs(dot(geoNormal, upVec)); #endif // Shadows #if defined OVERWORLD || defined END #ifdef GBUFFERS_WATER //NdotL = mix(NdotL, 1.0, 1.0 - color.a); #endif #ifdef CUSTOM_PBR float geoNdotL = dot(geoNormal, lightVec); float geoNdotLM = geoNdotL > 0.0 ? geoNdotL * 10.0 : geoNdotL; NdotL = min(geoNdotLM, NdotL); NdotL *= 1.0 - 0.7 * (1.0 - pow2(pow2(NdotUmax0))) * NPdotU; #endif #if SHADOW_QUALITY == -1 && defined GBUFFERS_TERRAIN if (subsurfaceMode == 1) { NdotU = 1.0; NdotUmax0 = 1.0; NdotL = dot(upVec, lightVec); } else if (subsurfaceMode == 2) { highlightMult *= NdotL; NdotL = mix(NdotL, 1.0, 0.35); } subsurfaceMode = 0; #endif float NdotLmax0 = max0(NdotL); float NdotLM = NdotLmax0 * 0.9999; #ifdef GBUFFERS_TEXTURED NdotLM = 1.0; #else #ifdef GBUFFERS_TERRAIN if (subsurfaceMode != 0) { #if defined CUSTOM_PBR && defined POM && POM_QUALITY >= 128 && POM_LIGHTING_MODE == 2 shadowMult *= max(pow2(pow2(dot(normalM, geoNormal))), sqrt2(NdotLmax0)); #endif NdotLM = 1.0; } #ifdef SIDE_SHADOWING else #endif #endif #ifdef SIDE_SHADOWING NdotLM = max0(NdotL + 0.4) * 0.714; #ifdef END NdotLM = sqrt3(NdotLM); #endif #endif #endif #if ENTITY_SHADOW == -1 && defined GBUFFERS_ENTITIES || ENTITY_SHADOW <= 1 && defined GBUFFERS_BLOCK lightColorM = mix(lightColorM * 0.75, ambientColorM, 0.5 * pow2(pow2(1.0 - NdotLM))); NdotLM = NdotLM * 0.75 + 0.25; #endif if (shadowMult.r > 0.00001) { #if SHADOW_QUALITY > -1 if (NdotLM > 0.0001) { vec3 shadowMultBeforeLighting = shadowMult; #if !defined DH_TERRAIN && !defined DH_WATER float shadowLength = shadowDistance * 0.9166667 - lViewPos; //consistent08JJ622 #else float shadowLength = 0.0; #endif if (shadowLength > 0.000001) { #if SHADOW_SMOOTHING == 4 || SHADOW_QUALITY == 0 float offset = 0.00098; #elif SHADOW_SMOOTHING == 3 float offset = 0.00075; #elif SHADOW_SMOOTHING == 2 float offset = 0.0005; #elif SHADOW_SMOOTHING == 1 float offset = 0.0003; #endif vec3 playerPosM = playerPos; vec3 centerPlayerPos = floor(playerPos + cameraPosition + worldGeoNormal * 0.01) - cameraPosition + 0.5; #if defined DO_PIXELATION_EFFECTS && defined PIXELATED_SHADOWS playerPosM = playerPosPixelated; offset *= 0.75; #endif // Fix light leaking in caves // #ifdef GBUFFERS_TERRAIN if (centerShadowBias || subsurfaceMode == 1) { #ifdef OVERWORLD playerPosM = mix(centerPlayerPos, playerPosM, 0.5 + 0.5 * lightmapYM); #endif } else { float centerFactor = max(glColor.a, lightmapYM); #if defined PERPENDICULAR_TWEAKS && SHADOW_QUALITY >= 2 && !defined DH_TERRAIN // Fake Variable Penumbra Shadows // Making centerFactor also work in daylight if AO gradient is facing towards sun if (geoNdotU > 0.99) { float dFdxGLCA = dFdx(glColor.a); float dFdyGLCA = dFdy(glColor.a); if (abs(dFdxGLCA) + abs(dFdyGLCA) > 0.00001) { vec3 aoGradView = dFdxGLCA * normalize(dFdx(playerPos.xyz)) + dFdyGLCA * normalize(dFdy(playerPos.xyz)); if (dot(normalize(aoGradView.xz), normalize(ViewToPlayer(lightVec).xz)) < 0.3 + 0.4 * dither) if (dot(lightVec, upVec) < 0.99999) centerFactor = sqrt1(max0(glColor.a - 0.55) / 0.45); } } #endif playerPosM = mix(playerPosM, centerPlayerPos, 0.2 * (1.0 - pow2(pow2(centerFactor)))); } #elif defined GBUFFERS_HAND playerPosM = mix(vec3(0.0), playerPosM, 0.2 + 0.8 * lightmapYM); #elif defined GBUFFERS_TEXTURED playerPosM = mix(centerPlayerPos, playerPosM + vec3(0.0, 0.02, 0.0), lightmapYM); #else playerPosM = mix(playerPosM, centerPlayerPos, 0.2 * (1.0 - lightmapYM)); #endif // Shadow bias without peter-panning // #ifndef GBUFFERS_TEXTURED #ifdef GBUFFERS_TERRAIN if (subsurfaceMode != 1) #endif { float distanceBias = pow(dot(playerPos, playerPos), 0.75); distanceBias = 0.12 + 0.0008 * distanceBias; vec3 bias = worldGeoNormal * distanceBias * (2.0 - 0.95 * NdotLmax0); // 0.95 fixes pink petals noon shadows #if defined GBUFFERS_TERRAIN && !defined DH_TERRAIN if (subsurfaceMode == 2) { bias *= vec3(0.0, 0.0, -0.5); bias.z += 0.25 * signMidCoordPos.x * NdotE; } #endif playerPosM += bias; } #endif vec3 shadowPos = GetShadowPos(playerPosM); bool leaves = false; #ifdef GBUFFERS_TERRAIN if (subsurfaceMode == 0) { #if defined PERPENDICULAR_TWEAKS && defined SIDE_SHADOWING offset *= 1.0 + pow2(absNdotN); #endif } else { float VdotL = dot(nViewPos, lightVec); float lightFactor = pow(max(VdotL, 0.0), 10.0) * float(isEyeInWater == 0); if (subsurfaceMode == 1) { offset = 0.0005235 * lightmapYM + 0.0009765; shadowPos.z -= max(NdotL * 0.0001, 0.0) * lightmapYM; subsurfaceHighlight = lightFactor * 0.8; #ifndef SHADOW_FILTERING shadowPos.z -= 0.0002; #endif } else if (subsurfaceMode == 2) { leaves = true; offset = 0.0005235 * lightmapYM + 0.0009765; shadowPos.z -= 0.000175 * lightmapYM; subsurfaceHighlight = lightFactor * 0.6; #ifndef SHADOW_FILTERING NdotLM = mix(NdotL, NdotLM, 0.5); #endif } else { } } #endif int shadowSampleBooster = int(subsurfaceMode > 0 && lViewPos < 10.0); #if SHADOW_QUALITY == 0 int shadowSamples = 0; // We don't use SampleTAAFilteredShadow on Shadow Quality 0 #elif SHADOW_QUALITY == 1 int shadowSamples = 1 + shadowSampleBooster; #elif SHADOW_QUALITY == 2 || SHADOW_QUALITY == 3 int shadowSamples = 2 + 2 * shadowSampleBooster; #elif SHADOW_QUALITY == 4 int shadowSamples = 4 + 4 * shadowSampleBooster; #elif SHADOW_QUALITY == 5 int shadowSamples = 8 + 8 * shadowSampleBooster; #endif shadowMult *= GetShadow(shadowPos, lightmap.y, offset, shadowSamples, leaves); } float shadowSmooth = 16.0; if (shadowLength < shadowSmooth) { float shadowMixer = max0(shadowLength / shadowSmooth); #ifdef GBUFFERS_TERRAIN if (subsurfaceMode != 0) { float shadowMixerM = pow2(shadowMixer); if (subsurfaceMode == 1) skyLightShadowMult *= mix(0.6 + 0.3 * pow2(noonFactor), 1.0, shadowMixerM); else skyLightShadowMult *= mix(NdotL * 0.4999 + 0.5, 1.0, shadowMixerM); subsurfaceHighlight *= shadowMixer; } #endif shadowMult = mix(vec3(skyLightShadowMult * shadowMultBeforeLighting), shadowMult, shadowMixer); } } #else shadowMult *= skyLightShadowMult; #endif #ifdef CLOUD_SHADOWS shadowMult *= GetCloudShadow(playerPos); #endif shadowMult *= max(NdotLM * shadowTime, 0.0); } #ifdef GBUFFERS_WATER else { // Low Quality Water shadowMult = vec3(pow2(lightmapY2) * max(NdotLM * shadowTime, 0.0)); } #endif #endif #ifdef END_FLASH_SHADOW_INTERNAL shadowMult = mix(vec3(1.0), (shadowMult) * 2.0, endFlashIntensity); #endif // Blocklight float lightmapXM; #if defined LIGHTMAP_CURVES && !defined GBUFFERS_TEXTURED if (!noSmoothLighting || oldSubsurfaceMode > 0 && !isLightSource) { float lx4 = pow2(pow2(lightmap.x)); float lx8 = pow2(lx4); float vsBrightFactor = 2.8 - 0.6 * vsBrightness + XLIGHT_CURVE; float transitionFactor = ((UPPER_LIGHTMAP_CURVE * 0.1 + 0.9) - 1.0) * mix(1.0, 10.0, float(int(max(0.0, UPPER_LIGHTMAP_CURVE - 0.01)))); float transitions = (pow2(lx8) * (10 - vsBrightness) * 2 + lx8 * (2.8 + XLIGHT_CURVE - vsBrightness) * 0.8 + lx4 * (2.8 + XLIGHT_CURVE - vsBrightness * 0.7)) * transitionFactor; float lightmapXMSteep = max(0.0, pow2(pow2(lightmap.x * lightmap.x)) * vsBrightFactor + transitions); float lightmapXMCalm = lightmap.x * (2.8 - XLIGHT_CURVE + 0.6 * vsBrightness) * LOWER_LIGHTMAP_CURVE; lightmapXM = pow(lightmapXMSteep + lightmapXMCalm, 2.25); } else { float xLightCurveM = XLIGHT_CURVE > 0.999 ? XLIGHT_CURVE : sqrt2(XLIGHT_CURVE); lightmapXM = pow(lightmap.x, 3.0 * xLightCurveM) * 10.0 * pow(lightmap.x, pow2(UPPER_LIGHTMAP_CURVE)) * UPPER_LIGHTMAP_CURVE * (UPPER_LIGHTMAP_CURVE * 0.7 + 0.3); } #else if (!noSmoothLighting) { float lightmapXMSteep = pow2(pow2(lightmap.x * lightmap.x)) * (2.8 - 0.6 * vsBrightness + XLIGHT_CURVE); float lightmapXMCalm = lightmap.x * (2.8 + 0.6 * vsBrightness - XLIGHT_CURVE); lightmapXM = pow(lightmapXMSteep + lightmapXMCalm, 2.25); } else { float xLightCurveM = XLIGHT_CURVE > 0.999 ? XLIGHT_CURVE : sqrt2(XLIGHT_CURVE); lightmapXM = pow(lightmap.x, 3.0 * xLightCurveM) * 10.0; } #endif float daylightFactor = lightmapYM * invRainFactor * sunVisibility; emission *= 1.0 - 0.25 * daylightFactor; // Less emission under direct skylight #ifdef GBUFFERS_TEXTURED lightmapXM *= 1.5 - 0.5 * daylightFactor; // Brighter lit particles #endif #if defined DIRECTIONAL_LIGHTMAP_NORMALS && (defined GBUFFERS_TERRAIN || defined GBUFFERS_WATER || defined GBUFFERS_BLOCK) if (oldLightmap.x > 0.035) { // very specific value, do not change float lightmapDir = lightmapXM; #ifdef USE_FINE_DERIVATIVES vec2 dFdBlock = vec2(dFdxFine(oldLightmap.x), dFdyFine(oldLightmap.x)); // Get higher precision derivatives when available #else vec2 dFdBlock = vec2(dFdx(oldLightmap.x), dFdy(oldLightmap.x)); #endif vec3 blockLightDir; if (length(dFdBlock) < 1e-6) { vec3 blockCenterPos = floor(playerPos + cameraPosition + 0.001 * worldGeoNormal) - cameraPosition + 0.5; // + 0.001 fixes percision issues blockLightDir = blockCenterPos - worldGeoNormal * dot(worldGeoNormal, blockCenterPos - playerPos) - playerPos; blockLightDir = mat3(gbufferModelView) * blockLightDir; } else { #ifdef USE_FINE_DERIVATIVES blockLightDir = dFdxFine(viewPos) * dFdBlock.x + dFdyFine(viewPos) * dFdBlock.y; // Get higher precision derivatives when available #else blockLightDir = dFdx(viewPos) * dFdBlock.x + dFdy(viewPos) * dFdBlock.y; #endif } float dotNormal = dot(normalize(blockLightDir), normalM); lightmapDir *= pow(dotNormal + 1.0, DIRECTIONAL_LIGHTMAP_NORMALS_BLOCK_STRENGTH_NEW + 0.25); lightmapXM = mix(lightmapXM, lightmapDir, 0.01 * max0(100.0 - lViewPos)); } #endif #if BLOCKLIGHT_FLICKERING > 0 vec2 flickerNoiseBlock = texture2DLod(noisetex, vec2(frameTimeCounter * 0.06), 0.0).rb; lightmapXM *= mix(1.0, min1(max(flickerNoiseBlock.r, flickerNoiseBlock.g) * 1.7), pow2(BLOCKLIGHT_FLICKERING * 0.1)); #endif #ifdef RANDOM_BLOCKLIGHT float RandR = texture2DLod(noisetex, 0.00016 * RANDOM_BLOCKLIGHT_SIZE * (playerPos.xz + cameraPosition.xz), 0.0).r * XLIGHT_R; float RandG = texture2DLod(noisetex, 0.00029 * RANDOM_BLOCKLIGHT_SIZE * (playerPos.xz + cameraPosition.xz), 0.0).r * XLIGHT_G; float RandB = texture2DLod(noisetex, 0.00034 * RANDOM_BLOCKLIGHT_SIZE * (playerPos.xz + cameraPosition.xz), 0.0).r * XLIGHT_B; blocklightCol = vec3(RandR, RandG, RandB) * 0.875; #endif vec3 blockLighting = lightmapXM * blocklightCol; #if COLORED_LIGHTING_INTERNAL > 0 // Prepare #if defined GBUFFERS_HAND vec3 voxelPos = SceneToVoxel(vec3(0.0)); #elif defined GBUFFERS_TEXTURED vec3 voxelPos = SceneToVoxel(playerPos); #else vec3 voxelPos = SceneToVoxel(playerPos); voxelPos = voxelPos + worldGeoNormal * 0.55; // should be close to 0.5 for ACT_CORNER_LEAK_FIX but 0.5 makes slabs flicker #endif vec3 specialLighting = vec3(0.0); vec4 lightVolume = vec4(0.0); if (CheckInsideVoxelVolume(voxelPos)) { vec3 voxelPosM = clamp01(voxelPos / vec3(voxelVolumeSize)); lightVolume = GetLightVolume(voxelPosM); lightVolume = sqrt(lightVolume); specialLighting = lightVolume.rgb; } // Add extra articial light for blocks that request it lightmapXM = max(lightmapXM, mix(lightmapXM, 10.0, lightVolume.a)); specialLighting *= 1.0 + 50.0 * lightVolume.a; purkinjeOverwrite += 17.0 * lightVolume.a; // Color Balance specialLighting = lightmapXM * 0.13 * DoLuminanceCorrection(specialLighting + blocklightCol * 0.05); // Add some extra non-contrasty detail AddSpecialLightDetail(specialLighting, color.rgb, emission); #if COLORED_LIGHT_SATURATION != 100 specialLighting = mix(blockLighting, specialLighting, COLORED_LIGHT_SATURATION * 0.01); #endif // Serve with distance fade vec3 absPlayerPosM = abs(playerPos); #if COLORED_LIGHTING_INTERNAL <= 512 absPlayerPosM.y *= 2.0; #elif COLORED_LIGHTING_INTERNAL == 768 absPlayerPosM.y *= 3.0; #elif COLORED_LIGHTING_INTERNAL == 1024 absPlayerPosM.y *= 4.0; #endif float maxPlayerPos = max(absPlayerPosM.x, max(absPlayerPosM.y, absPlayerPosM.z)); float blocklightDecider = pow2(min1(maxPlayerPos / effectiveACTdistance * 2.0)); //if (heldItemId != 40000 || heldItemId2 == 40000) // Hold spider eye to see vanilla lighting blockLighting = mix(specialLighting, blockLighting, blocklightDecider); //if (heldItemId2 == 40000 && heldItemId != 40000) blockLighting = lightVolume.rgb; // Hold spider eye to see light volume #endif #if defined END && END_CENTER_LIGHTING > 0 && MC_VERSION >= 10900 && defined END_CENTER_LIGHTING_AFFECT_BLOCKLIGHT && (defined GBUFFERS_BLOCK || defined GBUFFERS_ENTITIES || defined GBUFFERS_TERRAIN || defined GBUFFERS_HAND) blockLighting = mix(blockLighting, lightmapXM * clamp01(saturateColors(endCenterCol, 1.3)), clamp01(endCenterLightDist) * enderDragonDead); #endif #if HELD_LIGHTING_MODE >= 1 #if !defined DO_PIXELATION_EFFECTS || !defined PIXELATED_BLOCKLIGHT vec3 playerPosForHeldLighting = playerPos; #else vec3 playerPosForHeldLighting = playerPosPixelated; #endif vec3 heldLighting = GetHeldLighting(playerPosForHeldLighting, color.rgb, emission, worldGeoNormal, normalM, viewPos); #ifdef GBUFFERS_HAND blockLighting *= 0.5; heldLighting *= 2.0; #endif #endif vec3 minLighting = GetMinimumLighting(lightmapYM, playerPos); vec3 shadowLightMult = shadowMult; float shadowMultFloat = min1(GetLuminance(shadowMult)); // Lighting Tweaks #ifdef OVERWORLD ambientMult = mix(lightmapYM, pow2(lightmapYM) * lightmapYM, rainFactor); #if SHADOW_QUALITY == -1 float tweakFactor = 1.0 + 0.6 * (1.0 - pow2(pow2(pow2(noonFactor)))); lightColorM /= tweakFactor; ambientMult *= mix(tweakFactor, 1.0, 0.5 * NdotUmax0); #endif #if AMBIENT_MULT != 100 #if AMBIENT_MULT < 100 #define AMBIENT_MULT_M (AMBIENT_MULT - 100) * 0.006 vec3 shadowMultP = shadowMult / (0.1 + 0.9 * sqrt2(max0(NdotLM))); ambientMult *= 1.0 + pow2(pow2(max0(1.0 - dot(shadowMultP, shadowMultP)))) * AMBIENT_MULT_M * (0.5 + 0.2 * sunFactor + 0.8 * noonFactor) * (1.0 - rainFactor * 0.5); #else #define AMBIENT_MULT_M (AMBIENT_MULT - 100) * 0.002 shadowLightMult = mix(shadowLightMult, vec3(1.0), AMBIENT_MULT_M); lightColorM = mix(lightColorM, GetLuminance(lightColorM) * DoLuminanceCorrection(ambientColorM), (1.0 - shadowMultFloat) * AMBIENT_MULT_M); #endif #endif if (isEyeInWater != 1) { float lxFactor = (sunVisibility2 * 0.4 + (0.6 - 0.6 * pow2(invNoonFactor))) * (6.0 - 5.0 * rainFactor); lxFactor *= lightmapY2 + lightmapY2 * 2.0 * pow2(shadowMultFloat); lxFactor = max0(lxFactor - emission * 1000000.0); blockLighting *= pow(lightmapXM / 60.0 + 0.001, 0.09 * lxFactor); // Less light in the distance / more light closer to the camera during rain or night to simulate thicker fog float rainLF = 0.1 * rainFactor; float lightFogTweaks = 1.0 + max0(96.0 - lViewPos) * (0.002 * (1.0 - sunVisibility2) + 0.0104 * rainLF) - rainLF; ambientMult *= lightFogTweaks; lightColorM *= lightFogTweaks; } #endif #ifdef END #if defined IS_IRIS && MC_VERSION >= 12109 vec3 worldEndFlashPosition = mat3(gbufferModelViewInverse) * endFlashPosition; worldEndFlashPosition = normalize(vec3(worldEndFlashPosition.x, 0.0, worldEndFlashPosition.z)); float endFlashDirectionFactor = max0(1.0 + dot(worldGeoNormal, normalize(worldEndFlashPosition))) * 0.5; endFlashDirectionFactor = pow2(pow2(endFlashDirectionFactor)); vec3 endFlashColor = (endOrangeCol + 0.5 * endLightColor) * endFlashIntensity * pow2(lightmapYM); ambientColorM += endFlashColor * (0.2 * endFlashDirectionFactor); #endif #endif #ifdef GBUFFERS_HAND ambientMult *= 1.3; // To improve held map visibility #endif // Directional Shading float directionShade = 1.0; #ifdef DIRECTIONAL_SHADING if (!noDirectionalShading) { float absNdotE2 = pow2(absNdotE); #if !defined NETHER float NdotUM = 0.75 + NdotU * 0.25; #else float NdotUM = 0.75 + abs(NdotU + 0.5) * 0.16666; #endif float NdotNM = 1.0 + 0.075 * absNdotN; float NdotEM = 1.0 - 0.1 * absNdotE2; directionShade = NdotUM * NdotEM * NdotNM; #ifdef OVERWORLD lightColorM *= 1.0 + absNdotE2 * 0.75; #elif defined NETHER directionShade *= directionShade; ambientColorM += lavaLightColor * pow2(absNdotN * 0.5 + max0(-NdotU)) * (0.7 + 0.35 * vsBrightness); #endif #if defined CUSTOM_PBR || defined GENERATED_NORMALS float cpbrAmbFactor = NdotN * NPdotU; cpbrAmbFactor = 1.0 - 0.3 * cpbrAmbFactor; ambientColorM *= cpbrAmbFactor; minLighting *= cpbrAmbFactor; #endif #if defined OVERWORLD && defined PERPENDICULAR_TWEAKS && defined SIDE_SHADOWING // Fake bounced light ambientColorM = mix(ambientColorM, lightColorM, (0.05 + 0.03 * subsurfaceMode) * absNdotN * lightmapY2); // Get a bit more natural looking lighting during noon lightColorM *= 1.0 + max0(1.0 - subsurfaceMode) * pow(noonFactor, 20.0) * (pow2(absNdotN) * 0.8 - absNdotE2 * 0.2); #endif } #endif // Scene Lighting Stuff vec3 sceneLighting = lightColorM * shadowLightMult + ambientColorM * ambientMult; float dotSceneLighting = dot(sceneLighting, sceneLighting); #if HELD_LIGHTING_MODE >= 1 blockLighting = sqrt(pow2(blockLighting) + heldLighting); #endif blockLighting *= XLIGHT_I; #ifdef BLOCKLIGHT_CAUSTICS if (isEyeInWater == 1) { vec3 worldPos = playerPos + cameraPosition; #if defined DO_PIXELATION_EFFECTS && defined PIXELATED_SHADOWS worldPos = playerPosPixelated + cameraPosition; #endif float causticTime = frameTimeCounter * 0.045; mat2 rot = rotate(causticTime * 35); vec3 absNormal = abs(worldGeoNormal); vec2 basePos = absNormal.y > max(absNormal.x, absNormal.z) ? worldPos.xz : absNormal.x > absNormal.z ? worldPos.yz : worldPos.xy; basePos *= 1.35; // Opposing directional movement for the two layers vec2 causticWind1 = vec2(causticTime * 0.3, causticTime * 0.15); vec2 causticWind2 = vec2(-causticTime * 0.17, -causticTime * 0.22); vec2 cPos1 = basePos * 0.10 + causticWind1; vec2 cPos2 = basePos * 0.05 + causticWind2; float gradientNoise = fract(52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y)); #ifdef TAA gradientNoise = fract(gradientNoise + 0.618034 * mod(float(frameCounter), 3600.0)); #endif float caustic = 0.0; int causticSamples = 4; for (int i = 0; i < causticSamples; i++) { vec2 offset1 = causticOffsetDist(gradientNoise + float(i), causticSamples); vec2 offset2 = causticOffsetDist(gradientNoise + float(i) + 0.5, causticSamples); offset1 = rot * offset1; offset2 = rot * offset2; vec4 sample1a = texture2D(gaux4, cPos1 + offset1); vec4 sample1b = texture2D(gaux4, cPos1 - offset1); vec4 sample2a = texture2D(gaux4, cPos2 + offset2); vec4 sample2b = texture2D(gaux4, cPos2 - offset2); float caustic1 = dot(sample1a.rg - sample1b.rg, vec2(6.0)); float caustic2 = dot(sample2a.rg - sample2b.rg, vec2(6.0)); caustic += caustic1 + caustic2; } caustic /= causticSamples; caustic = clamp(caustic, -0.15, 2.0) * 0.52 + 0.587; blockLighting *= caustic * WATER_CAUSTIC_STRENGTH; } #endif #ifdef LIGHT_COLOR_MULTS sceneLighting *= lightColorMult; #endif #ifdef MOON_PHASE_INF_LIGHT sceneLighting *= moonPhaseInfluence; #endif // Vanilla Ambient Occlusion float vanillaAO = 1.0; #if VANILLAAO_I > 0 vanillaAO = glColor.a; #if defined DO_PIXELATION_EFFECTS && defined PIXELATED_AO vanillaAO = TexelSnap(vanillaAO, pixelationOffset); #endif if (subsurfaceMode != 0) vanillaAO = mix(min1(vanillaAO * 1.15), 1.0, shadowMultFloat); else if (!noVanillaAO) { #ifdef GBUFFERS_TERRAIN vanillaAO = min1(vanillaAO + 0.08); #ifdef OVERWORLD vanillaAO = pow( pow1_5(vanillaAO), 1.0 + dotSceneLighting * 0.02 + NdotUmax0 * (0.15 + 0.25 * pow2(noonFactor * pow2(lightmapY2))) ); #elif defined NETHER vanillaAO = pow( pow1_5(vanillaAO), 1.0 + NdotUmax0 * 0.5 ); #else vanillaAO = pow( vanillaAO, 0.75 + NdotUmax0 * 0.25 ); #endif #endif vanillaAO = vanillaAO * 0.9 + 0.1; #if VANILLAAO_I != 100 #define VANILLAAO_IM VANILLAAO_I * 0.01 vanillaAO = pow(vanillaAO, VANILLAAO_IM); #endif } #endif #ifdef RAIN_ATMOSPHERE vanillaAO += lightningAdd.y * 0.1 * (-vanillaAO + 1); #endif // Light Highlight vec3 lightHighlight = vec3(0.0); #ifdef LIGHT_HIGHLIGHT float specularHighlight = GGX(normalM, nViewPos, lightVec, NdotLmax0, smoothnessG); specularHighlight *= highlightMult; lightHighlight = isEyeInWater != 1 ? shadowMult : pow(shadowMult, vec3(0.25)) * 0.35; lightHighlight *= (subsurfaceHighlight * subsurfaceColor + specularHighlight) * highlightColor; #ifdef LIGHT_COLOR_MULTS lightHighlight *= lightColorMult; #endif #ifdef MOON_PHASE_INF_REFLECTION lightHighlight *= pow2(moonPhaseInfluence); #endif #if BLOOD_MOON > 0 lightHighlight *= mix(vec3(1.0), vec3(1.0, 0.1294, 0.1294), getBloodMoon(sunVisibility)); #endif #endif // Mix Colors vec3 finalDiffuse = pow2(directionShade * vanillaAO) * (blockLighting + pow2(sceneLighting) + minLighting) + pow2(emission); finalDiffuse = sqrt(max(finalDiffuse, vec3(0.0))); // sqrt() for a bit more realistic light mix, max() to prevent NaNs // Apply Lighting color.rgb *= finalDiffuse; color.rgb += lightHighlight; color.rgb *= pow2(1.0 - darknessLightFactor); }