574 lines
No EOL
24 KiB
GLSL
574 lines
No EOL
24 KiB
GLSL
//Lighting Includes//
|
|
#include "/lib/colors/lightAndAmbientColors.glsl"
|
|
#include "/lib/lighting/ggx.glsl"
|
|
|
|
#if SHADOW_QUALITY > -1 && (defined OVERWORLD || defined END)
|
|
#include "/lib/lighting/shadowSampling.glsl"
|
|
#endif
|
|
|
|
#if defined CLOUDS_REIMAGINED && defined CLOUD_SHADOWS
|
|
#include "/lib/atmospherics/clouds/cloudCoord.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 > 0
|
|
#include "/lib/misc/voxelization.glsl"
|
|
#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,
|
|
vec3 worldGeoNormal, vec2 lightmap, bool noSmoothLighting, bool noDirectionalShading, bool noVanillaAO,
|
|
bool centerShadowBias, int subsurfaceMode, float smoothnessG, float highlightMult, float emission) {
|
|
float lightmapY2 = pow2(lightmap.y);
|
|
float lightmapYM = smoothstep1(lightmap.y);
|
|
float subsurfaceHighlight = 0.0;
|
|
float ambientMult = 1.0;
|
|
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
|
|
|
|
#ifdef OVERWORLD
|
|
float skyLightShadowMult = pow2(pow2(lightmapY2));
|
|
#else
|
|
float skyLightShadowMult = 1.0;
|
|
#endif
|
|
|
|
#if defined SIDE_SHADOWING || defined DIRECTIONAL_SHADING
|
|
float NdotN = dot(normalM, northVec);
|
|
float absNdotN = abs(NdotN);
|
|
#endif
|
|
|
|
#if defined CUSTOM_PBR || defined GENERATED_NORMALS
|
|
float NPdotU = abs(dot(geoNormal, upVec));
|
|
#endif
|
|
|
|
// Shadows
|
|
#if defined OVERWORLD || defined END
|
|
float NdotL = dot(normalM, lightVec);
|
|
#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 || defined DREAM_TWEAKED_LIGHTING
|
|
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;
|
|
|
|
#ifndef GBUFFERS_TEXTURED
|
|
#if defined 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
|
|
#else
|
|
NdotLM = 1.0;
|
|
#endif
|
|
|
|
#if ENTITY_SHADOWS_DEFINE == -1 && (defined GBUFFERS_ENTITIES || 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;
|
|
float shadowLength = min(shadowDistance, far) * 0.9166667 - lViewPos; //consistent08JJ622
|
|
|
|
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;
|
|
|
|
#if PIXEL_SHADOW > 0 && !defined GBUFFERS_HAND
|
|
playerPosM = floor((playerPosM + cameraPosition) * PIXEL_SHADOW + 0.001) / PIXEL_SHADOW - cameraPosition + 0.5 / PIXEL_SHADOW;
|
|
#endif
|
|
|
|
#ifndef GBUFFERS_TEXTURED
|
|
// Shadow bias without peter-panning
|
|
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
|
|
|
|
#ifdef GBUFFERS_TERRAIN
|
|
if (subsurfaceMode == 2) {
|
|
bias *= vec3(0.0, 0.0, -0.75);
|
|
} else if (subsurfaceMode == 1) {
|
|
bias = vec3(0.0);
|
|
centerShadowBias = true;
|
|
}
|
|
#endif
|
|
|
|
// Fix light leaking in caves
|
|
if (lightmapYM < 0.999) {
|
|
#ifdef GBUFFERS_HAND
|
|
playerPosM = mix(vec3(0.0), playerPosM, 0.2 + 0.8 * lightmapYM);
|
|
#else
|
|
if (centerShadowBias) {
|
|
#ifdef OVERWORLD
|
|
vec3 centerPos = floor(playerPosM + cameraPosition) - cameraPosition + 0.5;
|
|
playerPosM = mix(centerPos, playerPosM, 0.5 + 0.5 * lightmapYM);
|
|
#endif
|
|
} else {
|
|
vec3 edgeFactor = 0.2 * (0.5 - fract(playerPosM + cameraPosition + worldGeoNormal * 0.01));
|
|
|
|
#ifdef GBUFFERS_WATER
|
|
bias *= 0.7;
|
|
playerPosM += (1.0 - lightmapYM) * edgeFactor;
|
|
#endif
|
|
|
|
playerPosM += (1.0 - pow2(pow2(max(glColor.a, lightmapYM)))) * edgeFactor;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
playerPosM += bias;
|
|
#else
|
|
vec3 centerplayerPos = floor(playerPosM + cameraPosition) - cameraPosition + 0.5;
|
|
playerPosM = mix(centerplayerPos, playerPosM + vec3(0.0, 0.02, 0.0), lightmapYM);
|
|
#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.0010235 * 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
|
|
|
|
shadowMult *= GetShadow(shadowPos, lViewPos, lightmap.y, offset, 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
|
|
vec3 worldPos = playerPos + cameraPosition;
|
|
|
|
#ifdef CLOUDS_REIMAGINED
|
|
float EdotL = dot(eastVec, lightVec);
|
|
float EdotLM = tan(acos(EdotL));
|
|
|
|
#if SUN_ANGLE != 0
|
|
float NVdotLM = tan(acos(dot(northVec, lightVec)));
|
|
#endif
|
|
|
|
float distToCloudLayer1 = cloudAlt1i - worldPos.y;
|
|
vec3 cloudOffset1 = vec3(distToCloudLayer1 / EdotLM, 0.0, 0.0);
|
|
#if SUN_ANGLE != 0
|
|
cloudOffset1.z += distToCloudLayer1 / NVdotLM;
|
|
#endif
|
|
vec2 cloudPos1 = GetRoundedCloudCoord(ModifyTracePos(worldPos + cloudOffset1, cloudAlt1i).xz, 0.35);
|
|
float cloudSample = texture2D(gaux4, cloudPos1).b;
|
|
cloudSample *= clamp(distToCloudLayer1 * 0.1, 0.0, 1.0);
|
|
|
|
#ifdef DOUBLE_REIM_CLOUDS
|
|
float distToCloudLayer2 = cloudAlt2i - worldPos.y;
|
|
vec3 cloudOffset2 = vec3(distToCloudLayer2 / EdotLM, 0.0, 0.0);
|
|
#if SUN_ANGLE != 0
|
|
cloudOffset2.z += distToCloudLayer2 / NVdotLM;
|
|
#endif
|
|
vec2 cloudPos2 = GetRoundedCloudCoord(ModifyTracePos(worldPos + cloudOffset2, cloudAlt2i).xz, 0.35);
|
|
float cloudSample2 = texture2D(gaux4, cloudPos2).b;
|
|
cloudSample2 *= clamp(distToCloudLayer2 * 0.1, 0.0, 1.0);
|
|
|
|
cloudSample = max(cloudSample, cloudSample2);
|
|
#endif
|
|
|
|
cloudSample *= sqrt3(1.0 - abs(EdotL));
|
|
shadowMult *= 1.0 - 0.85 * cloudSample;
|
|
#else
|
|
vec2 csPos = worldPos.xz + worldPos.y * 0.25;
|
|
csPos.x += syncedTime;
|
|
csPos *= 0.000002 * CLOUD_UNBOUND_SIZE_MULT;
|
|
|
|
vec2 shadowoffsets[8] = vec2[8](
|
|
vec2( 0.0 , 1.0 ),
|
|
vec2( 0.7071, 0.7071),
|
|
vec2( 1.0 , 0.0 ),
|
|
vec2( 0.7071,-0.7071),
|
|
vec2( 0.0 ,-1.0 ),
|
|
vec2(-0.7071,-0.7071),
|
|
vec2(-1.0 , 0.0 ),
|
|
vec2(-0.7071, 0.7071));
|
|
float cloudSample = 0.0;
|
|
for (int i = 0; i < 8; i++) {
|
|
cloudSample += texture2D(noisetex, csPos + 0.005 * shadowoffsets[i]).b;
|
|
}
|
|
|
|
shadowMult *= smoothstep1(pow2(min1(cloudSample * 0.2)));
|
|
#endif
|
|
#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
|
|
|
|
// Blocklight
|
|
float lightmapXM;
|
|
if (!noSmoothLighting) {
|
|
float lightmapXMSteep = pow2(pow2(lightmap.x * lightmap.x)) * (3.8 - 0.6 * vsBrightness);
|
|
float lightmapXMCalm = (lightmap.x) * (1.8 + 0.6 * vsBrightness);
|
|
lightmapXM = pow(lightmapXMSteep + lightmapXMCalm, 2.25);
|
|
} else lightmapXM = pow2(lightmap.x) * lightmap.x * 10.0;
|
|
|
|
#if BLOCKLIGHT_FLICKERING > 0
|
|
vec2 flickerNoise = texture2D(noisetex, vec2(frameTimeCounter * 0.06)).rb;
|
|
lightmapXM *= mix(1.0, min1(max(flickerNoise.r, flickerNoise.g) * 1.7), pow2(BLOCKLIGHT_FLICKERING * 0.1));
|
|
#endif
|
|
|
|
vec3 blockLighting = lightmapXM * blocklightCol;
|
|
|
|
#if COLORED_LIGHTING > 0
|
|
// Prepare
|
|
#ifndef GBUFFERS_HAND
|
|
vec3 voxelPos = SceneToVoxel(playerPos);
|
|
vec3 voxelPosM = voxelPos + worldGeoNormal * 0.5;
|
|
voxelPosM = clamp01(voxelPosM / vec3(voxelVolumeSize));
|
|
#else
|
|
vec3 voxelPos = SceneToVoxel(vec3(0.0));
|
|
vec3 voxelPosM = clamp01(voxelPos / vec3(voxelVolumeSize));
|
|
#endif
|
|
|
|
vec3 specialLighting = vec3(0.0);
|
|
vec4 lightVolume = vec4(0.0);
|
|
if (CheckInsideVoxelVolume(voxelPos)) {
|
|
lightVolume = GetLightVolume(voxelPosM);
|
|
lightVolume = sqrt(lightVolume);
|
|
specialLighting = lightVolume.rgb;
|
|
}
|
|
|
|
// Add extra articial light for blocks that request it
|
|
lightmapXM = mix(lightmapXM, 10.0, lightVolume.a);
|
|
specialLighting *= 1.0 + 50.0 * lightVolume.a;
|
|
|
|
// Color Balance
|
|
specialLighting = lightmapXM * 0.13 * DoLuminanceCorrection(specialLighting + blocklightCol * 0.05);
|
|
|
|
// Add some extra non-contrasty detail
|
|
vec3 specialLightingM = max(specialLighting, vec3(0.0));
|
|
specialLightingM /= (0.2 + 0.8 * GetLuminance(specialLightingM));
|
|
specialLightingM *= (1.0 / (1.0 + emission)) * 0.22;
|
|
specialLighting *= 0.9;
|
|
specialLighting += pow2(specialLightingM / (color.rgb + 0.1));
|
|
|
|
// Serve with distance fade
|
|
vec3 absPlayerPos = abs(playerPos);
|
|
float maxPlayerPos = max(absPlayerPos.x, max(absPlayerPos.y * 2.0, absPlayerPos.z));
|
|
float blocklightDecider = pow2(min1(maxPlayerPos / effectiveACLdistance * 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 HELD_LIGHTING_MODE >= 1
|
|
float heldLight = heldBlockLightValue; float heldLight2 = heldBlockLightValue2;
|
|
#if COLORED_LIGHTING == 0
|
|
vec3 heldLightCol = blocklightCol; vec3 heldLightCol2 = blocklightCol;
|
|
|
|
if (heldItemId == 45032) heldLight = 15; if (heldItemId2 == 45032) heldLight2 = 15; // Lava Bucket
|
|
#else
|
|
vec3 heldLightCol = GetSpecialBlocklightColor(heldItemId - 44000).rgb;
|
|
vec3 heldLightCol2 = GetSpecialBlocklightColor(heldItemId2 - 44000).rgb;
|
|
|
|
if (heldItemId == 45032) { heldLightCol = lavaSpecialLightColor; heldLight = 15; } // Lava Bucket
|
|
if (heldItemId2 == 45032) { heldLightCol2 = lavaSpecialLightColor; heldLight2 = 15; }
|
|
#endif
|
|
|
|
vec3 playerPosLightM = playerPos + relativeEyePosition;
|
|
playerPosLightM.y += 0.7;
|
|
float lViewPosL = length(playerPosLightM) + 6.0;
|
|
#if HELD_LIGHTING_MODE == 1
|
|
lViewPosL *= 1.5;
|
|
#endif
|
|
|
|
heldLight = pow2(pow2(heldLight * 0.47 / lViewPosL));
|
|
heldLight2 = pow2(pow2(heldLight2 * 0.47 / lViewPosL));
|
|
|
|
vec3 heldLighting = pow2(heldLight * DoLuminanceCorrection(heldLightCol + 0.001))
|
|
+ pow2(heldLight2 * DoLuminanceCorrection(heldLightCol2 + 0.001));
|
|
|
|
#ifdef GBUFFERS_HAND
|
|
blockLighting *= 0.5;
|
|
heldLighting *= 2.0;
|
|
#endif
|
|
#endif
|
|
|
|
// Minimum Light
|
|
#if !defined END && MINIMUM_LIGHT_MODE > 0
|
|
#if MINIMUM_LIGHT_MODE == 1
|
|
vec3 minLighting = vec3(0.0038);
|
|
#elif MINIMUM_LIGHT_MODE == 2
|
|
vec3 minLighting = vec3(0.005625 + vsBrightness * 0.043);
|
|
#elif MINIMUM_LIGHT_MODE == 3
|
|
vec3 minLighting = vec3(0.0625);
|
|
#elif MINIMUM_LIGHT_MODE >= 4
|
|
vec3 minLighting = vec3(0.07 * pow2(MINIMUM_LIGHT_MODE - 2.5));
|
|
#endif
|
|
minLighting *= vec3(0.45, 0.475, 0.6);
|
|
minLighting *= 1.0 - lightmapYM;
|
|
#else
|
|
vec3 minLighting = vec3(0.0);
|
|
#endif
|
|
|
|
minLighting += nightVision * vec3(0.5, 0.5, 0.75);
|
|
|
|
// 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
|
|
#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);
|
|
#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(shadowMult.r);
|
|
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 GBUFFERS_HAND
|
|
ambientMult *= 1.3; // To improve held map visibility
|
|
#endif
|
|
|
|
// Directional Shading
|
|
float directionShade = 1.0;
|
|
#ifdef DIRECTIONAL_SHADING
|
|
if (!noDirectionalShading) {
|
|
float NdotE = dot(normalM, eastVec);
|
|
float absNdotE = abs(NdotE);
|
|
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) - absNdotE2 * 0.1);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef DREAM_TWEAKED_LIGHTING
|
|
ambientColorM = mix(ambientColorM, lightColorM, 0.25) * 1.5;
|
|
lightColorM = lightColorM * 0.3;
|
|
#endif
|
|
|
|
// Scene Lighting Stuff
|
|
vec3 sceneLighting = lightColorM * shadowMult + ambientColorM * ambientMult;
|
|
float dotSceneLighting = dot(sceneLighting, sceneLighting);
|
|
|
|
#if HELD_LIGHTING_MODE >= 1
|
|
blockLighting = sqrt(pow2(blockLighting) + heldLighting);
|
|
#endif
|
|
|
|
blockLighting *= XLIGHT_I;
|
|
|
|
#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
|
|
if (subsurfaceMode != 0) vanillaAO = min1(glColor.a * 1.15);
|
|
else if (!noVanillaAO) {
|
|
#ifdef GBUFFERS_TERRAIN
|
|
vanillaAO = min1(glColor.a + 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
|
|
#else
|
|
vanillaAO = glColor.a;
|
|
#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
|
|
|
|
// 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 + specularHighlight) * highlightColor;
|
|
|
|
#ifdef LIGHT_COLOR_MULTS
|
|
lightHighlight *= lightColorMult;
|
|
#endif
|
|
#ifdef MOON_PHASE_INF_REFLECTION
|
|
lightHighlight *= pow2(moonPhaseInfluence);
|
|
#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);
|
|
} |