feat: initial commit
This commit is contained in:
+267
@@ -0,0 +1,267 @@
|
||||
#if !defined AURORA_BOREALIS_GLSL
|
||||
#define AURORA_BOREALIS_GLSL
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
#include "/lib/colors/colorMultipliers.glsl"
|
||||
#endif
|
||||
#include "/lib/util/colorConversion.glsl"
|
||||
#define AURORA_CONDITION 3 //[-1 0 1 2 3 4]
|
||||
|
||||
#define AURORA_COLOR_PRESET 0 //[-1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] // 0 is manual and default, 1 is daily, 2 is monthly and 3 is one color preset same with all numbers after
|
||||
|
||||
#define AURORA_UP_R 112 //[0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 255]
|
||||
#define AURORA_UP_G 36 //[0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 255]
|
||||
#define AURORA_UP_B 192 //[0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 255]
|
||||
#define AURORA_UP_I 33 //[0 3 5 8 10 13 15 18 20 23 25 28 30 33 35 38 40 43 45 48 50 53 55 58 60 63 65 68 70 73 75 78 80 83 85 88 90 93 95 98 100]
|
||||
|
||||
#define AURORA_DOWN_R 96 //[0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 255]
|
||||
#define AURORA_DOWN_G 255 //[0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 255]
|
||||
#define AURORA_DOWN_B 192 //[0 4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 255]
|
||||
#define AURORA_DOWN_I 33 //[0 3 5 8 10 13 15 18 20 23 25 28 30 33 35 38 40 43 45 48 50 53 55 58 60 63 65 68 70 73 75 78 80 83 85 88 90 93 95 98 100]
|
||||
|
||||
#define AURORA_SIZE 1.00 //[0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 2.05 2.10 2.15 2.20 2.25 2.30 2.35 2.40 2.45 2.50 2.55 2.60 2.65 2.70 2.75 2.80 2.85 2.90 2.95 3.00]
|
||||
#define AURORA_DRAW_DISTANCE 0.65 //[0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00]
|
||||
|
||||
#define RANDOM_AURORA 0 //[0 1 2 3 4 5 6 7 8 9]
|
||||
|
||||
//#define RGB_AURORA
|
||||
|
||||
#define AURORA_CLOUD_INFLUENCE_INTENSITY 1.00 //[0.00 0.25 0.50 0.75 1.00 1.25 1.50 1.75 2.00 2.50 3.00]
|
||||
#define AURORA_TERRAIN_INFLUENCE_INTENSITY 1.00 //[0.00 0.25 0.50 0.75 1.00 1.25 1.50]
|
||||
|
||||
#define AURORA_NOISE_SCALE 1.00 //[0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 2.05 2.10 2.15 2.20 2.25 2.30 2.35 2.40 2.45 2.50 2.55 2.60 2.65 2.70 2.75 2.80 2.85 2.90 2.95 3.00 3.05 3.10 3.15 3.20 3.25 3.30 3.35 3.40 3.45 3.50 3.55 3.60 3.65 3.70 3.75 3.80 3.85 3.90 3.95 4.00 4.05 4.10 4.15 4.20 4.25 4.30 4.35 4.40 4.45 4.50 4.55 4.60 4.65 4.70 4.75 4.80 4.85 4.90 4.95 5.00]
|
||||
#define AURORA_PATTERN_WARP 0 //[0 1 2 3 4 5 6 7 8 9 10]
|
||||
#define AURORA_SATURATION 10 //[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20]
|
||||
#define AURORA_COLOR_MIX_POWER 2.0 //[0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0]
|
||||
|
||||
float GetAuroraVisibility(in float VdotU, float VdotUAmount) {
|
||||
float visibility = sqrt1(clamp01(mix(1.0, VdotU, VdotUAmount) * (AURORA_DRAW_DISTANCE * 1.125 + 0.75) - 0.225)) - sunVisibility - maxBlindnessDarkness;
|
||||
|
||||
#ifdef CLEAR_SKY_WHEN_RAINING
|
||||
visibility -= rainFactor * 0.5;
|
||||
#else
|
||||
visibility -= rainFactor;
|
||||
#endif
|
||||
|
||||
visibility *= 1.0 - VdotU * 0.9 * VdotUAmount;
|
||||
|
||||
#if AURORA_CONDITION == 1 || AURORA_CONDITION == 3
|
||||
visibility -= moonPhase;
|
||||
#endif
|
||||
#if AURORA_CONDITION == 2 || AURORA_CONDITION == 3
|
||||
visibility *= inSnowy;
|
||||
#endif
|
||||
#if AURORA_CONDITION == 4
|
||||
visibility = max(visibility * inSnowy, visibility - moonPhase);
|
||||
#endif
|
||||
#if AURORA_CONDITION == -1 // Always except new moon
|
||||
visibility *= clamp01(max(moonPhase, 1) % 4);
|
||||
#endif
|
||||
|
||||
#if RANDOM_AURORA > 0
|
||||
float randomValue = hash11(float(worldDay));
|
||||
if (randomValue > RANDOM_AURORA * 0.1) {
|
||||
visibility = -1.0; // Disable aurora this day
|
||||
}
|
||||
#endif
|
||||
|
||||
return visibility;
|
||||
}
|
||||
|
||||
vec3 auroraUpA[] = vec3[](
|
||||
vec3(112.0, 36.0, 192.0), // [1] [2] Complementary
|
||||
vec3(112.0, 80.0, 255.0), // [3] Legacy Complementary (v4)
|
||||
vec3(168.0, 36.0, 88.0), // [4] permafrost
|
||||
vec3(255.0, 68.0, 124.0), // [5] Blossoming Lights (Pink)
|
||||
vec3(72.0, 96.0, 192.0), // [6] Nebula
|
||||
vec3(24.0, 255.0, 140.0), // [7] Celestial Dance
|
||||
vec3(255.0, 220.0, 255.0), // [8] Green Flash
|
||||
vec3(64.0, 255.0, 255.0), // [9] Ethereal Lights
|
||||
vec3(0.0, 20.0, 60.0), // [10] Glacial Blessing
|
||||
vec3(132.0, 0.0, 200.0), // [11] Mythical Lights
|
||||
vec3(120.0, 212.0, 56.0), // [12] watermelon
|
||||
vec3(0.0, 255.0, 255.0), // [13] blood bath
|
||||
vec3(255.0, 80.0, 112.0) // [14] Ghost
|
||||
);
|
||||
vec3 auroraDownA[] = vec3[](
|
||||
vec3(96.0, 255.0, 192.0), // [1] [2] Complementary
|
||||
vec3(80.0, 255.0, 180.0), // [3] Legacy Complementary (v4)
|
||||
vec3(60.0, 184.0, 152.0), // [4] permafrost
|
||||
vec3(160.0, 96.0, 255.0), // [5] Blossoming Lights (Pink)
|
||||
vec3(172.0, 44.0, 88.0), // [6] Nebula
|
||||
vec3(108.0, 72.0, 255.0), // [7] Celestial Dance
|
||||
vec3(68.0, 255.0, 72.0), // [8] Green Flash
|
||||
vec3(128.0, 64.0, 128.0), // [9] Ethereal Lights
|
||||
vec3(0.0, 24.0, 36.0), // [10] Glacial Blessing
|
||||
vec3(56.0, 168.0, 255.0), // [11] Mythical Lights
|
||||
vec3(176.0, 88.0, 72.0), // [12] watermelon
|
||||
vec3(180.0, 0.0, 0.0), // [13] blood bath
|
||||
vec3(80.0, 255.0, 180.0) // [14] Ghost
|
||||
);
|
||||
|
||||
vec2 warpAuroraCoords(vec2 coord, float warpAmount) {
|
||||
float angle = texture2D(noisetex, coord * 0.5).r * 6.28318 * warpAmount;
|
||||
float strength = texture2D(noisetex, coord * 0.7 + 0.5).r * warpAmount;
|
||||
vec2 offset = vec2(cos(angle), sin(angle)) * strength;
|
||||
return coord + offset;
|
||||
}
|
||||
|
||||
void GetAuroraColor(in vec2 wpos, out vec3 auroraUp, out vec3 auroraDown) {
|
||||
#ifdef RGB_AURORA
|
||||
auroraUp = getRainbowColor(wpos, 0.06);
|
||||
auroraDown = getRainbowColor(wpos, 0.05);
|
||||
#elif AURORA_COLOR_PRESET == 0
|
||||
auroraUp = vec3(AURORA_UP_R, AURORA_UP_G, AURORA_UP_B);
|
||||
auroraDown = vec3(AURORA_DOWN_R, AURORA_DOWN_G, AURORA_DOWN_B);
|
||||
#elif AURORA_COLOR_PRESET == -1
|
||||
float randomValue = hash11(float(worldDay));
|
||||
randomValue = pow(randomValue, 0.7); // Bias towards higher values (more transitions)
|
||||
float transitionsPerNight = min(randomValue * 2.0, 1.75);
|
||||
float idx, frac = modf(nightFactor * transitionsPerNight, idx);
|
||||
|
||||
int dayOffset = worldDay % auroraUpA.length();
|
||||
|
||||
int colorsCount = auroraUpA.length();
|
||||
int i0 = (int(idx) + dayOffset) % colorsCount;
|
||||
int i1 = (i0 + 1) % colorsCount;
|
||||
|
||||
// Interpolate in OKLab color space for perceptually uniform transitions
|
||||
vec3 oklabUp0 = rgb2oklab(auroraUpA[i0] / 255.0);
|
||||
vec3 oklabUp1 = rgb2oklab(auroraUpA[i1] / 255.0);
|
||||
vec3 oklabDown0 = rgb2oklab(auroraDownA[i0] / 255.0);
|
||||
vec3 oklabDown1 = rgb2oklab(auroraDownA[i1] / 255.0);
|
||||
|
||||
auroraUp = oklab2rgb(mix(oklabUp0, oklabUp1, frac)) * 255.0;
|
||||
auroraDown = oklab2rgb(mix(oklabDown0, oklabDown1, frac)) * 255.0;
|
||||
#else
|
||||
#if AURORA_COLOR_PRESET == 1
|
||||
int p = worldDay % auroraUpA.length();
|
||||
#elif AURORA_COLOR_PRESET == 2
|
||||
int p = worldDay % (auroraUpA.length() * 8) / 8;
|
||||
#else
|
||||
const int p = AURORA_COLOR_PRESET - 2;
|
||||
#endif
|
||||
|
||||
auroraUp = auroraUpA[p];
|
||||
auroraDown = auroraDownA[p];
|
||||
#endif
|
||||
auroraUp = max(auroraUp, vec3(0.001));
|
||||
auroraDown = max(auroraDown, vec3(0.001));
|
||||
|
||||
auroraUp *= (AURORA_UP_I * 0.093 + 3.1) / GetLuminance(auroraUp);
|
||||
auroraDown *= (AURORA_DOWN_I * 0.245 + 8.15) / GetLuminance(auroraDown);
|
||||
|
||||
#if AURORA_SATURATION != 10
|
||||
auroraUp = rgb2hsv(auroraUp);
|
||||
auroraUp.g *= AURORA_SATURATION * 0.1;
|
||||
auroraUp = hsv2rgb(auroraUp);
|
||||
|
||||
auroraDown = rgb2hsv(auroraDown);
|
||||
auroraDown.g *= AURORA_SATURATION * 0.1;
|
||||
auroraDown = hsv2rgb(auroraDown);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 getAuroraAmbientColor(vec3 color, vec3 viewPos, float multiplier, float influence, float VdotUAmount) {
|
||||
float visibility = GetAuroraVisibility(0.5, VdotUAmount);
|
||||
if (visibility > 0) {
|
||||
vec3 wpos = (gbufferModelViewInverse * vec4(viewPos, 1.0)).xyz;
|
||||
wpos.xz /= (abs(wpos.y) + length(wpos.xz));
|
||||
|
||||
vec3 auroraUp, auroraDown;
|
||||
GetAuroraColor(wpos.xz, auroraUp, auroraDown);
|
||||
|
||||
vec3 auroraColor = mix(auroraUp, auroraDown, 0.8);
|
||||
#ifdef COMPOSITE1
|
||||
visibility *= influence;
|
||||
return mix(color, auroraColor, visibility);
|
||||
#endif
|
||||
auroraColor *= multiplier;
|
||||
visibility *= influence;
|
||||
#ifdef DEFERRED1
|
||||
return mix(color, saturateColors(auroraColor, 0.8) * visibility * 0.45, visibility);
|
||||
#endif
|
||||
float luminanceColor = GetLuminance(color);
|
||||
vec3 newColor = mix(color, mix(color, vec3(luminanceColor), 0.88), visibility);
|
||||
newColor *= mix(vec3(1.0), auroraColor * luminanceColor * 10.0, visibility);
|
||||
return clamp01(newColor);
|
||||
// return mix(color, color * auroraColor, visibility); // old, keep it for now
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
vec3 GetAuroraBorealis(vec3 viewPos, float VdotU, float dither) {
|
||||
float visibility = GetAuroraVisibility(VdotU, 1.0);
|
||||
|
||||
if (visibility > 0.0) {
|
||||
vec3 aurora = vec3(0.0);
|
||||
|
||||
vec3 wpos = mat3(gbufferModelViewInverse) * viewPos;
|
||||
wpos.xz /= wpos.y;
|
||||
vec2 cameraPositionM = cameraPosition.xz * 0.0075;
|
||||
cameraPositionM.x += syncedTime * 0.04;
|
||||
|
||||
#ifdef DEFERRED1
|
||||
int sampleCount = 25;
|
||||
int sampleCountP = sampleCount + 5;
|
||||
#else
|
||||
int sampleCount = 10;
|
||||
int sampleCountP = sampleCount + 10;
|
||||
#endif
|
||||
|
||||
float ditherM = dither + 5.0;
|
||||
float auroraAnimate = frameTimeCounter * 0.001;
|
||||
|
||||
vec3 auroraUp, auroraDown;
|
||||
GetAuroraColor(wpos.xz, auroraUp, auroraDown);
|
||||
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
float current = pow2((i + ditherM) / sampleCountP);
|
||||
|
||||
vec2 planePos = wpos.xz * (AURORA_SIZE * 0.8 + current) * 11.0 * AURORA_NOISE_SCALE + cameraPositionM;
|
||||
|
||||
#if AURORA_STYLE == 1
|
||||
planePos = floor(planePos) * 0.0007;
|
||||
|
||||
#if AURORA_PATTERN_WARP > 0
|
||||
planePos = warpAuroraCoords(planePos, AURORA_PATTERN_WARP * 0.0057);
|
||||
#endif
|
||||
|
||||
float noise = texture2DLod(noisetex, planePos, 0.0).b;
|
||||
noise = pow2(pow2(pow2(pow2(1.0 - 2.0 * abs(noise - 0.5)))));
|
||||
|
||||
noise *= pow1_5(texture2DLod(noisetex, planePos * 100.0 + auroraAnimate, 0.0).b);
|
||||
#else
|
||||
planePos *= 0.0007;
|
||||
|
||||
#if AURORA_PATTERN_WARP > 0
|
||||
planePos = warpAuroraCoords(planePos, AURORA_PATTERN_WARP * 0.0082);
|
||||
#endif
|
||||
|
||||
float noise = texture2DLod(noisetex, planePos, 0.0).r;
|
||||
noise = pow2(pow2(pow2(pow2(1.0 - 2.0 * abs(noise - 0.5)))));
|
||||
|
||||
noise *= texture2DLod(noisetex, planePos * 3.0 + auroraAnimate, 0.0).b;
|
||||
noise *= texture2DLod(noisetex, planePos * 5.0 - auroraAnimate, 0.0).b;
|
||||
#endif
|
||||
|
||||
float currentM = 1.0 - current;
|
||||
|
||||
aurora += noise * currentM * mix(auroraUp, auroraDown, pow(pow2(currentM), AURORA_COLOR_MIX_POWER));
|
||||
}
|
||||
|
||||
#if AURORA_STYLE == 1
|
||||
aurora *= 1.3;
|
||||
#else
|
||||
aurora *= 1.8;
|
||||
#endif
|
||||
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
aurora *= sqrtAtmColorMult; // C72380KD - Reduced atmColorMult impact on some things
|
||||
#endif
|
||||
|
||||
return aurora * visibility / sampleCount;
|
||||
}
|
||||
|
||||
return vec3(0.0);
|
||||
}
|
||||
#endif
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
vec3 GetBedrockNoise(vec3 viewPos, float VdotU, float dither) {
|
||||
float eyeAltitude1 = eyeAltitude * 0.005;
|
||||
float visibility = clamp01(-VdotU * 1.875 - 0.225) * (1.0 - maxBlindnessDarkness);
|
||||
visibility *= 1.0 + VdotU * 0.75;
|
||||
|
||||
float distanceAboveBedrock = bedrockLevel - eyeAltitude;
|
||||
|
||||
float fadeStart = 180.0;
|
||||
float fadeWidth = 50.0;
|
||||
|
||||
float noiseHeight = 2.0 / (1.0 + exp(-(fadeStart - distanceAboveBedrock) / fadeWidth));
|
||||
|
||||
visibility *= -eyeAltitude1 * 3.0 + (bedrockLevel / 66.6) + 2.0;
|
||||
|
||||
if (visibility >= 0.0) {
|
||||
vec3 wpos = (gbufferModelViewInverse * vec4(viewPos, 1.0)).xyz;
|
||||
wpos /= (abs(wpos.y) + length(wpos.xz) * 0.5);
|
||||
|
||||
vec2 cameraPositionM = cameraPosition.xz * 0.0075;
|
||||
cameraPositionM.x += frameTimeCounter * 0.004;
|
||||
float VdotUM = 1.0 - VdotU * VdotU;
|
||||
|
||||
// Star calculation
|
||||
vec2 starCoord = noiseHeight * wpos.xz * 0.2 + cameraPositionM * 0.1;
|
||||
starCoord = floor(starCoord * 1024.0) / 1024.0;
|
||||
|
||||
float star = GetStarNoise(starCoord.xy) *
|
||||
GetStarNoise(starCoord.xy+0.1) *
|
||||
GetStarNoise(starCoord.xy+0.23);
|
||||
star = max0((star - 0.4) * 6.0);
|
||||
star *= star;
|
||||
|
||||
vec3 stars = star * vec3(0.1765, 0.1569, 0.1804) * (VdotUM + 0.3);
|
||||
|
||||
float wind = fract(frameTimeCounter * 0.0125);
|
||||
const int sampleCount = 1;
|
||||
const int sampleCountP = sampleCount + 5;
|
||||
float ditherM = dither + 5.0;
|
||||
|
||||
vec3 spots = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
float current = pow2((i + ditherM) / sampleCountP);
|
||||
float currentM = 1.0 - current;
|
||||
|
||||
vec2 planePos = wpos.xz * (0.5 + current) * noiseHeight;
|
||||
planePos = (planePos * 0.5 + cameraPositionM * 0.5) * 20.0;
|
||||
|
||||
float noiseSpots = texture2DLod(noisetex, floor(planePos) * 0.1, 0.0).g;
|
||||
vec3 noise = texture2DLod(noisetex, vec2(noiseSpots) + wind * 0.3, 0.0).b * vec3(0.3);
|
||||
|
||||
spots += noise * currentM * 6.0;
|
||||
}
|
||||
|
||||
#ifdef OVERWORLD
|
||||
spots = (spots - 0.5) * 1.5 + 0.5; // contrast
|
||||
#else
|
||||
spots = (spots - 0.5) * 3.5 + 0.5; // contrast
|
||||
#endif
|
||||
|
||||
spots += stars;
|
||||
|
||||
float clampedNoiseHeight = clamp01(noiseHeight);
|
||||
return spots * visibility / sampleCount * clampedNoiseHeight + clampedNoiseHeight - 1.0;
|
||||
}
|
||||
|
||||
return vec3(0.0);
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#ifndef INCLUDE_CLOUD_COORD
|
||||
#define INCLUDE_CLOUD_COORD
|
||||
|
||||
#include "/lib/shaderSettings/clouds.glsl"
|
||||
|
||||
const float cloudNarrowness = CLOUD_NARROWNESS;
|
||||
|
||||
// Thanks to SixthSurge
|
||||
vec2 GetRoundedCloudCoord(vec2 pos, float cloudRoundness) { // cloudRoundness is meant to be 0.125 for clouds and 0.35 for cloud shadows
|
||||
vec2 coord = pos.yx + 0.5;
|
||||
#ifdef ROTATE_REIMAGINED_CLOUDS_90_NEW
|
||||
coord = coord.yx;
|
||||
#endif
|
||||
vec2 signCoord = sign(coord);
|
||||
coord = abs(coord) + 1.0;
|
||||
vec2 i, f = modf(coord, i);
|
||||
f = smoothstep(0.5 - cloudRoundness, 0.5 + cloudRoundness, f);
|
||||
coord = i + f;
|
||||
return (coord - 0.5) * signCoord / 256.0;
|
||||
}
|
||||
|
||||
vec3 ModifyTracePos(vec3 tracePos, int cloudAltitude) {
|
||||
#if CLOUD_SPEED_MULT == 100
|
||||
float wind = syncedTime;
|
||||
#else
|
||||
#define CLOUD_SPEED_MULT_M CLOUD_SPEED_MULT * 0.01
|
||||
float wind = frameTimeCounter * CLOUD_SPEED_MULT_M;
|
||||
#endif
|
||||
|
||||
if (cloudAltitude != cloudAlt1i) {
|
||||
wind *= CLOUD_LAYER2_SPEED_MULT;
|
||||
}
|
||||
|
||||
#if CLOUD_DIRECTION == 1
|
||||
tracePos.x -= wind;
|
||||
tracePos.z += cloudAltitude * 64.0;
|
||||
#else
|
||||
tracePos.z -= wind;
|
||||
tracePos.x += cloudAltitude * 64.0;
|
||||
#endif
|
||||
|
||||
tracePos.xz *= cloudNarrowness;
|
||||
return tracePos.xyz;
|
||||
}
|
||||
|
||||
#endif
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
#include "/lib/shaderSettings/clouds.glsl"
|
||||
#if CLOUD_UNBOUND_SIZE_MULT != 100
|
||||
#define CLOUD_UNBOUND_SIZE_MULT_M CLOUD_UNBOUND_SIZE_MULT * 0.01
|
||||
#endif
|
||||
|
||||
#include "/lib/colors/lightAndAmbientColors.glsl"
|
||||
#include "/lib/colors/cloudColors.glsl"
|
||||
#include "/lib/atmospherics/sky.glsl"
|
||||
|
||||
float InterleavedGradientNoiseForClouds() {
|
||||
float n = 52.9829189 * fract(0.06711056 * gl_FragCoord.x + 0.00583715 * gl_FragCoord.y);
|
||||
#ifdef TAA
|
||||
return fract(n + goldenRatio * mod(float(frameCounter), 3600.0));
|
||||
#else
|
||||
return fract(n);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SHADOW_QUALITY > -1
|
||||
vec3 GetShadowOnCloudPosition(vec3 tracePos, vec3 cameraPos) {
|
||||
vec3 wpos = PlayerToShadow(tracePos - cameraPos);
|
||||
float distb = sqrt(wpos.x * wpos.x + wpos.y * wpos.y);
|
||||
float distortFactor = 1.0 - shadowMapBias + distb * shadowMapBias;
|
||||
vec3 shadowPosition = vec3(vec2(wpos.xy / distortFactor), wpos.z * 0.2);
|
||||
return shadowPosition * 0.5 + 0.5;
|
||||
}
|
||||
|
||||
bool GetShadowOnCloud(vec3 tracePos, vec3 cameraPos, int cloudAltitude, float lowerPlaneAltitude, float higherPlaneAltitude) {
|
||||
const float cloudShadowOffset = 0.5;
|
||||
|
||||
vec3 shadowPosition0 = GetShadowOnCloudPosition(tracePos, cameraPos);
|
||||
if (length(shadowPosition0.xy * 2.0 - 1.0) < 1.0) {
|
||||
float shadowsample0 = shadow2D(shadowtex0, shadowPosition0).z;
|
||||
|
||||
if (shadowsample0 == 0.0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLOUDS_REIMAGINED
|
||||
#include "/lib/atmospherics/clouds/reimaginedClouds.glsl"
|
||||
#endif
|
||||
#ifdef CLOUDS_UNBOUND
|
||||
#include "/lib/atmospherics/clouds/unboundClouds.glsl"
|
||||
#endif
|
||||
|
||||
vec4 GetClouds(inout float cloudLinearDepth, float skyFade, vec3 cameraPosOffset, vec3 playerPos, vec3 viewPos,
|
||||
float lViewPos, float VdotS, float VdotU, float dither, vec3 auroraBorealis, vec3 nightNebula, vec3 sunVec) {
|
||||
vec4 clouds = vec4(0.0);
|
||||
|
||||
vec3 nPlayerPos = normalize(playerPos);
|
||||
float lViewPosM = lViewPos < renderDistance * 1.5 ? lViewPos - 1.0 : 1000000000.0;
|
||||
float skyMult0 = pow2(skyFade * 3.333333 - 2.333333);
|
||||
|
||||
#if IRIS_VERSION >= 10800
|
||||
#ifdef CLOUDS_REIMAGINED
|
||||
float modFactor = 1.0 / cloudNarrowness * 256.0;
|
||||
#else
|
||||
#if CLOUD_UNBOUND_SIZE_MULT == 100
|
||||
float modFactor = 1.0 / cloudNarrowness;
|
||||
#else
|
||||
float modFactor = 1.0 / (cloudNarrowness * CLOUD_UNBOUND_SIZE_MULT_M);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int modFactorM = int(modFactor);
|
||||
|
||||
vec2 cameraPositionBIM = cameraPositionInt.xz - modFactorM * (cameraPositionInt.xz / modFactorM);
|
||||
|
||||
vec3 cameraPos = vec3(
|
||||
cameraPositionBIM.x + cameraPositionBestFract.x,
|
||||
cameraPosition.y,
|
||||
cameraPositionBIM.y + cameraPositionBestFract.z
|
||||
);
|
||||
|
||||
#if defined CLOUDS_UNBOUND && defined DOUBLE_UNBOUND_CLOUDS
|
||||
float layer2ScaleFactor = CLOUD_UNBOUND_LAYER2_SIZE * 10.0 / CLOUD_UNBOUND_SIZE_MULT;
|
||||
#if CLOUD_UNBOUND_SIZE_MULT == 100
|
||||
float modFactor2 = 1.0 / (cloudNarrowness * layer2ScaleFactor);
|
||||
#else
|
||||
float modFactor2 = 1.0 / (cloudNarrowness * CLOUD_UNBOUND_SIZE_MULT_M * layer2ScaleFactor);
|
||||
#endif
|
||||
|
||||
int modFactorM2 = int(modFactor2);
|
||||
|
||||
vec2 cameraPositionBIM2 = cameraPositionInt.xz - modFactorM2 * (cameraPositionInt.xz / modFactorM2);
|
||||
|
||||
vec3 cameraPos2 = vec3(
|
||||
cameraPositionBIM2.x + cameraPositionBestFract.x,
|
||||
cameraPosition.y,
|
||||
cameraPositionBIM2.y + cameraPositionBestFract.z
|
||||
);
|
||||
#endif
|
||||
#else
|
||||
vec3 cameraPos = cameraPosition;
|
||||
#if defined CLOUDS_UNBOUND && defined DOUBLE_UNBOUND_CLOUDS
|
||||
vec3 cameraPos2 = cameraPosition;
|
||||
#endif
|
||||
#endif
|
||||
cameraPos += cameraPosOffset;
|
||||
#if defined CLOUDS_UNBOUND && defined DOUBLE_UNBOUND_CLOUDS
|
||||
cameraPos2 += cameraPosOffset;
|
||||
#endif
|
||||
|
||||
#ifdef CLOUDS_REIMAGINED
|
||||
float thresholdF = 4000.0;
|
||||
#else
|
||||
float thresholdF = 4000.0;
|
||||
#endif
|
||||
|
||||
//float thresholdMix = pow2(clamp01(VdotU * 15.0));
|
||||
//thresholdF = mix(far, thresholdF, thresholdMix * 0.5 + 0.5);
|
||||
thresholdF *= CLOUD_RENDER_DISTANCE;
|
||||
|
||||
#if RAINBOW_CLOUD != 0
|
||||
vec3 wpos = normalize((gbufferModelViewInverse * vec4(viewPos, 1.0)).xyz);
|
||||
wpos /= (abs(wpos.y) + length(wpos.xz));
|
||||
|
||||
vec3 rainbowColor = getRainbowColor(wpos.xz * rainbowCloudDistribution * 0.35, 0.05);
|
||||
cloudRainColor *= rainbowColor;
|
||||
cloudAmbientColor *= rainbowColor;
|
||||
cloudLightColor *= rainbowColor;
|
||||
#endif
|
||||
|
||||
#ifdef CLOUDS_REIMAGINED
|
||||
cloudAmbientColor *= 1.0 - 0.25 * rainFactor;
|
||||
#endif
|
||||
|
||||
vec3 cloudColorMult = vec3(1.0);
|
||||
#if CLOUD_R != 100 || CLOUD_G != 100 || CLOUD_B != 100
|
||||
cloudColorMult *= vec3(CLOUD_R, CLOUD_G, CLOUD_B) * 0.01;
|
||||
#endif
|
||||
cloudAmbientColor *= cloudColorMult;
|
||||
cloudLightColor *= cloudColorMult;
|
||||
|
||||
#if defined CLOUDS_REIMAGINED && defined DOUBLE_REIM_CLOUDS
|
||||
int maxCloudAlt = max(cloudAlt1i, cloudAlt2i);
|
||||
int minCloudAlt = min(cloudAlt1i, cloudAlt2i);
|
||||
|
||||
if (abs(cameraPos.y - minCloudAlt) < abs(cameraPos.y - maxCloudAlt)) {
|
||||
clouds = GetVolumetricClouds(minCloudAlt, thresholdF, cloudLinearDepth, skyFade, skyMult0,
|
||||
cameraPos, nPlayerPos, lViewPosM, VdotS, VdotU, dither, sunVec, viewPos);
|
||||
if (clouds.a == 0.0) {
|
||||
clouds = GetVolumetricClouds(maxCloudAlt, thresholdF, cloudLinearDepth, skyFade, skyMult0,
|
||||
cameraPos, nPlayerPos, lViewPosM, VdotS, VdotU, dither, sunVec, viewPos);
|
||||
}
|
||||
} else {
|
||||
clouds = GetVolumetricClouds(maxCloudAlt, thresholdF, cloudLinearDepth, skyFade, skyMult0,
|
||||
cameraPos, nPlayerPos, lViewPosM, VdotS, VdotU, dither, sunVec, viewPos);
|
||||
if (clouds.a == 0.0) {
|
||||
clouds = GetVolumetricClouds(minCloudAlt, thresholdF, cloudLinearDepth, skyFade, skyMult0,
|
||||
cameraPos, nPlayerPos, lViewPosM, VdotS, VdotU, dither, sunVec, viewPos);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined CLOUDS_UNBOUND && defined DOUBLE_UNBOUND_CLOUDS
|
||||
float cloudLinearDepth1 = 1.0;
|
||||
float cloudLinearDepth2 = 1.0;
|
||||
//The order of calculating the clouds actually matters here
|
||||
vec4 clouds1 = GetVolumetricClouds(cloudAlt1i, thresholdF, cloudLinearDepth1, skyFade, skyMult0,
|
||||
cameraPos, nPlayerPos, lViewPosM, VdotS, VdotU, dither, sunVec, viewPos);
|
||||
vec4 clouds2 = GetVolumetricClouds(cloudAlt2i, thresholdF, cloudLinearDepth2, skyFade, skyMult0,
|
||||
cameraPos2, nPlayerPos, lViewPosM, VdotS, VdotU, dither, sunVec, viewPos);
|
||||
|
||||
if (clouds1.a * clouds2.a < 1e-36)
|
||||
clouds = clouds1 * sign(max(0.0, clouds1.a - 1e-36)) + clouds2 * sign(max(0.0, clouds2.a - 1e-36));
|
||||
else {
|
||||
if (cloudLinearDepth1 < cloudLinearDepth2)
|
||||
clouds = vec4(mix(clouds2.rgb, clouds1.rgb, clouds1.w), mix(clouds2.w, 1.0, clouds1.w));
|
||||
else
|
||||
clouds = vec4(mix(clouds1.rgb, clouds2.rgb, clouds2.w), mix(clouds1.w, 1.0, clouds2.w));
|
||||
}
|
||||
|
||||
cloudLinearDepth = min(clouds1.a > 0.5 ? cloudLinearDepth1 : 1.0, clouds2.a > 0.5 ? cloudLinearDepth2 : 1.0);
|
||||
#else
|
||||
clouds = GetVolumetricClouds(cloudAlt1i, thresholdF, cloudLinearDepth, skyFade, skyMult0,
|
||||
cameraPos, nPlayerPos, lViewPosM, VdotS, VdotU, dither, sunVec, viewPos) ;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
clouds.rgb *= sqrtAtmColorMult; // C72380KD - Reduced atmColorMult impact on some things
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_ATMOSPHERE
|
||||
clouds.rgb *= moonPhaseInfluence;
|
||||
#endif
|
||||
|
||||
#if AURORA_STYLE > 0
|
||||
clouds.rgb += auroraBorealis * 0.1;
|
||||
#endif
|
||||
#if NIGHT_NEBULAE == 1
|
||||
clouds.rgb += nightNebula * 0.2;
|
||||
#endif
|
||||
|
||||
return clouds;
|
||||
}
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
#include "/lib/shaderSettings/cloudsAndLighting.glsl"
|
||||
#include "/lib/atmospherics/clouds/cloudCoord.glsl"
|
||||
|
||||
#ifdef DOUBLE_REIM_CLOUDS
|
||||
const float cloudStretch = CLOUD_STRETCH * 4.2;
|
||||
const float L2cloudStretch = cloudStretch * CLOUD_REIMAGINED_LAYER2_HEIGHT;
|
||||
const float cloudTallness = cloudStretch * 2.0;
|
||||
#else
|
||||
const float cloudStretch = CLOUD_STRETCH * 4.2;
|
||||
const float cloudTallness = cloudStretch * 2.0;
|
||||
#endif
|
||||
const float cloudRoundness = CLOUD_ROUNDNESS;
|
||||
|
||||
bool GetCloudNoise(vec3 tracePos, inout vec3 tracePosM, int cloudAltitude) {
|
||||
tracePosM = ModifyTracePos(tracePos, cloudAltitude);
|
||||
vec2 coord = GetRoundedCloudCoord(tracePosM.xz, cloudRoundness);
|
||||
|
||||
#ifdef DEFERRED1
|
||||
float noise = texture2D(colortex3, coord).b;
|
||||
#else
|
||||
float noise = texture2D(gaux4, coord).b;
|
||||
#endif
|
||||
|
||||
float threshold = clamp(abs(cloudAltitude - tracePos.y) / cloudStretch, 0.001, 0.999);
|
||||
threshold = pow2(pow2(pow2(threshold)));
|
||||
return noise > threshold * 0.5 + 0.25;
|
||||
}
|
||||
|
||||
float Get2DCloudSample(vec2 pos) {
|
||||
#ifdef DEFERRED1
|
||||
return texture2D(colortex3, GetRoundedCloudCoord(pos, cloudRoundness)).b;
|
||||
#else
|
||||
return texture2D(gaux4, GetRoundedCloudCoord(pos, cloudRoundness)).b;
|
||||
#endif
|
||||
}
|
||||
|
||||
vec4 GetVolumetricClouds(int cloudAltitude, float distanceThreshold, inout float cloudLinearDepth, float skyFade, float skyMult0, vec3 cameraPos, vec3 nPlayerPos, float lViewPosM, float VdotS, float VdotU, float dither, vec3 sunVec, vec3 viewPos) {
|
||||
vec4 volumetricClouds = vec4(0.0);
|
||||
|
||||
// Use local variables to avoid modifying globals
|
||||
float localCloudStretch = cloudStretch;
|
||||
float localCloudTallness = cloudTallness;
|
||||
|
||||
#ifdef DOUBLE_REIM_CLOUDS
|
||||
if (cloudAltitude != cloudAlt1i) { // second layer
|
||||
localCloudStretch = L2cloudStretch;
|
||||
localCloudTallness = 2.0 * localCloudStretch;
|
||||
}
|
||||
#endif
|
||||
|
||||
float higherPlaneAltitude = cloudAltitude + localCloudStretch;
|
||||
float lowerPlaneAltitude = cloudAltitude - localCloudStretch;
|
||||
|
||||
float lowerPlaneDistance = (lowerPlaneAltitude - cameraPos.y) / nPlayerPos.y;
|
||||
float higherPlaneDistance = (higherPlaneAltitude - cameraPos.y) / nPlayerPos.y;
|
||||
float minPlaneDistance = min(lowerPlaneDistance, higherPlaneDistance);
|
||||
minPlaneDistance = max(minPlaneDistance, 0.0);
|
||||
float maxPlaneDistance = max(lowerPlaneDistance, higherPlaneDistance);
|
||||
if (maxPlaneDistance < 0.0) return vec4(0.0);
|
||||
float planeDistanceDif = maxPlaneDistance - minPlaneDistance;
|
||||
|
||||
#if CLOUD_QUALITY_INTERNAL == 1 || !defined DEFERRED1
|
||||
int sampleCount = max(int(planeDistanceDif) / 16, 6);
|
||||
#elif CLOUD_QUALITY_INTERNAL == 2
|
||||
int sampleCount = max(int(planeDistanceDif) / 8, 12);
|
||||
#elif CLOUD_QUALITY_INTERNAL == 3 || CLOUD_QUALITY_INTERNAL == 4
|
||||
int sampleCount = max(int(planeDistanceDif), 12);
|
||||
#endif
|
||||
|
||||
float stepMult = planeDistanceDif / sampleCount;
|
||||
vec3 traceAdd = nPlayerPos * stepMult;
|
||||
vec3 tracePos = cameraPos + minPlaneDistance * nPlayerPos;
|
||||
tracePos += traceAdd * dither;
|
||||
tracePos.y -= traceAdd.y;
|
||||
|
||||
#ifdef FIX_AMD_REFLECTION_CRASH
|
||||
sampleCount = min(sampleCount, 30); //BFARC
|
||||
#endif
|
||||
|
||||
#ifdef AURORA_INFLUENCE
|
||||
cloudAmbientColor = getAuroraAmbientColor(cloudAmbientColor, viewPos, 0.032, AURORA_CLOUD_INFLUENCE_INTENSITY, 0.75);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
tracePos += traceAdd;
|
||||
|
||||
vec3 cloudPlayerPos = tracePos - cameraPos;
|
||||
float lTracePos = length(cloudPlayerPos);
|
||||
float lTracePosXZ = length(cloudPlayerPos.xz);
|
||||
float cloudMult = 1.0;
|
||||
if (lTracePosXZ > distanceThreshold) break;
|
||||
if (lTracePos > lViewPosM) {
|
||||
if (skyFade < 0.7) continue;
|
||||
else cloudMult = skyMult0;
|
||||
}
|
||||
|
||||
vec3 tracePosM;
|
||||
if (GetCloudNoise(tracePos, tracePosM, cloudAltitude)) {
|
||||
float lightMult = 1.0;
|
||||
|
||||
#if SHADOW_QUALITY > -1
|
||||
float shadowLength = shadowDistance * 0.9166667; //consistent08JJ622
|
||||
if (shadowLength > lTracePos)
|
||||
if (GetShadowOnCloud(tracePos, cameraPos, cloudAltitude, lowerPlaneAltitude, higherPlaneAltitude)) {
|
||||
#ifdef CLOUD_CLOSED_AREA_CHECK
|
||||
if (eyeBrightness.y != 240) continue;
|
||||
else
|
||||
#endif
|
||||
lightMult = 0.25;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INVERTED_CLOUD_SHADING
|
||||
float cloudShading = (higherPlaneAltitude - tracePos.y) / localCloudTallness;
|
||||
#else
|
||||
float cloudShading = 1.0 - (higherPlaneAltitude - tracePos.y) / localCloudTallness;
|
||||
#endif
|
||||
cloudShading = pow(max0(cloudShading), max0(CLOUD_SHADING_AMOUNT * 0.1 - 0.2));
|
||||
float VdotSM1 = max0(sunVisibility > 0.5 ? VdotS : - VdotS);
|
||||
|
||||
#if CLOUD_QUALITY_INTERNAL >= 2
|
||||
#ifdef DEFERRED1
|
||||
float cloudShadingM = 1.0 - pow2(cloudShading);
|
||||
#else
|
||||
float cloudShadingM = 1.0 - cloudShading;
|
||||
#endif
|
||||
|
||||
float gradientNoise = InterleavedGradientNoiseForClouds();
|
||||
|
||||
vec3 cLightPos = tracePosM;
|
||||
vec3 cLightPosAdd = normalize(ViewToPlayer(lightVec * 1000000000.0)) * vec3(0.08);
|
||||
cLightPosAdd *= shadowTime;
|
||||
|
||||
float light = 2.0;
|
||||
cLightPos += (1.0 + gradientNoise) * cLightPosAdd;
|
||||
light -= Get2DCloudSample(cLightPos.xz) * cloudShadingM;
|
||||
cLightPos += gradientNoise * cLightPosAdd;
|
||||
light -= Get2DCloudSample(cLightPos.xz) * cloudShadingM;
|
||||
|
||||
float VdotSM2 = VdotSM1 * shadowTime * 0.25;
|
||||
VdotSM2 += 0.5 * cloudShading + 0.08;
|
||||
cloudShading = VdotSM2 * light * lightMult;
|
||||
#endif
|
||||
|
||||
#if CLOUD_SUN_MOON_SHADING > 0
|
||||
float visibilityFactor = 1.0;
|
||||
#if CLOUD_SUN_MOON_SHADING == 1
|
||||
visibilityFactor = 1.0 - sunVisibility;
|
||||
#elif CLOUD_SUN_MOON_SHADING == 2
|
||||
visibilityFactor = sunVisibility;
|
||||
#endif
|
||||
|
||||
if (visibilityFactor > 0.0) {
|
||||
vec3 worldLightVec = mat3(gbufferModelViewInverse) * sunVec;
|
||||
float cloudLightRadius = 375.0;
|
||||
|
||||
float aboveFade = 1.0 - smoothstep(-20.0, 0.0, cameraPos.y - cloudAltitude);
|
||||
float sunPlaneIntersect = (cloudAltitude - cameraPos.y) / worldLightVec.y;
|
||||
vec2 posVector = cameraPos.xz + worldLightVec.xz * sunPlaneIntersect - tracePos.xz;
|
||||
|
||||
float moonVisibility = abs(1.0 - moonPhase / 4.0);
|
||||
float sunMult = mix(moonVisibility, 0.75, sunVisibility);
|
||||
float falloff = exp((1.0 - max0(1.0 - length(posVector) / cloudLightRadius)) * -6.0) * aboveFade * sunMult;
|
||||
|
||||
float sunCloudMult = clamp01(falloff * 2.5 * mix(1.0, (lTracePos - minPlaneDistance) / (maxPlaneDistance - minPlaneDistance), 0.6));
|
||||
|
||||
vec3 bloodMoonCloudColor = vec3(1.0);
|
||||
#if BLOOD_MOON > 0
|
||||
bloodMoonCloudColor = mix(bloodMoonCloudColor, vec3(0.302, 0.0078, 0.0078) * 5, getBloodMoon(sunVisibility));
|
||||
#endif
|
||||
|
||||
cloudLightColor += bloodMoonCloudColor * sunCloudMult * 0.11 * visibilityFactor;
|
||||
cloudShading += sunCloudMult * 1.5 * visibilityFactor;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BLOOD_MOON > 0
|
||||
vec3 hsvCloudLightColor = rgb2hsv(cloudLightColor);
|
||||
cloudLightColor = mix(cloudLightColor, hsv2rgb(vec3(0, max(0.66, hsvCloudLightColor.y), hsvCloudLightColor.z)), getBloodMoon(sunVisibility));
|
||||
#endif
|
||||
|
||||
#ifdef AURORA_INFLUENCE
|
||||
cloudLightColor = getAuroraAmbientColor(cloudLightColor, viewPos, 0.1, AURORA_CLOUD_INFLUENCE_INTENSITY, 0.75);
|
||||
#endif
|
||||
|
||||
vec3 colorSample = cloudAmbientColor * 0.95 * (1.0 - 0.35 * cloudShading) + cloudLightColor * (0.1 + cloudShading);
|
||||
|
||||
#ifdef RAIN_ATMOSPHERE
|
||||
// Lightning flashes around lightning bolt position
|
||||
vec3 lightningPos = getLightningPos(tracePos - cameraPos, lightningBoltPosition.xyz, false);
|
||||
vec2 lightningAdd = lightningFlashEffect(lightningPos, vec3(1.0), 450.0, 0.0, 0) * isLightningActive() * 10.0;
|
||||
colorSample += lightningAdd.y;
|
||||
|
||||
// Thunderstorm cloud highlights (randomly appear in stormy weather)
|
||||
float highlightBoost = getThunderstormCloudHighlights(tracePos, cameraPos.xz, lTracePos, minPlaneDistance, maxPlaneDistance, 0.005);
|
||||
colorSample += highlightBoost;
|
||||
#endif
|
||||
|
||||
vec3 cloudSkyColor = GetSky(VdotU, VdotS, dither, isEyeInWater == 0, false);
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
cloudSkyColor *= sqrtAtmColorMult; // C72380KD - Reduced atmColorMult impact on some things
|
||||
#endif
|
||||
float distanceRatio = (distanceThreshold - lTracePosXZ) / distanceThreshold;
|
||||
float cloudFogFactor = pow2(clamp(distanceRatio, 0.0, 1.0)) * 0.75;
|
||||
float nightCloudRemove = NIGHT_CLOUD_UNBOUND_REMOVE * (1.0 - sunVisibility) * -1 + 1.0; // mapped to 1 to 0 range
|
||||
|
||||
#if defined DOUBLE_REIM_CLOUDS && CLOUD_REIMAGINED_LAYER2_TRANSPARENCY != 20
|
||||
if (cloudAltitude != cloudAlt1i) { // second layer uses custom transparency
|
||||
cloudMult *= (CLOUD_REIMAGINED_LAYER2_TRANSPARENCY * 0.05) * nightCloudRemove;
|
||||
} else {
|
||||
cloudMult *= CLOUD_TRANSPARENCY * nightCloudRemove;
|
||||
}
|
||||
#else
|
||||
cloudMult *= CLOUD_TRANSPARENCY * nightCloudRemove;
|
||||
#endif
|
||||
|
||||
float skyMult1 = 1.0 - 0.2 * (1.0 - skyFade) * max(sunVisibility2, nightFactor);
|
||||
float skyMult2 = 1.0 - 0.33333 * skyFade;
|
||||
colorSample = mix(cloudSkyColor, colorSample * skyMult1, cloudFogFactor * skyMult2);
|
||||
colorSample *= pow2(1.0 - maxBlindnessDarkness);
|
||||
|
||||
float cloudDistanceFactor = clamp(distanceRatio, 0.0, 0.75);
|
||||
//float distanceRatioNew = (2000 - lTracePosXZ) / 2000;
|
||||
//float cloudDistanceFactorNew = clamp(distanceRatioNew, 0.5, 0.75);
|
||||
|
||||
//volumetricClouds.a = pow(cloudDistanceFactor * 1.33333, 0.5 + 10.0 * pow(abs(VdotSM1), 90.0)) * cloudMult;
|
||||
volumetricClouds.a = sqrt(cloudDistanceFactor * 1.33333) * cloudMult;
|
||||
volumetricClouds.rgb = colorSample;
|
||||
|
||||
cloudLinearDepth = sqrt(lTracePos / renderDistance);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return volumetricClouds;
|
||||
}
|
||||
+376
@@ -0,0 +1,376 @@
|
||||
#include "/lib/shaderSettings/cloudsAndLighting.glsl"
|
||||
const float cloudStretchModified = max(0.25, float(CLOUD_STRETCH) * 1.9 - 0.9);
|
||||
#if CLOUD_QUALITY_INTERNAL == 1 || !defined DEFERRED1
|
||||
const float cloudStretchRaw = 11.0 * cloudStretchModified;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 2
|
||||
const float cloudStretchRaw = 16.0 * cloudStretchModified;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 3
|
||||
const float cloudStretchRaw = 18.0 * cloudStretchModified;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 4
|
||||
const float cloudStretchRaw = 20.0 * cloudStretchModified;
|
||||
#endif
|
||||
|
||||
#ifdef DOUBLE_UNBOUND_CLOUDS
|
||||
const float L2cloudStretch = cloudStretchRaw * CLOUD_UNBOUND_LAYER2_HEIGHT / CLOUD_STRETCH;
|
||||
|
||||
#if CLOUD_UNBOUND_SIZE_MULT <= 100
|
||||
float cloudStretch = cloudStretchRaw;
|
||||
#else
|
||||
float cloudStretch = cloudStretchRaw / float(CLOUD_UNBOUND_SIZE_MULT_M);
|
||||
#endif
|
||||
|
||||
float cloudTallness = cloudStretch * 2.0;
|
||||
#else
|
||||
#if CLOUD_UNBOUND_SIZE_MULT <= 100
|
||||
const float cloudStretch = cloudStretchRaw;
|
||||
#else
|
||||
const float cloudStretch = cloudStretchRaw / float(CLOUD_UNBOUND_SIZE_MULT_M);
|
||||
#endif
|
||||
const float cloudTallness = cloudStretch * 2.0;
|
||||
#endif
|
||||
|
||||
#if CLOUD_QUALITY > 1
|
||||
const float cloudNarrowness = 0.00012;
|
||||
#else
|
||||
const float cloudNarrowness = 0.00006;
|
||||
#endif
|
||||
|
||||
|
||||
float GetCloudNoise(vec3 tracePos, int cloudAltitude, float lTracePosXZ, float cloudPlayerPosY) {
|
||||
vec3 tracePosM = tracePos.xyz * cloudNarrowness;
|
||||
float wind = 0.0006;
|
||||
float noise = 0.0;
|
||||
float currentPersist = 1.0;
|
||||
float total = 0.0;
|
||||
|
||||
#if CLOUD_SPEED_MULT == 100
|
||||
#define CLOUD_SPEED_MULT_M CLOUD_SPEED_MULT * 0.01
|
||||
wind *= syncedTime;
|
||||
#else
|
||||
#define CLOUD_SPEED_MULT_M CLOUD_SPEED_MULT * 0.01
|
||||
wind *= frameTimeCounter * CLOUD_SPEED_MULT_M;
|
||||
#endif
|
||||
|
||||
#if CLOUD_UNBOUND_SIZE_MULT != 100
|
||||
tracePosM *= CLOUD_UNBOUND_SIZE_MULT_M;
|
||||
wind *= CLOUD_UNBOUND_SIZE_MULT_M;
|
||||
#endif
|
||||
|
||||
#ifdef DOUBLE_UNBOUND_CLOUDS
|
||||
if (cloudAltitude != cloudAlt1i) {
|
||||
tracePosM *= CLOUD_UNBOUND_LAYER2_SIZE * 10.0 / CLOUD_UNBOUND_SIZE_MULT;
|
||||
wind *= CLOUD_UNBOUND_LAYER2_SIZE * 30.0 * CLOUD_LAYER2_SPEED_MULT / CLOUD_UNBOUND_SIZE_MULT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CLOUD_QUALITY_INTERNAL == 1
|
||||
int sampleCount = 2;
|
||||
float persistance = 0.6;
|
||||
float noiseMult = 0.95;
|
||||
wind *= 0.5;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 2 || !defined DEFERRED1
|
||||
int sampleCount = 4;
|
||||
float persistance = 0.5;
|
||||
float noiseMult = 1.14;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 3
|
||||
int sampleCount = 4;
|
||||
float persistance = 0.5;
|
||||
float noiseMult = 1.0;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 4
|
||||
int sampleCount = 5;
|
||||
float persistance = 0.5;
|
||||
float noiseMult = 1.05;
|
||||
#endif
|
||||
|
||||
#ifndef DEFERRED1
|
||||
noiseMult *= 1.2;
|
||||
#endif
|
||||
|
||||
#if CLOUD_DIRECTION == 1
|
||||
tracePosM.xz = tracePosM.zx;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
#if CLOUD_QUALITY_INTERNAL >= 2
|
||||
noise += Noise3D(tracePosM - vec3(0.0, 0.0, wind)) * currentPersist;
|
||||
#else
|
||||
noise += texture2DLod(noisetex, tracePosM.xz - vec2(0.0, wind), 0.0).b * currentPersist;
|
||||
#endif
|
||||
total += currentPersist;
|
||||
|
||||
tracePosM *= 3.0;
|
||||
wind *= 0.5;
|
||||
currentPersist *= persistance;
|
||||
}
|
||||
noise = pow2(noise / total);
|
||||
|
||||
#define CLOUD_BASE_ADD 0.8
|
||||
//#define CLOUD_FAR_ADD -0.005
|
||||
#define CLOUD_ABOVE_ADD 0.1
|
||||
|
||||
float nightCloudRemove = NIGHT_CLOUD_UNBOUND_REMOVE * (1.0 - sunVisibility) * -0.65 + 1.0; // mapped to 1 to 0.65 range
|
||||
|
||||
float seasonCloudAdd = 0.0;
|
||||
#if SEASONS > 0
|
||||
float autumnOnlyForests = 1.0;
|
||||
#ifdef AUTUMN_CONDITION
|
||||
autumnOnlyForests = inForest;
|
||||
#endif
|
||||
float autumnWinterTime = autumnTime + winterTime;
|
||||
#if SNOW_CONDITION != 2
|
||||
autumnWinterTime *= mix(inSnowy + autumnOnlyForests, inSnowy, winterTime); // make only appear in cold biomes during winter
|
||||
#endif
|
||||
#if SNOW_CONDITION == 0
|
||||
autumnWinterTime *= mix(rainFactor + autumnOnlyForests, rainFactor, winterTime); // make only appear in rain during winter
|
||||
#endif
|
||||
seasonCloudAdd += mix(0.0, 0.35, autumnWinterTime);
|
||||
seasonCloudAdd += mix(0.0, -0.2, summerTime);
|
||||
#endif
|
||||
|
||||
noiseMult *= CLOUD_BASE_ADD
|
||||
//+ CLOUD_FAR_ADD * sqrt(lTracePosXZ + 10.0) // more/less clouds far away
|
||||
+ CLOUD_ABOVE_ADD * clamp01(-cloudPlayerPosY / cloudTallness) // more clouds when camera is above them
|
||||
+ CLOUD_UNBOUND_RAIN_ADD * rainFactor + seasonCloudAdd; // more clouds during rain and seasons
|
||||
|
||||
#ifdef DOUBLE_UNBOUND_CLOUDS
|
||||
if (cloudAltitude != cloudAlt1i)
|
||||
noise *= noiseMult * CLOUD_UNBOUND_LAYER2_AMOUNT * nightCloudRemove;
|
||||
else
|
||||
#endif
|
||||
noise *= noiseMult * CLOUD_UNBOUND_AMOUNT * nightCloudRemove;
|
||||
|
||||
float threshold = clamp(abs(cloudAltitude - tracePos.y) / cloudStretch, 0.001, 0.999);
|
||||
threshold = pow2(pow2(pow2(threshold)));
|
||||
return noise - (threshold * 0.2 + 0.25);
|
||||
}
|
||||
|
||||
vec4 GetVolumetricClouds(int cloudAltitude, float distanceThreshold, inout float cloudLinearDepth, float skyFade, float skyMult0, vec3 cameraPos, vec3 nPlayerPos, float lViewPosM, float VdotS, float VdotU, float dither, vec3 sunVec, vec3 viewPos) {
|
||||
vec4 volumetricClouds = vec4(0.0);
|
||||
|
||||
#ifdef DOUBLE_UNBOUND_CLOUDS
|
||||
float L1cloudStretch = cloudStretch;
|
||||
|
||||
if (cloudAltitude != cloudAlt1i) { // second layer
|
||||
cloudStretch = L2cloudStretch;
|
||||
cloudTallness = 2.0 * cloudStretch;
|
||||
}
|
||||
#endif
|
||||
|
||||
float higherPlaneAltitude = cloudAltitude + cloudStretch;
|
||||
float lowerPlaneAltitude = cloudAltitude - cloudStretch;
|
||||
|
||||
float lowerPlaneDistance = (lowerPlaneAltitude - cameraPos.y) / nPlayerPos.y;
|
||||
float higherPlaneDistance = (higherPlaneAltitude - cameraPos.y) / nPlayerPos.y;
|
||||
float minPlaneDistance = min(lowerPlaneDistance, higherPlaneDistance);
|
||||
minPlaneDistance = max(minPlaneDistance, 0.0);
|
||||
float maxPlaneDistance = max(lowerPlaneDistance, higherPlaneDistance);
|
||||
if (maxPlaneDistance < 0.0) return vec4(0.0);
|
||||
float planeDistanceDif = maxPlaneDistance - minPlaneDistance;
|
||||
|
||||
#ifndef DEFERRED1
|
||||
float stepMult = 64.0;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 1
|
||||
float stepMult = 16.0;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 2
|
||||
float stepMult = 32.0;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 3
|
||||
float stepMult = 16.0;
|
||||
#elif CLOUD_QUALITY_INTERNAL == 4
|
||||
float stepMult = 24.0;
|
||||
#endif
|
||||
|
||||
#if defined DOUBLE_UNBOUND_CLOUDS && (CLOUD_UNBOUND_LAYER2_SIZE > 10 || CLOUD_UNBOUND_SIZE_MULT > 100)
|
||||
if (cloudAltitude != cloudAlt1i) {
|
||||
#if CLOUD_UNBOUND_LAYER2_SIZE > 10
|
||||
stepMult = stepMult / sqrt(CLOUD_UNBOUND_LAYER2_SIZE * 0.1);
|
||||
#endif
|
||||
} else {
|
||||
#if CLOUD_UNBOUND_SIZE_MULT > 100
|
||||
stepMult = stepMult / sqrt(float(CLOUD_UNBOUND_SIZE_MULT_M));
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if CLOUD_UNBOUND_SIZE_MULT > 100
|
||||
stepMult = stepMult / sqrt(float(CLOUD_UNBOUND_SIZE_MULT_M));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
int sampleCount = int(planeDistanceDif / stepMult + dither + 1);
|
||||
vec3 traceAdd = nPlayerPos * stepMult;
|
||||
vec3 tracePos = cameraPos + minPlaneDistance * nPlayerPos;
|
||||
tracePos += traceAdd * dither;
|
||||
tracePos.y -= traceAdd.y;
|
||||
|
||||
float firstHitPos = 0.0;
|
||||
float VdotSM1 = max0(sunVisibility > 0.5 ? VdotS : - VdotS);
|
||||
float VdotSM1M = VdotSM1 * invRainFactor;
|
||||
float VdotSM2 = pow2(VdotSM1) * abs(sunVisibility - 0.5) * 2.0;
|
||||
float VdotSM3 = VdotSM2 * (2.5 + rainFactor) + 1.5 * rainFactor;
|
||||
float VdotSM4 = pow(VdotSM1M, 100.0) * sunVisibility;
|
||||
|
||||
#ifdef FIX_AMD_REFLECTION_CRASH
|
||||
sampleCount = min(sampleCount, 30); //BFARC
|
||||
#endif
|
||||
|
||||
#ifdef AURORA_INFLUENCE
|
||||
cloudLightColor = getAuroraAmbientColor(cloudLightColor, viewPos, 0.06, AURORA_CLOUD_INFLUENCE_INTENSITY, 0.75);
|
||||
cloudAmbientColor = getAuroraAmbientColor(cloudAmbientColor, viewPos, 0.03, AURORA_CLOUD_INFLUENCE_INTENSITY, 0.75);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
tracePos += traceAdd;
|
||||
|
||||
if (abs(tracePos.y - cloudAltitude) > cloudStretch) break;
|
||||
|
||||
vec3 cloudPlayerPos = tracePos - cameraPos;
|
||||
float lTracePos = length(cloudPlayerPos);
|
||||
float lTracePosXZ = length(cloudPlayerPos.xz);
|
||||
float cloudMult = 1.0;
|
||||
if (lTracePosXZ > distanceThreshold) break;
|
||||
if (lTracePos > lViewPosM) {
|
||||
if (skyFade < 0.7) continue;
|
||||
else cloudMult = skyMult0;
|
||||
}
|
||||
|
||||
float cloudNoise = GetCloudNoise(tracePos, cloudAltitude, lTracePosXZ, cloudPlayerPos.y);
|
||||
|
||||
if (cloudNoise > 0.00001) {
|
||||
#if defined DOUBLE_UNBOUND_CLOUDS
|
||||
//Fixes overlapping clouds
|
||||
|
||||
if (CLOUD_UNBOUND_LAYER2_HEIGHT > CLOUD_STRETCH){
|
||||
if (cloudAltitude == cloudAlt1i) {
|
||||
if (abs(tracePos.y - cloudAlt2i) < L2cloudStretch)
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (cloudAltitude != cloudAlt1i) {
|
||||
if (abs(tracePos.y - cloudAlt1i) < L1cloudStretch)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined CLOUD_CLOSED_AREA_CHECK && SHADOW_QUALITY > -1
|
||||
float shadowLength = shadowDistance * 0.9166667; //consistent08JJ622
|
||||
if (shadowLength < lTracePos)
|
||||
if (GetShadowOnCloud(tracePos, cameraPos, cloudAltitude, lowerPlaneAltitude, higherPlaneAltitude)) {
|
||||
if (eyeBrightness.y != 240) continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (firstHitPos < 1.0) {
|
||||
firstHitPos = lTracePos;
|
||||
#if CLOUD_QUALITY_INTERNAL == 1 && defined DEFERRED1
|
||||
tracePos.y += 4.0 * (texture2DLod(noisetex, tracePos.xz * cloudNarrowness * 16.0, 0.0).r - 0.5);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined DOUBLE_UNBOUND_CLOUDS && CLOUD_UNBOUND_LAYER2_TRANSPARENCY != 20
|
||||
float opacityFactor = cloudAltitude != cloudAlt1i
|
||||
? min1(cloudNoise * 8.0) * (CLOUD_UNBOUND_LAYER2_TRANSPARENCY * 0.05)
|
||||
: min1(cloudNoise * 8.0) * CLOUD_TRANSPARENCY;
|
||||
#else
|
||||
float opacityFactor = min1(cloudNoise * 8.0) * CLOUD_TRANSPARENCY;
|
||||
#endif
|
||||
|
||||
#ifdef INVERTED_CLOUD_SHADING
|
||||
float cloudShading = (higherPlaneAltitude - tracePos.y) / cloudTallness;
|
||||
#else
|
||||
float cloudShading = 1.0 - (higherPlaneAltitude - tracePos.y) / cloudTallness;
|
||||
#endif
|
||||
|
||||
cloudShading *= 1.0 + 0.2 * VdotSM3 * (1.0 - opacityFactor) + VdotSM4;
|
||||
#if CLOUD_SHADING_AMOUNT != 10
|
||||
cloudShading = pow(max0(cloudShading), CLOUD_SHADING_AMOUNT * 0.1);
|
||||
#endif
|
||||
|
||||
#ifdef AURORA_INFLUENCE
|
||||
cloudLightColor = getAuroraAmbientColor(cloudLightColor, viewPos, 0.1, AURORA_CLOUD_INFLUENCE_INTENSITY, 0.75);
|
||||
#endif
|
||||
|
||||
#if CLOUD_SUN_MOON_SHADING > 0
|
||||
float visibilityFactor = 1.0;
|
||||
#if CLOUD_SUN_MOON_SHADING == 1
|
||||
visibilityFactor = 1.0 - sunVisibility;
|
||||
#elif CLOUD_SUN_MOON_SHADING == 2
|
||||
visibilityFactor = sunVisibility;
|
||||
#endif
|
||||
|
||||
if (visibilityFactor > 0.0) {
|
||||
vec3 worldLightVec = mat3(gbufferModelViewInverse) * sunVec;
|
||||
float cloudLightRadius = 375.0;
|
||||
|
||||
float aboveFade = clamp01(1.0 - (cameraPos.y - cloudAltitude) / (cloudTallness * 3.0));
|
||||
float radiusFactor = mix(cloudLightRadius * 8.0, cloudLightRadius, aboveFade);
|
||||
float moonVisibility = abs(1.0 - moonPhase / 4.0);
|
||||
float sunMult = mix(moonVisibility, 0.85, sunVisibility);
|
||||
|
||||
float sunPlaneIntersect = (cloudAltitude - cameraPos.y) / worldLightVec.y;
|
||||
vec2 posVector = cameraPos.xz + worldLightVec.xz * sunPlaneIntersect - tracePos.xz;
|
||||
float falloff = exp((1.0 - max0(1.0 - length(posVector) / radiusFactor)) * -6.0) * aboveFade * sunMult;
|
||||
|
||||
float sunShadingFactor = clamp01(falloff * mix(1.0, 2.0, aboveFade) * mix(1.0, (lTracePos - minPlaneDistance) / (maxPlaneDistance - minPlaneDistance), 0.75));
|
||||
|
||||
vec3 bloodMoonCloudColor = vec3(1.0);
|
||||
#if BLOOD_MOON > 0
|
||||
bloodMoonCloudColor = mix(bloodMoonCloudColor, vec3(0.302, 0.0078, 0.0078) * 5, getBloodMoon(sunVisibility));
|
||||
#endif
|
||||
|
||||
cloudLightColor += bloodMoonCloudColor * sunShadingFactor * 0.3 * visibilityFactor;
|
||||
cloudShading += sunShadingFactor * 0.45 * visibilityFactor;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BLOOD_MOON > 0
|
||||
vec3 hsvCloudLightColor = rgb2hsv(cloudLightColor);
|
||||
cloudLightColor = mix(cloudLightColor, hsv2rgb(vec3(0, max(0.66, hsvCloudLightColor.y), hsvCloudLightColor.z)), getBloodMoon(sunVisibility));
|
||||
#endif
|
||||
|
||||
vec3 colorSample = cloudAmbientColor * (0.4 + 0.6 * cloudShading) + cloudLightColor * cloudShading;
|
||||
//vec3 colorSample = 2.5 * cloudLightColor * pow2(cloudShading); // <-- Used this to take the Unbound logo
|
||||
|
||||
#ifdef RAIN_ATMOSPHERE
|
||||
// Lightning flashes around lightning bolt position
|
||||
vec3 lightningPos = getLightningPos(tracePos - cameraPos, lightningBoltPosition.xyz, false);
|
||||
vec2 lightningAdd = lightningFlashEffect(lightningPos, vec3(1.0), 550.0, 0.0, 0) * isLightningActive() * 10.0;
|
||||
colorSample += lightningAdd.y;
|
||||
|
||||
// Thunderstorm cloud highlights (randomly appear in stormy weather)
|
||||
float highlightBoost = getThunderstormCloudHighlights(tracePos, cameraPos.xz, lTracePos, minPlaneDistance, maxPlaneDistance, 0.004);
|
||||
colorSample += highlightBoost;
|
||||
#endif
|
||||
|
||||
vec3 cloudSkyColor = GetSky(VdotU, VdotS, dither, isEyeInWater == 0, false);
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
cloudSkyColor *= sqrtAtmColorMult; // C72380KD - Reduced atmColorMult impact on some things
|
||||
#endif
|
||||
float distanceRatio = (distanceThreshold - lTracePosXZ) / distanceThreshold;
|
||||
float cloudDistanceFactor = clamp(distanceRatio, 0.0, 0.8) * 1.25;
|
||||
float cloudFogFactor = pow2(pow1_5(clamp(distanceRatio, 0.0, 1.0)));
|
||||
float skyMult1 = 1.0 - 0.2 * (1.0 - skyFade) * max(sunVisibility2, nightFactor);
|
||||
float skyMult2 = 1.0 - 0.33333 * skyFade;
|
||||
colorSample = mix(cloudSkyColor, colorSample * skyMult1, cloudFogFactor * skyMult2 * 0.72);
|
||||
colorSample *= pow2(1.0 - maxBlindnessDarkness);
|
||||
|
||||
volumetricClouds.rgb = mix(volumetricClouds.rgb, colorSample, 1.0 - min1(volumetricClouds.a));
|
||||
volumetricClouds.a += opacityFactor * pow(cloudDistanceFactor, 0.5 + 10.0 * pow(abs(VdotSM1M), 90.0)) * cloudMult;
|
||||
|
||||
if (volumetricClouds.a > 0.9) {
|
||||
volumetricClouds.a = 1.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DOUBLE_UNBOUND_CLOUDS
|
||||
if (volumetricClouds.a > 0.5)
|
||||
#endif
|
||||
{ cloudLinearDepth = sqrt(firstHitPos / renderDistance); }
|
||||
|
||||
return volumetricClouds;
|
||||
}
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
#ifndef ENDCRYSTAL_SAMPLER_DEFINE
|
||||
uniform isampler2D endcrystal_sampler;
|
||||
#endif
|
||||
|
||||
const float healing_boundRadius = 6.0;
|
||||
const float healing_ballRadius = 3.5;
|
||||
const float healing_beamRadius = 0.6;
|
||||
const float vortex_cylinderRadius = 3.0;
|
||||
const float vortex_ballRadius = 5.0;
|
||||
const float death_radius = 70.0;
|
||||
|
||||
#ifndef INCLUDE_ENDER_BEAMS
|
||||
#ifdef GBUFFERS_WATER
|
||||
float vlFactor = 0.5;
|
||||
#endif
|
||||
#endif
|
||||
vec3 beamPurple = normalize(endColorBeam * endColorBeam * endColorBeam) * (2.5 - 1.0 * vlFactor) * E_BEAM_I;
|
||||
|
||||
vec3 endDragonColM = sqrt(endOrangeCol);
|
||||
vec3 beamColM = sqrt(beamPurple);
|
||||
|
||||
float GetBallRadius(float state) {
|
||||
return vortex_ballRadius * (1.0 + 4.0 * sqrt(1.0 - state));
|
||||
}
|
||||
|
||||
float VortexWidth(float x, float ballRadius) {
|
||||
if (x > 0.5 * ballRadius) {
|
||||
float expScale = sqrt(0.75) * ballRadius - vortex_cylinderRadius;
|
||||
return vortex_cylinderRadius + expScale * exp( -sqrt(1.0/3.0) / expScale * (x - 0.5 * ballRadius));
|
||||
} else if (x > -ballRadius) {
|
||||
return sqrt(pow2(ballRadius) - pow2(x));
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
vec4 SampleEndCrystalVortex(vec3 relPos, vec2 state, vec2 noiseOffset) {
|
||||
float thisBallRadius = GetBallRadius(state.x);
|
||||
|
||||
float beamFactor = smoothstep(-thisBallRadius, thisBallRadius, relPos.y);
|
||||
float featureWidth = VortexWidth(relPos.y, thisBallRadius);
|
||||
vec2 horizontalScaledPos = featureWidth > 0.0 ? relPos.xz / featureWidth : vec2(2.0);
|
||||
float featureDist = length(horizontalScaledPos);
|
||||
if (length(relPos.xz) > featureWidth) {
|
||||
return vec4(0);
|
||||
}
|
||||
float beamStrength = 2.5 * beamFactor * (cos(featureDist * 3.1416) * 0.5 + 0.5) * pow2(max(0.0, 1 - pow2(0.005 / (0.9 * state.x + 0.1) / pow2(pow2(state.y)) * relPos.y))) * state.x;
|
||||
float spiralStrength = 200 * beamFactor * pow(featureDist, 7) * pow2(1.0 - featureDist) * pow2(max(0.0, 1 - pow2(0.02 / (0.6 * state.x * state.x + 0.4) / state.y * relPos.y)));
|
||||
float spiralAngle = (0.4 / vortex_cylinderRadius * relPos.y - 0.2 * pow2(min(0.0, -2.5 + relPos.y / thisBallRadius))) / (state.x + 0.2);
|
||||
vec2 spiralPos = mat2(cos(spiralAngle), -sin(spiralAngle), sin(spiralAngle), cos(spiralAngle)) * horizontalScaledPos;
|
||||
vec4 beamNoise = texture2DLod(noisetex, noiseOffset + 5.0 / noiseTextureResolution * horizontalScaledPos, 0.0);
|
||||
vec4 beamNoise2 = texture2DLod(noisetex, noiseOffset + 5.0 / noiseTextureResolution * vec2(relPos.y * 0.02 + 2.7 * beamNoise.gb - 3.6 * frameTimeCounter * 0.5), 0.0);
|
||||
vec4 spiralNoise = texture2DLod(noisetex, noiseOffset + 5.0 / noiseTextureResolution * spiralPos, 0.0);
|
||||
vec4 spiralNoise2 = texture2DLod(noisetex, noiseOffset + 20.0 / noiseTextureResolution * spiralPos, 0.0);
|
||||
return vec4(beamStrength * beamNoise.r * beamNoise2.r * endDragonColM + spiralStrength * pow2(spiralNoise.r) * (0.5 + spiralNoise2.r) * beamColM, beamStrength + spiralStrength) * 0.3;
|
||||
}
|
||||
|
||||
vec4 SingleEndCrystalVortex(vec3 start, vec3 direction, vec3 center, vec2 state, float dither) {
|
||||
const float stepSize = 0.5;
|
||||
float invHorizontalDirLen = 1.0 / length(direction.xz);
|
||||
float thisBallRadius = GetBallRadius(state.x);
|
||||
float closestProgress = clamp(
|
||||
dot(center.xz - start.xz, direction.xz) * pow2(invHorizontalDirLen),
|
||||
-thisBallRadius * invHorizontalDirLen,
|
||||
1.0 + thisBallRadius * invHorizontalDirLen);
|
||||
vec3 closestPos = start + closestProgress * direction;
|
||||
float closestDist = length(closestPos.xz - center.xz);
|
||||
if (closestDist > thisBallRadius) {
|
||||
return vec4(0);
|
||||
}
|
||||
float startProgress = closestProgress - sqrt((thisBallRadius * thisBallRadius - closestDist * closestDist)) * invHorizontalDirLen;
|
||||
float endProgress = min(1.0, 2 * closestProgress - startProgress);
|
||||
startProgress = max(0.0, startProgress);
|
||||
vec2 noiseOffset = (center.xz + cameraPosition.xz + vec2(3.0, 1.6) * frameTimeCounter) * 0.005;
|
||||
vec4 colour = vec4(0);
|
||||
float dist = startProgress + dither * invHorizontalDirLen * stepSize;
|
||||
for (int k = 0; k < 100; k++) {
|
||||
if (dist > endProgress) break;
|
||||
colour += SampleEndCrystalVortex(start + dist * direction - center, state, noiseOffset);
|
||||
dist += invHorizontalDirLen * stepSize;
|
||||
}
|
||||
return colour * stepSize * smoothstep(0.0, 1.0, state.x);
|
||||
}
|
||||
|
||||
float EndCrystalBeamWidth(float x, float len) {
|
||||
x = 0.5 * len - abs(x - 0.5 * len);
|
||||
if (x <= -healing_ballRadius) return 0.0;
|
||||
if (x < 0.5 * healing_ballRadius) return sqrt(pow2(healing_ballRadius) - pow2(x));
|
||||
float expScale = sqrt(0.75) * healing_ballRadius - healing_beamRadius;
|
||||
return healing_beamRadius + expScale * exp( -sqrt(1.0/3.0) / expScale * (x - 0.5 * healing_ballRadius));
|
||||
}
|
||||
|
||||
vec4 SampleEndCrystalBeam(vec3 relPos, float len) {
|
||||
float beamWidth = EndCrystalBeamWidth(relPos.x, len);
|
||||
|
||||
if (beamWidth > 0.0001) {
|
||||
float beamFactor = smoothstep(0.0, 2.0 * healing_ballRadius, 0.5 * len - abs(relPos.x - 0.5 * len));
|
||||
float noisyTime = frameTimeCounter + 0.4 * texture2DLod(noisetex, vec2(3.0 / noiseTextureResolution, frameTimeCounter / (0.45 * noiseTextureResolution)), 0.0).r;
|
||||
|
||||
relPos.yz /= beamWidth;
|
||||
float strength = 0.0;
|
||||
vec3 healBeamColor = vec3(0);
|
||||
for (int k = 0; k < 3; k++) {
|
||||
vec2 noiseCoords = vec2(0.2 / noiseTextureResolution * relPos.x, 0 + vec2(k, 6 * k) / noiseTextureResolution);
|
||||
vec4 zapNoise0 = texture2DLod(noisetex, noiseCoords + floor(8.0 * noisyTime) / noiseTextureResolution, 0.0);
|
||||
vec4 zapNoise1 = texture2DLod(noisetex, 3.3 * noiseCoords + floor(8.0 * noisyTime) / noiseTextureResolution, 0.0);
|
||||
vec4 zapNoise2 = texture2DLod(noisetex, 6.8 * noiseCoords + (15.0 * frameTimeCounter) / noiseTextureResolution, 0.0);
|
||||
vec2 thisRelPos = relPos.yz + beamFactor / beamWidth * (6.0 * zapNoise0.rb + 1.6 * zapNoise1.rb + 1.2 * zapNoise2.rb - (3.0 + 0.8 + 0.6));
|
||||
vec4 sideNoise = texture2DLod(noisetex, (7.0 * thisRelPos.xy) / noiseTextureResolution, 0.0);
|
||||
vec3 colorNoise = texture2DLod(noisetex, 4.0 * noiseCoords + floor(12.0 * noisyTime) / noiseTextureResolution, 0.0).rgb;
|
||||
float centerDist0 = length(thisRelPos.xy);
|
||||
|
||||
float centerDist = centerDist0 - 1.2;
|
||||
strength = max(strength, clamp( -centerDist, 0.0, 0.2) * pow2(max(0.0, 1.0 - pow2((centerDist0 - 1.0) * beamWidth * 0.5))) * mix(1.0, sideNoise.b, beamWidth / healing_ballRadius));
|
||||
healBeamColor = mix(clamp01(saturateColors(beamColM, 0.8) - sideNoise.rgb * 0.08), saturateColors(beamColM, 1.3) * 1.3, colorNoise);
|
||||
}
|
||||
return strength / beamWidth * vec4(healBeamColor * 0.5, 1.0) + 0.2 * beamFactor * exp(-6.0 * dot(relPos.yz, relPos.yz)) * vec4(endDragonColM * 2.2, 1.0);
|
||||
}
|
||||
return vec4(0.0);
|
||||
}
|
||||
|
||||
|
||||
vec4 EndCrystalBeam(vec3 start, vec3 direction, vec3 startPos, vec3 endPos, float dither) {
|
||||
vec3 startDiff = start - startPos;
|
||||
vec3 beamDirection = endPos - startPos;
|
||||
mat3 rotMat;
|
||||
rotMat[0] = normalize(beamDirection);
|
||||
rotMat[1] = normalize(cross(beamDirection, vec3(-2e-4, 1, 1e-5)));
|
||||
rotMat[2] = cross(rotMat[0], rotMat[1]);
|
||||
start *= rotMat;
|
||||
startPos *= rotMat;
|
||||
beamDirection *= rotMat;
|
||||
direction *= rotMat;
|
||||
const float stepSize = 0.5;
|
||||
float invHorizontalDirLen = 1.0 / length(direction.yz);
|
||||
float closestProgress = clamp(
|
||||
dot(startPos.yz - start.yz, direction.yz) * pow2(invHorizontalDirLen),
|
||||
-healing_boundRadius * invHorizontalDirLen,
|
||||
1.0 + healing_boundRadius * invHorizontalDirLen);
|
||||
vec3 closestPos = start + closestProgress * direction;
|
||||
float closestDist = length(closestPos.yz - startPos.yz);
|
||||
if (closestDist > healing_boundRadius) {
|
||||
return vec4(0);
|
||||
}
|
||||
float startProgress = closestProgress - sqrt((healing_boundRadius * healing_boundRadius - closestDist * closestDist)) * invHorizontalDirLen;
|
||||
float endProgress = min(1.0, 2 * closestProgress - startProgress);
|
||||
startProgress = max(0.0, startProgress);
|
||||
vec4 colour = vec4(0);
|
||||
float dist = startProgress + dither * invHorizontalDirLen * stepSize;
|
||||
for (int k = 0; k < 100; k++) {
|
||||
if (dist > endProgress) break;
|
||||
colour += SampleEndCrystalBeam(start + dist * direction - startPos, beamDirection.x);
|
||||
dist += invHorizontalDirLen * stepSize;
|
||||
}
|
||||
return 3.0 * log(length(colour) * stepSize + 1.0) * normalize(colour + 0.0000001);
|
||||
}
|
||||
|
||||
float GetDragonDeathFactor(float dragonDeathTime) {
|
||||
return 0.02 * dragonDeathTime * exp(0.1 * dragonDeathTime);
|
||||
}
|
||||
|
||||
vec4 SampleDeathBuildup(vec3 relPos, float dragonDeathTime) {
|
||||
float effectFactor = GetDragonDeathFactor(dragonDeathTime);
|
||||
float effectRadius = death_radius * effectFactor;
|
||||
float sizeNoiseFactor = 1.0 + 0.3 * texture2DLod(noisetex, vec2(0.2, dragonDeathTime * 5.0 / noiseTextureResolution), 0.0).r;
|
||||
float centerDist = length(relPos) / effectRadius;
|
||||
relPos *= sizeNoiseFactor;
|
||||
float angle = centerDist * 5.0 / log(dragonDeathTime * 0.6 + 1.0);
|
||||
mat2 rotMat = mat2(
|
||||
cos(angle), sin(angle),
|
||||
-sin(angle), cos(angle)
|
||||
);
|
||||
relPos.xz = rotMat * relPos.xz;
|
||||
vec2 val = pow(fract(hash23(floor(0.8 * relPos + 2.7 * sign(relPos) * exp(0.3 * dragonDeathTime)))), vec2(40.0 * pow2(centerDist))) * (1.0 - centerDist);
|
||||
return 0.1 * (vec4(beamColM, 1.0) * (val.x + 0.4 * exp(-8.0 * pow2(centerDist))) + vec4(endDragonColM, 1.0) * (val.y + 0.1 * exp(-3.0 * pow2(centerDist))));
|
||||
}
|
||||
|
||||
vec4 DragonDeathAnimation(vec3 start, vec3 direction, vec3 dragonPos, float dragonDeathTime, float dragonDeathFactor, float dither) {
|
||||
float dirLen = length(direction);
|
||||
float closestProgress = dot(dragonPos - start, direction) / pow2(dirLen);
|
||||
vec4 colour = vec4(0);
|
||||
if (dragonDeathFactor >= 0.99) {
|
||||
float effectRadius = death_radius * GetDragonDeathFactor(dragonDeathTime);
|
||||
vec3 closestPos = start + closestProgress * direction;
|
||||
float closestDist = length(closestPos - dragonPos);
|
||||
if (closestDist >= effectRadius) return vec4(0.0);
|
||||
float stepSize = 0.5 / dirLen;
|
||||
float startProgress = closestProgress - sqrt(pow2(effectRadius) - pow2(closestDist)) / dirLen;
|
||||
float endProgress = min(1.0, 2.0 * closestProgress - startProgress);
|
||||
startProgress = max(0.0, startProgress);
|
||||
float dist = startProgress + stepSize * dither;
|
||||
for (int k = 0; k < 150; k++) {
|
||||
if (dist > endProgress) break;
|
||||
colour += SampleDeathBuildup(start + dist * direction - dragonPos, dragonDeathTime);
|
||||
dist += stepSize;
|
||||
}
|
||||
colour *= stepSize * dirLen;
|
||||
} else {
|
||||
vec3 closestPos = start + clamp(closestProgress, 0.0, 1.0) * direction;
|
||||
float closestDist = length(dragonPos - closestPos);
|
||||
colour = vec4(endDragonColM + 0.5 * beamColM, 1.0) * (0.4 * death_radius * (1.0 - exp(-dirLen/(4.0 * death_radius))) * exp(-10.0 * (1.0 - dragonDeathFactor) - closestDist * closestDist / (death_radius * death_radius)) * dragonDeathFactor);
|
||||
}
|
||||
return colour;
|
||||
}
|
||||
|
||||
vec4 EndCrystalVortices(vec3 start, vec3 direction, float dither) {
|
||||
vec4 color = vec4(0);
|
||||
#if END_CRYSTAL_VORTEX_INTERNAL / 2 == 1 || DRAGON_DEATH_EFFECT_INTERNAL > 0
|
||||
ivec4 rawDragonPos = ivec4(
|
||||
texelFetch(endcrystal_sampler, ivec2(35, 5), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(35, 6), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(35, 7), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(35, 8), 0).r
|
||||
);
|
||||
vec3 dragonPos = rawDragonPos.xyz != ivec3(0) ? 0.0001 * rawDragonPos.xyz : vec3(0.5, 80.5, 0.5) - cameraPosition;
|
||||
#endif
|
||||
#if END_CRYSTAL_VORTEX_INTERNAL / 2 == 1
|
||||
vec3[15] healBeamEndPositions;
|
||||
int isTarget = 0;
|
||||
int healBeamCount = 15;
|
||||
for (int k = 0; k < 15; k++) {
|
||||
ivec4 rawPos = ivec4(
|
||||
texelFetch(endcrystal_sampler, ivec2(20 + k, 5), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(20 + k, 6), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(20 + k, 7), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(20 + k, 8), 0).r
|
||||
);
|
||||
if (rawPos.w == 0) {
|
||||
healBeamCount = k;
|
||||
break;
|
||||
}
|
||||
healBeamEndPositions[k] = vec3(rawPos.xyz) / rawPos.w;
|
||||
isTarget |= (length(healBeamEndPositions[k].xz + cameraPosition.xz - 0.5) < 4.5 || length(dragonPos - healBeamEndPositions[k]) < 5.0) ? 1 << k : 0;
|
||||
}
|
||||
#endif
|
||||
#if END_CRYSTAL_VORTEX_INTERNAL % 2 == 1
|
||||
for (int k = 0; k < 20; k++) {
|
||||
if (texelFetch(endcrystal_sampler, ivec2(k, 8), 0).r <= 0) continue;
|
||||
ivec4 rawPos = ivec4(
|
||||
texelFetch(endcrystal_sampler, ivec2(k, 5), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(k, 6), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(k, 7), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(k, 8), 0).r
|
||||
);
|
||||
if (rawPos.w <= 0) {
|
||||
continue;
|
||||
}
|
||||
int age = texelFetch(endcrystal_sampler, ivec2(k, 9), 0).r;
|
||||
vec3 pos = rawPos.xyz * 0.0001;
|
||||
#if END_CRYSTAL_VORTEX_INTERNAL / 2 == 1
|
||||
for (int i = 0; i < healBeamCount; i++) {
|
||||
isTarget |= length(pos - healBeamEndPositions[i]) < 4.5 ? 1<<(i+15) : 0;
|
||||
}
|
||||
#endif
|
||||
vec2 state = vec2(clamp(rawPos.w / 15000.0, 0.0, 1.0), 1.00001 - exp(-0.0001 * age));
|
||||
if (length(pos) > min(shadowDistance, far) * 0.9 && state.x < 0.999) {
|
||||
state.y = state.x;
|
||||
state.x = 1.0;
|
||||
}
|
||||
vec4 thisVortexCol = pow2(SingleEndCrystalVortex(start, direction, pos, state, dither));
|
||||
color += thisVortexCol;
|
||||
}
|
||||
#endif
|
||||
#if END_CRYSTAL_VORTEX_INTERNAL / 2 == 1
|
||||
for (int k = 0; k < healBeamCount; k++) {
|
||||
for (int l = k+1; l < healBeamCount; l++) {
|
||||
if (
|
||||
((isTarget >> k & 1) == 0 ^^ (isTarget >> l & 1) == 0)
|
||||
#if END_CRYSTAL_VORTEX_INTERNAL % 2 == 1
|
||||
&& ((isTarget >> k + 15 & 1) == 0 ^^ (isTarget >> l + 15 & 1) == 0)
|
||||
#endif
|
||||
) {
|
||||
vec3 pos0 = healBeamEndPositions[k];
|
||||
vec3 pos1 = healBeamEndPositions[l];
|
||||
if (pos0.y > pos1.y) {
|
||||
vec3 tmp = pos0;
|
||||
pos0 = pos1;
|
||||
pos1 = tmp;
|
||||
}
|
||||
color += pow2(EndCrystalBeam(start, direction, pos0, pos1, dither));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if DRAGON_DEATH_EFFECT_INTERNAL > 0
|
||||
int isDying = texelFetch(endcrystal_sampler, ivec2(35, 0), 0).r;
|
||||
float dragonDeathTime = 0.0001 * rawDragonPos.w;
|
||||
float dragonDeathFactor = 0.0001 * isDying;
|
||||
// dragonDeathTime = mod(frameTimeCounter, 22.0);
|
||||
// dragonDeathFactor = 2.2 - 0.1 * dragonDeathTime;
|
||||
// dragonPos = vec3(0, 80, 0) - cameraPosition;
|
||||
if (dragonDeathFactor > 0.001) {
|
||||
color += pow2(DragonDeathAnimation(start, direction, dragonPos, dragonDeathTime, dragonDeathFactor, dither));
|
||||
}
|
||||
#endif
|
||||
return sqrt(color) * (1.0 - maxBlindnessDarkness);
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
vec3 DrawEndFlash(vec3 nViewPos, float VdotU, float dither) {
|
||||
vec3 worldEndFlashPosition = mat3(gbufferModelViewInverse) * endFlashPosition;
|
||||
worldEndFlashPosition = normalize(worldEndFlashPosition);
|
||||
vec3 nViewPosWorld = mat3(gbufferModelViewInverse) * nViewPos;
|
||||
nViewPosWorld = normalize(nViewPosWorld);
|
||||
|
||||
vec3 horizontalEndPos = normalize(vec3(worldEndFlashPosition.x, 0.0, worldEndFlashPosition.z));
|
||||
vec3 horizontalViewPos = normalize(vec3(nViewPosWorld.x, 0.0, nViewPosWorld.z));
|
||||
float horizDirFactor = pow(max0(dot(horizontalEndPos, horizontalViewPos)), 0.2);
|
||||
|
||||
float dirFactor = pow(max0(dot(worldEndFlashPosition, nViewPosWorld)), 10.0);
|
||||
|
||||
float verticalDist = abs(nViewPosWorld.y - worldEndFlashPosition.y);
|
||||
float verticalFalloff = exp(-pow2(verticalDist * 5.5));
|
||||
|
||||
float endFlashFactor = endFlashIntensity * dirFactor * verticalFalloff;
|
||||
|
||||
if (endFlashFactor < 0.001) return vec3(0.0);
|
||||
|
||||
float time = frameTimeCounter * 0.05;
|
||||
float pulse = sin(time * 3.0) * 0.5 + 0.5;
|
||||
|
||||
vec2 noiseCoord = horizontalViewPos.xz * 0.5 + time * 0.05;
|
||||
float noise1 = texture2DLod(noisetex, noiseCoord, 0).r;
|
||||
float noise2 = texture2DLod(noisetex, noiseCoord * 2.7 - time * 0.17, 0).g;
|
||||
float noise3 = texture2DLod(noisetex, noiseCoord * 0.5 + time * 0.05, 0).b;
|
||||
|
||||
float rayFactor = pow(noise1 * noise2, 1.5) * 2.0;
|
||||
|
||||
float stripeFactor = pow(horizDirFactor, 2.0 + 4.0 * pulse);
|
||||
|
||||
// Inner core and wave animations
|
||||
float radius = 1.0 + sin(time * 2.0) * 0.1;
|
||||
float distFromCenter = length(dot(horizontalEndPos, horizontalViewPos));
|
||||
float waveFront = smoothstep(0.0, 0.2, 1.0 - abs(distFromCenter - radius) * (4.0 + pulse * 4.0));
|
||||
float core = pow(horizDirFactor, 1.0 + pulse * 2.0) * (1.0 + noise3 * 0.5);
|
||||
|
||||
float flashIntensity = mix(core, waveFront, 0.5) * endFlashFactor * (0.6 + rayFactor * 0.8);
|
||||
flashIntensity *= stripeFactor;
|
||||
|
||||
vec3 orangeColor = mix(endOrangeCol, vec3(1.0), 0.3) * (1.2 + noise2 * 1.3);
|
||||
|
||||
vec3 finalColor = saturateColors(orangeColor, 0.8) * flashIntensity * 0.7;
|
||||
|
||||
return finalColor;
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
#ifndef ENDCRYSTAL_SAMPLER_DEFINE
|
||||
uniform isampler2D endcrystal_sampler;
|
||||
#endif
|
||||
|
||||
vec2 RayAABoxIntersection(vec2 start, vec2 dir, vec2 lower, vec2 upper) {
|
||||
dir += 0.000001 * vec2(equal(dir, vec2(0)));
|
||||
vec2 front = mix(upper, lower, 0.5 * sign(dir) + 0.5);
|
||||
vec2 back = mix(lower, upper, 0.5 * sign(dir) + 0.5);
|
||||
vec2 front_iscts = (front - start) / dir;
|
||||
vec2 back_iscts = (back - start) / dir;
|
||||
float front_isct = max(front_iscts.x, front_iscts.y);
|
||||
float back_isct = min(back_iscts.x , back_iscts.y );
|
||||
return front_isct < back_isct ? vec2(front_isct, back_isct) : vec2(-1);
|
||||
}
|
||||
|
||||
vec4 GetEndPortalBeamNoise(vec3 relPos) {
|
||||
float colMixFactor = texture2DLod(noisetex, (relPos.xz + 0.1 * frameTimeCounter * vec2(-0.5, 1.5)) * 10.0 / noiseTextureResolution, 0.0).r;
|
||||
float strengthMul = texture2DLod(noisetex, (relPos.xz + 0.1 * frameTimeCounter * vec2(1.5, -1.0)) * 5.0 / noiseTextureResolution + 0.2, 0.0).r;
|
||||
colMixFactor = pow2(pow2(colMixFactor));
|
||||
strengthMul = pow2(strengthMul);
|
||||
vec3 col = mix(vec3(0.1137, 0.5569, 0.5255), vec3(0.3725, 0.8863, 0.749), colMixFactor);
|
||||
float strength
|
||||
= float(relPos.y > 0 && relPos.y < 2)
|
||||
* (2 - relPos.y)
|
||||
/ (3 * relPos.y*relPos.y*relPos.y + 1)
|
||||
* (strengthMul + 0.5);
|
||||
return pow2(vec4(col, 1) * strength);
|
||||
}
|
||||
|
||||
vec4 GetEndPortalBeam(vec3 start, vec3 dir) {
|
||||
if (texelFetch(endcrystal_sampler, ivec2(35, 4), 0).r == 1) {
|
||||
ivec4 rawPortalPos = ivec4(
|
||||
texelFetch(endcrystal_sampler, ivec2(35, 5), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(35, 6), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(35, 7), 0).r,
|
||||
texelFetch(endcrystal_sampler, ivec2(35, 8), 0).r
|
||||
);
|
||||
if (rawPortalPos.w > 0) {
|
||||
vec3 portalPos = floor(vec3(rawPortalPos.xyz) / max(1, rawPortalPos.w) + 0.5) + 0.5 - cameraPositionFract;
|
||||
vec2 iscts = RayAABoxIntersection(start.xz, dir.xz, portalPos.xz - 1.49, portalPos.xz + 1.49);
|
||||
int validIsctCount = 0;
|
||||
vec3[2] isctPositions;
|
||||
for (int k = 0; k < 2; k++) {
|
||||
if (iscts[k] > 0.0 && iscts[k] < 1.0) {
|
||||
isctPositions[validIsctCount++] = start + iscts[k] * dir;
|
||||
}
|
||||
}
|
||||
vec4 col = vec4(0.0);
|
||||
for (int k = 0; k < validIsctCount; k++) {
|
||||
col += GetEndPortalBeamNoise(isctPositions[k] - portalPos);
|
||||
}
|
||||
|
||||
vec3 absDir = abs(dir);
|
||||
float maxDir = max(absDir.x, max(absDir.y, absDir.z));
|
||||
float transition = 1.0 - pow3(min1(maxDir / mix(40, 10, maxBlindnessDarkness) * 2.0)); // fade to 0 when close to the range limit (32 blocks)
|
||||
|
||||
col *= transition;
|
||||
|
||||
return col;
|
||||
}
|
||||
}
|
||||
return vec4(0.0);
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
#ifndef INCLUDE_ENDER_BEAMS
|
||||
#define INCLUDE_ENDER_BEAMS
|
||||
|
||||
#include "/lib/colors/lightAndAmbientColors.glsl"
|
||||
|
||||
vec2 wind = vec2(syncedTime * 0.00);
|
||||
|
||||
float BeamNoise(vec2 planeCoord, vec2 wind) {
|
||||
float noise = texture2DLod(noisetex, planeCoord * 0.175 - wind * 0.0625, 0.0).b;
|
||||
noise+= texture2DLod(noisetex, planeCoord * 0.04375 + wind * 0.0375, 0.0).b * 5.0;
|
||||
|
||||
return noise;
|
||||
}
|
||||
|
||||
vec3 DrawEnderBeams(float VdotU, vec3 playerPos, vec3 nViewPos) {
|
||||
int sampleCount = 8;
|
||||
float beamMult = 1.0;
|
||||
float beamPow = 3.0;
|
||||
float beamPurpleReducer = vlFactor;
|
||||
float beamOrangeIncreaser = vlFactor;
|
||||
|
||||
float VdotUM = 1.0 - pow2(VdotU);
|
||||
float VdotUM2 = sqrt(VdotUM) + 0.15 * smoothstep1(pow2(pow2(1.0 - abs(VdotU))));
|
||||
|
||||
#if defined IS_IRIS && MC_VERSION >= 12109 && EP_END_FLASH % 2 == 0
|
||||
vec3 worldEndFlashPosition = mat3(gbufferModelViewInverse) * endFlashPosition;
|
||||
worldEndFlashPosition = normalize(vec3(worldEndFlashPosition.x, 0.0, worldEndFlashPosition.z));
|
||||
vec3 nViewPosWorld = mat3(gbufferModelViewInverse) * nViewPos;
|
||||
vec3 nViewPosWorldM = normalize(vec3(nViewPosWorld.x, 0.0, nViewPosWorld.z));
|
||||
|
||||
float endFlashDirectionFactor = pow(max0(dot(worldEndFlashPosition, nViewPosWorldM)), 12.0);
|
||||
float endFlashFactor = endFlashIntensity * endFlashDirectionFactor;
|
||||
|
||||
beamOrangeIncreaser = mix(beamOrangeIncreaser, 1.0, endFlashFactor);
|
||||
beamPurpleReducer = mix(beamPurpleReducer, 1.6, endFlashFactor);
|
||||
beamPow = mix(beamPow, 0.7, endFlashFactor * (pow(VdotUM, 8.0) * 0.75 + 0.25 * pow(1.0 - abs(VdotU) * 0.1 - 0.9 * pow2(VdotU), 30.0)));
|
||||
//beamPow = max(beamPow, 0.0001); // fix NaNs
|
||||
VdotUM = mix(VdotUM, sqrt2(VdotUM), endFlashFactor);
|
||||
#endif
|
||||
|
||||
vec3 beamPurple = normalize(endColorBeam * endColorBeam * endColorBeam) * (2.5 - beamPurpleReducer) * E_BEAM_I;
|
||||
vec3 beamOrange = endOrangeCol * (300.0 + 700.0 * beamOrangeIncreaser);
|
||||
|
||||
vec4 beams = vec4(0.0);
|
||||
float gradientMix = 1.0;
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
vec2 planeCoord = playerPos.xz + cameraPosition.xz;
|
||||
planeCoord *= (1.0 + i * 6.0 / sampleCount) * 0.0014;
|
||||
|
||||
float noise = BeamNoise(planeCoord, wind);
|
||||
#ifndef BEAMS_NEAR_PLAYER
|
||||
noise = max(0.75 - 1.0 / abs(noise - (4.0 + VdotUM * 2.0)), 0.0) * 3.0;
|
||||
#else
|
||||
noise = max(0.75 - 1.0 / abs(noise - (4.0 + dot(upVec, upVec) * 2.0)), 0.0) * 3.0;
|
||||
#endif
|
||||
|
||||
|
||||
if (noise > 0.0) {
|
||||
noise *= 0.65;
|
||||
float fireNoise = texture2DLod(noisetex, abs(planeCoord * 0.2) - wind, 0.0).b;
|
||||
noise *= 0.5 * fireNoise + 0.75;
|
||||
//noise = max0(noise); // fix NaNs
|
||||
noise = pow(noise, 1.75) * 2.9 / sampleCount;
|
||||
#ifndef BEAMS_NEAR_PLAYER
|
||||
noise *= VdotUM2;
|
||||
#endif
|
||||
|
||||
vec3 beamColor = beamPurple;
|
||||
beamColor += beamOrange * pow2(pow2(fireNoise - 0.5));
|
||||
beamColor *= gradientMix / sampleCount;
|
||||
|
||||
noise *= exp2(-6.0 * i / float(sampleCount));
|
||||
beams += vec4(noise * beamColor, noise);
|
||||
}
|
||||
gradientMix += 1.0;
|
||||
}
|
||||
#ifdef RAIN_ATMOSPHERE
|
||||
beams.rgb += 0.2 * isLightningActive();
|
||||
#endif
|
||||
beamMult *= pow(beams.a, beamPow) * 3.5;
|
||||
beams.rgb = sqrt(beams.rgb) * beamMult;
|
||||
|
||||
if(any(isnan(beams.rgb))) beams.rgb = vec3(0.0);
|
||||
|
||||
return beams.rgb;
|
||||
}
|
||||
|
||||
#endif //INCLUDE_ENDER_BEAMS
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#include "/lib/shaderSettings/enderStars.glsl"
|
||||
vec3 GetEnderStars(vec3 viewPos, float VdotU, float sizeMult, float starAmount) {
|
||||
vec3 wpos = normalize((gbufferModelViewInverse * vec4(viewPos * 1000.0, 1.0)).xyz);
|
||||
vec3 starCoord = 0.65 * wpos / (abs(wpos.y) + length(wpos.xz));
|
||||
vec2 starCoord2 = starCoord.xz * 0.5 / (END_STAR_SIZE * sizeMult);
|
||||
starCoord2 += VdotU < 0.0 ? 100.0 : 0.0;
|
||||
|
||||
const float starFactor = 1024.0;
|
||||
vec2 fractPart = fract(starCoord2 * starFactor);
|
||||
starCoord2 = floor(starCoord2 * starFactor) / starFactor;
|
||||
|
||||
float star = GetStarNoise(starCoord2.xy) * GetStarNoise(starCoord2.xy+0.1) * GetStarNoise(starCoord2.xy+0.23);
|
||||
|
||||
#if END_STAR_AMOUNT == 0
|
||||
star = max0(star - 0.77);
|
||||
#elif END_STAR_AMOUNT == 2
|
||||
star = max0((star + 0.15) * 0.9 - 0.7);
|
||||
#elif END_STAR_AMOUNT == 3
|
||||
star = max0((star + 0.4) * 0.8 - 0.7);
|
||||
#elif END_STAR_AMOUNT == 4
|
||||
star = max0((star + 0.5) * 0.8 - 0.7);
|
||||
#else
|
||||
star = max0(star - 0.7);
|
||||
#endif
|
||||
|
||||
star *= getStarEdgeFactor(fractPart, STAR_ROUNDNESS_END / 10.0, STAR_SOFTNESS_END);
|
||||
star = max0(star - starAmount * 0.1);
|
||||
star *= star;
|
||||
|
||||
vec3 starColor = GetStarColor(starCoord2,
|
||||
endSkyColor,
|
||||
vec3(STAR_COLOR_1_END_R, STAR_COLOR_1_END_G, STAR_COLOR_1_END_B),
|
||||
vec3(STAR_COLOR_2_END_R, STAR_COLOR_2_END_G, STAR_COLOR_2_END_B),
|
||||
vec3(STAR_COLOR_3_END_R, STAR_COLOR_3_END_G, STAR_COLOR_3_END_B),
|
||||
float(STAR_COLOR_VARIATION_END));
|
||||
|
||||
vec3 enderStars = star * starColor * 3000.0 * END_STAR_BRIGHTNESS;
|
||||
|
||||
float VdotUM1 = abs(VdotU);
|
||||
float VdotUM2 = pow2(1.0 - VdotUM1);
|
||||
enderStars *= VdotUM1 * VdotUM1 * (VdotUM2 + 0.015) + 0.015;
|
||||
|
||||
#if END_TWINKLING_STARS > 0
|
||||
enderStars *= getTwinklingStars(starCoord2, float(END_TWINKLING_STARS));
|
||||
#endif
|
||||
|
||||
return enderStars;
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#include "/lib/shaderSettings/bloom.glsl"
|
||||
#ifdef CAVE_FOG
|
||||
#include "/lib/atmospherics/fog/caveFactor.glsl"
|
||||
#endif
|
||||
|
||||
const float rainBloomAdd = 8.0;
|
||||
const float nightBloomAdd = 3.0;
|
||||
const float caveBloomAdd = 14.0;
|
||||
const float waterBloomAdd = 14.0;
|
||||
|
||||
#ifdef BORDER_FOG
|
||||
const float netherBloomAdd = 14.0;
|
||||
#else
|
||||
const float netherBloomAdd = 3.0;
|
||||
#endif
|
||||
|
||||
float GetBloomFog(float lViewPos) {
|
||||
#ifdef OVERWORLD
|
||||
float bloomFog = pow2(pow2(1.0 - exp(-lViewPos * (0.02 + 0.04 * float(isEyeInWater == 1)))));
|
||||
|
||||
float bloomFogMult;
|
||||
if (isEyeInWater != 1) {
|
||||
bloomFogMult = (rainFactor2 * rainBloomAdd + nightBloomAdd * (1.0 - sunFactor)) * eyeBrightnessM;
|
||||
#ifdef CAVE_FOG
|
||||
bloomFogMult += GetCaveFactor() * caveBloomAdd;
|
||||
#endif
|
||||
} else {
|
||||
bloomFogMult = waterBloomAdd;
|
||||
}
|
||||
#elif defined NETHER
|
||||
float farM = min(renderDistance, NETHER_VIEW_LIMIT); // consistency9023HFUE85JG
|
||||
float bloomFog = lViewPos / clamp(farM, 96.0, 256.0);
|
||||
bloomFog *= bloomFog * bloomFog;
|
||||
bloomFog = 1.0 - exp(-8.0 * bloomFog);
|
||||
bloomFog *= float(isEyeInWater == 0);
|
||||
|
||||
float bloomFogMult = netherBloomAdd;
|
||||
#else
|
||||
float bloomFog = 0.0;
|
||||
float bloomFogMult = 0.0;
|
||||
#endif
|
||||
|
||||
bloomFogMult *= BLOOM_STRENGTH * 8.33333;
|
||||
|
||||
return 1.0 + bloomFog * bloomFogMult;
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#ifndef INCLUDE_CAVE_FACTOR
|
||||
#define INCLUDE_CAVE_FACTOR
|
||||
#define CAVE_FOG_R_NEW 0.13 // [0.00 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.10 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.20 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.30 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.40 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.50 0.51 0.52 0.53 0.54 0.55 0.56 0.57 0.58 0.59 0.60 0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69 0.70 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.80 0.81 0.82 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.90 0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.00]
|
||||
#define CAVE_FOG_G_NEW 0.13 // [0.00 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.10 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.20 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.30 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.40 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.50 0.51 0.52 0.53 0.54 0.55 0.56 0.57 0.58 0.59 0.60 0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69 0.70 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.80 0.81 0.82 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.90 0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.00]
|
||||
#define CAVE_FOG_B_NEW 0.15 // [0.00 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.10 0.11 0.12 0.13 0.14 0.15 0.16 0.17 0.18 0.19 0.20 0.21 0.22 0.23 0.24 0.25 0.26 0.27 0.28 0.29 0.30 0.31 0.32 0.33 0.34 0.35 0.36 0.37 0.38 0.39 0.40 0.41 0.42 0.43 0.44 0.45 0.46 0.47 0.48 0.49 0.50 0.51 0.52 0.53 0.54 0.55 0.56 0.57 0.58 0.59 0.60 0.61 0.62 0.63 0.64 0.65 0.66 0.67 0.68 0.69 0.70 0.71 0.72 0.73 0.74 0.75 0.76 0.77 0.78 0.79 0.80 0.81 0.82 0.83 0.84 0.85 0.86 0.87 0.88 0.89 0.90 0.91 0.92 0.93 0.94 0.95 0.96 0.97 0.98 0.99 1.00]
|
||||
#define CAVE_FOG_I 1.00 //[0.20 0.25 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.0]
|
||||
|
||||
float GetCaveFactor() {
|
||||
return clamp(1.0 - cameraPosition.y / oceanAltitude, 0.0, 1.0 - eyeBrightnessM);
|
||||
}
|
||||
|
||||
vec3 caveFogColorRaw = vec3(CAVE_FOG_R_NEW, CAVE_FOG_G_NEW, CAVE_FOG_B_NEW) * CAVE_FOG_I;
|
||||
#if CAVE_LIGHTING < 100
|
||||
vec3 caveFogColor = caveFogColorRaw * 0.7;
|
||||
#elif CAVE_LIGHTING == 100
|
||||
vec3 caveFogColor = caveFogColorRaw * (0.7 + 0.3 * vsBrightness); // Default
|
||||
#elif CAVE_LIGHTING > 100
|
||||
vec3 caveFogColor = caveFogColorRaw;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
vec3 GetColoredLightFog(vec3 nPlayerPos, vec3 translucentMult, float lViewPos, float lViewPos1, float dither, float vlFactor) {
|
||||
vec3 lightFog = vec3(0.0);
|
||||
|
||||
float stepMult = 8.0;
|
||||
|
||||
#ifdef CAVE_SMOKE
|
||||
float caveFactor = GetCaveFactor() * (1.0 - clamp01(isEyeInWater));
|
||||
#endif
|
||||
|
||||
float maxDist = min(effectiveACTdistance * 0.5, far);
|
||||
int sampleCount = int(maxDist / stepMult + 0.001);
|
||||
vec3 traceAdd = nPlayerPos * stepMult;
|
||||
vec3 tracePos = traceAdd * dither;
|
||||
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
tracePos += traceAdd;
|
||||
|
||||
float lTracePos = length(tracePos);
|
||||
if (lTracePos > lViewPos1) break;
|
||||
if (any(greaterThan(abs(tracePos * 2.0), vec3(voxelVolumeSize)))) break;
|
||||
|
||||
vec3 voxelPos = SceneToVoxel(tracePos);
|
||||
voxelPos = clamp01(voxelPos / vec3(voxelVolumeSize));
|
||||
|
||||
vec4 lightVolume = GetLightVolume(voxelPos);
|
||||
vec3 lightSample = lightVolume.rgb;
|
||||
|
||||
#if defined END && END_CENTER_LIGHTING > 0 && MC_VERSION >= 10900 && defined END_CENTER_LIGHTING_AFFECT_BLOCKLIGHT
|
||||
vec3 endCenterCol = saturateColors(vec3(END_CENTER_LIGHTING_R, END_CENTER_LIGHTING_G, END_CENTER_LIGHTING_B), 1.1);
|
||||
vec3 endCenterPos = vec3(0.5, 60.5, 0.5) - (tracePos + cameraPositionBest);
|
||||
endCenterPos.y *= 0.66; // Make it a pill-shaped point light
|
||||
float rawDistance = length(endCenterPos);
|
||||
float endCenterLightDist = exp(-rawDistance * 0.62) * 100;
|
||||
lightSample = mix(lightSample, clamp01(saturateColors(endCenterCol, 1.3)), clamp01(endCenterLightDist) * (1.0 - vlFactor));
|
||||
#endif
|
||||
|
||||
float lTracePosM = length(
|
||||
vec3(
|
||||
tracePos.x,
|
||||
#if COLORED_LIGHTING_INTERNAL <= 512
|
||||
tracePos.y * 2.0,
|
||||
#elif COLORED_LIGHTING_INTERNAL == 768
|
||||
tracePos.y * 3.0,
|
||||
#elif COLORED_LIGHTING_INTERNAL == 1024
|
||||
tracePos.y * 4.0,
|
||||
#endif
|
||||
tracePos.z
|
||||
)
|
||||
);
|
||||
lightSample *= max0(1.0 - lTracePosM / maxDist);
|
||||
lightSample *= pow2(min1(lTracePos * 0.03125));
|
||||
|
||||
#ifdef CAVE_SMOKE
|
||||
if (caveFactor > 0.00001) {
|
||||
vec3 smokePos = 0.0025 * (tracePos + cameraPosition);
|
||||
vec3 smokeWind = frameTimeCounter * vec3(0.006, 0.003, 0.0);
|
||||
float smoke = Noise3D(smokePos + smokeWind)
|
||||
* Noise3D(smokePos * 3.0 - smokeWind)
|
||||
* Noise3D(smokePos * 9.0 + smokeWind);
|
||||
smoke = smoothstep1(smoke);
|
||||
lightSample *= mix(1.0, smoke * 16.0, caveFactor);
|
||||
lightSample += caveFogColor * pow2(smoke) * 0.05 * caveFactor;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (lTracePos > lViewPos) lightSample *= translucentMult;
|
||||
lightFog += lightSample;
|
||||
}
|
||||
|
||||
#ifdef NETHER
|
||||
lightFog *= netherColor * 5.0;
|
||||
#endif
|
||||
|
||||
lightFog *= 1.0 - maxBlindnessDarkness;
|
||||
lightFog = pow(lightFog / sampleCount, vec3(0.25));
|
||||
|
||||
return lightFog;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#if !defined END_CENTER_FOG
|
||||
#define END_CENTER_FOG
|
||||
float doEndCenterFog(vec3 ro, vec3 rayDir, float wsdist, float falloff) { // Thanks to FoZy STYLE
|
||||
vec3 d = ro - vec3(0.5, 60.5, 0.5); // Light source vector
|
||||
d.y *= 0.7;
|
||||
rayDir.y *= 0.7;
|
||||
|
||||
float a = falloff * dot(rayDir, rayDir);
|
||||
float b = 2.0 * falloff * dot(rayDir, d);
|
||||
float c = 1.0 + falloff * dot(d, d);
|
||||
|
||||
float sqrtDiscr = max(0.001, sqrt(4.0 * a * c - b * b));
|
||||
float upper = (2.0 * a * wsdist + b) / sqrtDiscr;
|
||||
float lower = b / sqrtDiscr;
|
||||
|
||||
return 2.0 * (atan(upper) - atan(lower)) / sqrtDiscr;
|
||||
}
|
||||
#endif
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
#include "/lib/shaderSettings/mainFog.glsl"
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
#include "/lib/colors/colorMultipliers.glsl"
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_ATMOSPHERE
|
||||
#include "/lib/colors/moonPhaseInfluence.glsl"
|
||||
#endif
|
||||
|
||||
#ifdef BORDER_FOG
|
||||
#ifdef OVERWORLD
|
||||
#include "/lib/atmospherics/sky.glsl"
|
||||
#elif defined NETHER || defined END
|
||||
#include "/lib/colors/skyColors.glsl"
|
||||
#endif
|
||||
|
||||
void DoBorderFog(inout vec4 color, inout float skyFade, float lPos, float VdotU, float VdotS, float dither) {
|
||||
#ifdef OVERWORLD
|
||||
float fog = lPos / renderDistance;
|
||||
fog = pow2(pow2(fog));
|
||||
#ifndef DISTANT_HORIZONS
|
||||
fog = pow2(pow2(fog));
|
||||
#endif
|
||||
fog = 1.0 - exp(-BORDER_FOG_DISTANCE_OVERWORLD * fog);
|
||||
#endif
|
||||
#ifdef NETHER
|
||||
float farM = min(renderDistance, NETHER_VIEW_LIMIT); // consistency9023HFUE85JG
|
||||
float fog = lPos / farM;
|
||||
fog = fog * 0.3 + 0.7 * pow(fog * BORDER_FOG_DISTANCE_NETHER / 3, 256.0 / max(farM, 256.0));
|
||||
#endif
|
||||
#ifdef END
|
||||
float fog = lPos / renderDistance;
|
||||
fog = pow2(pow2(fog));
|
||||
fog = 1.0 - exp(-BORDER_FOG_DISTANCE_END * fog);
|
||||
#endif
|
||||
|
||||
#ifdef IRIS_FEATURE_FADE_VARIABLE
|
||||
#if defined GBUFFERS_WATER || defined DEFERRED1
|
||||
float chunkFadeM = mix(1.0, chunkFade, pow2(clamp01(lPos * 0.015))); // don't do fade very close to the player
|
||||
fog = mix(1.0, fog, chunkFadeM);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (fog > 0.0) {
|
||||
fog = clamp(fog, 0.0, 1.0);
|
||||
|
||||
#ifdef OVERWORLD
|
||||
vec3 fogColorM = GetSky(VdotU, VdotS, dither, true, false);
|
||||
#define BORDER_FOG_DENSITY BORDER_FOG_DENSITY_OVERWORLD
|
||||
#elif defined NETHER
|
||||
vec3 fogColorM = netherColor;
|
||||
#define BORDER_FOG_DENSITY BORDER_FOG_DENSITY_NETHER
|
||||
#else
|
||||
vec3 fogColorM = endSkyColor;
|
||||
#define BORDER_FOG_DENSITY BORDER_FOG_DENSITY_END
|
||||
#endif
|
||||
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
fogColorM *= atmColorMult;
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_ATMOSPHERE
|
||||
fogColorM *= moonPhaseInfluence;
|
||||
#endif
|
||||
|
||||
fog *= BORDER_FOG_DENSITY;
|
||||
color = mix(color, vec4(fogColorM, 0.0), fog);
|
||||
|
||||
#ifndef GBUFFERS_WATER
|
||||
skyFade = fog;
|
||||
#else
|
||||
skyFade = fog * (1.0 - isEyeInWater);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CAVE_FOG
|
||||
#include "/lib/atmospherics/fog/caveFactor.glsl"
|
||||
|
||||
void DoCaveFog(inout vec4 color, float lViewPos) {
|
||||
float fog = GetCaveFactor() * (0.9 - 0.9 * exp(- lViewPos * 0.015 * CAVE_FOG_DENSITY));
|
||||
|
||||
color = mix(color, vec4(caveFogColor, 0.0), fog);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ATMOSPHERIC_FOG
|
||||
#include "/lib/colors/lightAndAmbientColors.glsl"
|
||||
#include "/lib/colors/skyColors.glsl"
|
||||
|
||||
// SRATA: Atm. fog starts reducing above this altitude
|
||||
// CRFTM: Atm. fog continues reducing for this meters
|
||||
#ifdef OVERWORLD
|
||||
#define atmFogSRATA ATM_FOG_ALTITUDE + 0.1
|
||||
#ifndef DISTANT_HORIZONS
|
||||
float atmFogCRFTM = 60.0;
|
||||
#else
|
||||
float atmFogCRFTM = 90.0;
|
||||
#endif
|
||||
|
||||
vec3 GetAtmFogColor(float altitudeFactorRaw, float VdotS) {
|
||||
vec3 atmFogColor = vec3(ATMOSPHERIC_FOG_R_NEW, ATMOSPHERIC_FOG_G_NEW, ATMOSPHERIC_FOG_B_NEW) * ATMOSPHERIC_FOG_I;
|
||||
#ifdef RADIOACTIVE_ATMOSPHERIC_FOG
|
||||
atmFogColor *= GetLuminance(atmFogColor) * 10;
|
||||
#endif
|
||||
|
||||
float nightFogMult = 2.5 - 0.625 * max(pow2(pow2(altitudeFactorRaw)), rainFactor);
|
||||
float dayNightFogBlend = pow(invNightFactor, 4.0 - VdotS - 2.5 * sunVisibility2);
|
||||
return atmFogColor * mix(
|
||||
nightUpSkyColor * (nightFogMult - dayNightFogBlend * nightFogMult),
|
||||
dayDownSkyColor * (0.9 + 0.3 * noonFactor),
|
||||
dayNightFogBlend
|
||||
);
|
||||
}
|
||||
#else
|
||||
float atmFogSRATA = 55.1;
|
||||
float atmFogCRFTM = 30.0;
|
||||
#endif
|
||||
|
||||
float GetAtmFogAltitudeFactor(float altitude) {
|
||||
float altitudeFactor = pow2(1.0 - clamp(altitude - atmFogSRATA, 0.0, atmFogCRFTM) / atmFogCRFTM);
|
||||
#ifndef LIGHTSHAFTS_ACTIVE
|
||||
altitudeFactor = mix(altitudeFactor, 1.0, rainFactor * 0.2);
|
||||
#endif
|
||||
return altitudeFactor;
|
||||
}
|
||||
|
||||
void DoAtmosphericFog(inout vec4 color, vec3 playerPos, float lViewPos, float VdotS) {
|
||||
#ifndef DISTANT_HORIZONS
|
||||
float renDisFactor = min1(192.0 / renderDistance);
|
||||
|
||||
#if ATM_FOG_DISTANCE != 100
|
||||
#define ATM_FOG_DISTANCE_M 100.0 / ATM_FOG_DISTANCE;
|
||||
renDisFactor *= ATM_FOG_DISTANCE_M;
|
||||
#endif
|
||||
float fog = 1.0 - exp(-pow(lViewPos * (0.001 - 0.0007 * rainFactor), 2.0 - rainFactor2) * lViewPos * renDisFactor);
|
||||
#else
|
||||
float fog = pow2(1.0 - exp(-max0(lViewPos - 40.0) * (0.7 + 0.7 * rainFactor) / ATM_FOG_DISTANCE));
|
||||
#endif
|
||||
|
||||
float atmFogA = 1.0;
|
||||
atmFogA *= ATMOSPHERIC_FOG_DENSITY * ATM_FOG_MULT;
|
||||
fog *= atmFogA - 0.1 - 0.15 * invRainFactor;
|
||||
|
||||
float altitudeFactorRaw = GetAtmFogAltitudeFactor(playerPos.y + cameraPosition.y);
|
||||
|
||||
#ifndef DISTANT_HORIZONS
|
||||
float altitudeFactor = altitudeFactorRaw * 0.9 + 0.1;
|
||||
#else
|
||||
float altitudeFactor = altitudeFactorRaw * 0.8 + 0.2;
|
||||
#endif
|
||||
|
||||
#ifdef OVERWORLD
|
||||
altitudeFactor *= 1.0 - 0.75 * GetAtmFogAltitudeFactor(cameraPosition.y) * invRainFactor;
|
||||
|
||||
#if defined SPECIAL_BIOME_WEATHER || RAIN_STYLE == 2
|
||||
if (isEyeInWater == 0) {
|
||||
#if RAIN_STYLE == 2
|
||||
float factor = 1.0;
|
||||
#else
|
||||
float factor = max(inSnowy, inDry);
|
||||
#endif
|
||||
|
||||
float fogFactor = 4.0;
|
||||
#ifdef SPECIAL_BIOME_WEATHER
|
||||
fogFactor += 2.0 * inDry;
|
||||
#endif
|
||||
fogFactor *= 0.5 + 0.5 * sunVisibility;
|
||||
|
||||
float fogIntense = pow2(1.0 - exp(-lViewPos * fogFactor / ATM_FOG_DISTANCE));
|
||||
fog = mix(fog, fogIntense / altitudeFactor, 0.8 * rainFactor * factor);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CAVE_FOG
|
||||
fog *= 0.2 + 0.8 * sqrt2(eyeBrightnessM);
|
||||
fog *= 1.0 - GetCaveFactor();
|
||||
#else
|
||||
fog *= eyeBrightnessM;
|
||||
#endif
|
||||
#else
|
||||
fog *= 0.5;
|
||||
#endif
|
||||
|
||||
fog *= altitudeFactor;
|
||||
|
||||
if (fog > 0.0) {
|
||||
fog = clamp(fog, 0.0, 1.0);
|
||||
|
||||
#ifdef OVERWORLD
|
||||
vec3 fogColorM = GetAtmFogColor(altitudeFactorRaw, VdotS);
|
||||
#else
|
||||
vec3 fogColorM = endSkyColor * 1.5;
|
||||
#endif
|
||||
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
fogColorM *= atmColorMult;
|
||||
#endif
|
||||
#ifdef MOON_PHASE_INF_ATMOSPHERE
|
||||
fogColorM *= moonPhaseInfluence;
|
||||
#endif
|
||||
|
||||
color = mix(color, vec4(fogColorM, 0.0), fog);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "/lib/atmospherics/fog/waterFog.glsl"
|
||||
|
||||
void DoWaterFog(inout vec4 color, float lViewPos) {
|
||||
float fog = GetWaterFog(lViewPos);
|
||||
color = mix(color, vec4(waterFogColor, 0), fog);
|
||||
}
|
||||
|
||||
void DoLavaFog(inout vec4 color, float lViewPos) {
|
||||
float fog = (lViewPos * 3.0 - gl_Fog.start) * gl_Fog.scale;
|
||||
|
||||
#ifdef LESS_LAVA_FOG
|
||||
fog = sqrt(fog) * 0.4;
|
||||
#endif
|
||||
|
||||
fog = 1.0 - exp(-fog);
|
||||
|
||||
fog = clamp(fog, 0.0, 1.0);
|
||||
color = mix(color, vec4(fogColor * 5.0, 0.0), fog);
|
||||
}
|
||||
|
||||
void DoPowderSnowFog(inout vec4 color, float lViewPos) {
|
||||
float fog = lViewPos;
|
||||
|
||||
#ifdef LESS_LAVA_FOG
|
||||
fog = sqrt(fog) * 0.4;
|
||||
#endif
|
||||
|
||||
fog *= fog;
|
||||
fog = 1.0 - exp(-fog);
|
||||
|
||||
fog = clamp(fog, 0.0, 1.0);
|
||||
color = mix(color, vec4(fogColor, 0.0), fog);
|
||||
}
|
||||
|
||||
void DoBlindnessFog(inout vec4 color, float lViewPos) {
|
||||
float fog = lViewPos * 0.3 * blindness;
|
||||
fog *= fog;
|
||||
fog = 1.0 - exp(-fog);
|
||||
|
||||
fog = clamp(fog, 0.0, 1.0);
|
||||
color *= 1.0 - fog;
|
||||
}
|
||||
|
||||
void DoDarknessFog(inout vec4 color, float lViewPos) {
|
||||
float fog = lViewPos * 0.075 * darknessFactor;
|
||||
fog *= fog;
|
||||
fog *= fog;
|
||||
color *= exp(-fog);
|
||||
}
|
||||
|
||||
void DoFog(inout vec4 color, inout float skyFade, float lViewPos, vec3 playerPos, float VdotU, float VdotS, float dither, bool isReflection, float lBlockPos) {
|
||||
#ifdef CAVE_FOG
|
||||
DoCaveFog(color, lViewPos);
|
||||
#endif
|
||||
#ifdef ATMOSPHERIC_FOG
|
||||
float lViewPosAtm = lViewPos;
|
||||
// Reduce fog if the reflecting block is already behind fog, and fogging the reflection would result in too much fog
|
||||
if (isReflection) lViewPosAtm *= 0.2 + 0.8 * sqrt1(max0(1.0 - lBlockPos / lViewPos));
|
||||
DoAtmosphericFog(color, playerPos, lViewPosAtm, VdotS);
|
||||
#endif
|
||||
#ifdef BORDER_FOG
|
||||
DoBorderFog(color, skyFade, max(length(playerPos.xz), abs(playerPos.y)), VdotU, VdotS, dither);
|
||||
#endif
|
||||
|
||||
if (isEyeInWater == 1) DoWaterFog(color, lViewPos);
|
||||
else if (isEyeInWater == 2) DoLavaFog(color, lViewPos);
|
||||
else if (isEyeInWater == 3) DoPowderSnowFog(color, lViewPos);
|
||||
|
||||
if (blindness > 0.00001) DoBlindnessFog(color, lViewPos);
|
||||
if (darknessFactor > 0.00001) DoDarknessFog(color, lViewPos);
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#ifndef INCLUDE_WATER_FOG
|
||||
#define INCLUDE_WATER_FOG
|
||||
|
||||
float GetWaterFog(float lViewPos) {
|
||||
#if WATER_FOG_MULT != 100
|
||||
#define WATER_FOG_MULT_M WATER_FOG_MULT * 0.01;
|
||||
lViewPos *= WATER_FOG_MULT_M;
|
||||
#endif
|
||||
|
||||
#if LIGHTSHAFT_QUALI > 0 && SHADOW_QUALITY > -1
|
||||
float fog = lViewPos / 48.0;
|
||||
fog *= fog;
|
||||
#else
|
||||
float fog = lViewPos / 32.0;
|
||||
#endif
|
||||
|
||||
return 1.0 - exp(-fog);
|
||||
}
|
||||
#endif
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
vec3 GetNetherNoise(vec3 viewPos, float VdotU, float dither) {
|
||||
float visibility = clamp01(VdotU * 1.875 - 0.225);
|
||||
visibility *= 1.0 - VdotU * 0.75 - maxBlindnessDarkness;
|
||||
|
||||
if (visibility > 0.0) {
|
||||
vec3 spots = vec3(0.0);
|
||||
|
||||
float eyeAltitude1 = eyeAltitude * 0.005;
|
||||
float noiseHeightFactor = max(0.0, 1.5 - eyeAltitude1 / (eyeAltitude1 + 1.0));
|
||||
noiseHeightFactor *= noiseHeightFactor;
|
||||
float noiseHeight = noiseHeightFactor * 0.5;
|
||||
|
||||
vec3 wpos = (gbufferModelViewInverse * vec4(viewPos, 1.0)).xyz;
|
||||
wpos.xz /= wpos.y;
|
||||
|
||||
vec2 cameraPositionM = cameraPosition.xz * 0.0075;
|
||||
cameraPositionM.x += frameTimeCounter * 0.004;
|
||||
|
||||
int sampleCount = 10;
|
||||
int sampleCountP = sampleCount + 5;
|
||||
float ditherM = dither + 5.0;
|
||||
float wind = fract(frameTimeCounter * 0.0125);
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
float current = pow2((i + ditherM) / sampleCountP);
|
||||
|
||||
vec2 planePos = wpos.xz * (0.8 + current) * noiseHeight;
|
||||
planePos = (planePos * 0.5 + cameraPositionM * 0.5) * 1.5;
|
||||
float noiseSpots = texture2DLod(noisetex, planePos * 0.5, 0.0).g;
|
||||
vec3 noise = texture2DLod(noisetex, vec2(noiseSpots) + wind, 0.0).g * netherColor * 2.5 - netherColor * 1.3;
|
||||
|
||||
float currentM = 1.0 - current;
|
||||
spots += noise * currentM * 6.0;
|
||||
}
|
||||
|
||||
#ifdef RAIN_ATMOSPHERE
|
||||
spots += 2.0 * isLightningActive();
|
||||
#endif
|
||||
|
||||
return spots * visibility / sampleCount;
|
||||
}
|
||||
|
||||
return vec3(0.0);
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
vec4 GetNetherStorm(vec3 color, vec3 translucentMult, vec3 nPlayerPos, vec3 playerPos, float lViewPos, float lViewPos1, float dither) {
|
||||
if (isEyeInWater != 0) return vec4(0.0);
|
||||
vec4 netherStorm = vec4(1.0, 1.0, 1.0, 0.0);
|
||||
|
||||
#ifdef BORDER_FOG
|
||||
float maxDist = min(renderDistance, NETHER_VIEW_LIMIT); // consistency9023HFUE85JG
|
||||
#else
|
||||
float maxDist = renderDistance;
|
||||
#endif
|
||||
|
||||
#ifndef LOW_QUALITY_NETHER_STORM
|
||||
int sampleCount = int(maxDist / 8.0 + 0.001);
|
||||
|
||||
vec3 traceAdd = nPlayerPos * maxDist / sampleCount;
|
||||
vec3 tracePos = cameraPosition;
|
||||
tracePos += traceAdd * dither;
|
||||
#else
|
||||
int sampleCount = int(maxDist / 16.0 + 0.001);
|
||||
|
||||
vec3 traceAdd = 0.75 * nPlayerPos * maxDist / sampleCount;
|
||||
vec3 tracePos = cameraPosition;
|
||||
tracePos += traceAdd * dither;
|
||||
tracePos += traceAdd * sampleCount * 0.25;
|
||||
#endif
|
||||
|
||||
vec3 translucentMultM = pow(translucentMult, vec3(1.0 / sampleCount));
|
||||
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
tracePos += traceAdd;
|
||||
|
||||
vec3 tracedPlayerPos = tracePos - cameraPosition;
|
||||
float lTracePos = length(tracedPlayerPos);
|
||||
if (lTracePos > lViewPos1) break;
|
||||
|
||||
vec3 wind = vec3(frameTimeCounter * 0.002);
|
||||
|
||||
vec3 tracePosM = tracePos * 0.001;
|
||||
tracePosM.y += tracePosM.x;
|
||||
tracePosM += Noise3D(tracePosM - wind) * 0.01;
|
||||
tracePosM = tracePosM * vec3(2.0, 0.5, 2.0);
|
||||
|
||||
float traceAltitudeM = abs(tracePos.y - NETHER_STORM_LOWER_ALT);
|
||||
if (tracePos.y < NETHER_STORM_LOWER_ALT) traceAltitudeM *= 10.0;
|
||||
traceAltitudeM = 1.0 - min1(abs(traceAltitudeM) / NETHER_STORM_HEIGHT);
|
||||
|
||||
for (int h = 0; h < 4; h++) {
|
||||
float stormSample = pow2(Noise3D(tracePosM + wind));
|
||||
stormSample *= traceAltitudeM;
|
||||
stormSample = pow2(pow2(stormSample));
|
||||
stormSample *= sqrt1(max0(1.0 - lTracePos / maxDist));
|
||||
|
||||
netherStorm.a += stormSample;
|
||||
tracePosM *= 2.0;
|
||||
wind *= -2.0;
|
||||
}
|
||||
|
||||
#ifdef RAIN_ATMOSPHERE
|
||||
vec3 lightningPos = getLightningPos(tracePos - cameraPosition, lightningBoltPosition.xyz, false);
|
||||
vec2 lightningAdd = lightningFlashEffect(lightningPos, vec3(1.0), 150.0, 0.0, 0) * isLightningActive() * 8.0;
|
||||
netherStorm.rgb += lightningAdd.y;
|
||||
#endif
|
||||
|
||||
if (lTracePos > lViewPos) netherStorm.rgb *= translucentMultM;
|
||||
}
|
||||
|
||||
#ifdef LOW_QUALITY_NETHER_STORM
|
||||
netherStorm.a *= 1.8;
|
||||
#endif
|
||||
|
||||
netherStorm.a = min1(netherStorm.a * NETHER_STORM_I);
|
||||
|
||||
netherStorm.rgb *= netherColor * 3.0 * (1.0 - maxBlindnessDarkness);
|
||||
|
||||
//if (netherStorm.a > 0.98) netherStorm.rgb = vec3(1,0,1);
|
||||
//netherStorm.a *= 1.0 - max0(netherStorm.a - 0.98) * 50.0;
|
||||
|
||||
return netherStorm;
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
#include "/lib/atmospherics/stars.glsl"
|
||||
|
||||
// Nebula implementation by flytrap https://godotshaders.com/shader/2d-nebula-shader/
|
||||
#include "/lib/shaderSettings/stars.glsl"
|
||||
#include "/lib/shaderSettings/nightNebula.glsl"
|
||||
|
||||
#ifndef HQ_NIGHT_NEBULA
|
||||
const int OCTAVE = 5;
|
||||
#else
|
||||
const int OCTAVE = 8;
|
||||
#endif
|
||||
|
||||
const float timescale = 5.0;
|
||||
const float zoomScale = NEBULA_ZOOM_LEVEL;
|
||||
|
||||
const vec4 CLOUD1_COL = vec4(NEBULA_R_1, NEBULA_G_1, NEBULA_B_1, 0.4);
|
||||
const vec4 CLOUD2_COL = vec4(NEBULA_R_2, NEBULA_G_2, NEBULA_B_2, 0.2);
|
||||
const vec4 CLOUD3_COL = vec4(NEBULA_R_3, NEBULA_G_3, NEBULA_B_3, 1.0);
|
||||
|
||||
float sinM(float x) {
|
||||
return sin(mod(x, 2.0 * pi));
|
||||
}
|
||||
|
||||
float cosM(float x) {
|
||||
return cos(mod(x, 2.0 * pi));
|
||||
}
|
||||
|
||||
float rand(vec2 inCoord){
|
||||
return fract(sinM(dot(inCoord, vec2(23.53, 44.0))) * 42350.45);
|
||||
}
|
||||
|
||||
float perlin(vec2 inCoord){
|
||||
vec2 i = floor(inCoord);
|
||||
vec2 j = fract(inCoord);
|
||||
vec2 coord = smoothstep(0.0, 1.0, j);
|
||||
|
||||
float a = rand(i);
|
||||
float b = rand(i + vec2(1.0, 0.0));
|
||||
float c = rand(i + vec2(0.0, 1.0));
|
||||
float d = rand(i + vec2(1.0, 1.0));
|
||||
|
||||
return mix(mix(a, b, coord.x), mix(c, d, coord.x), coord.y);
|
||||
}
|
||||
|
||||
float fbmCloud(vec2 inCoord, float minimum){
|
||||
float value = 0.0;
|
||||
float scale = NEBULA_AMOUNT * 0.1 + 0.45;
|
||||
|
||||
for (int i = 0; i < OCTAVE; i++){
|
||||
value += perlin(inCoord) * scale;
|
||||
inCoord *= 2.0;
|
||||
scale *= 0.5;
|
||||
}
|
||||
|
||||
return smoothstep(0.0, 1.0, (smoothstep(minimum, 1.0, value) - minimum) / (1.0 - minimum));
|
||||
}
|
||||
|
||||
float fbmCloud2(vec2 inCoord, float minimum){
|
||||
float value = 0.0;
|
||||
float scale = (NEBULA_AMOUNT + 0.1) * 0.25 + 0.35;
|
||||
|
||||
for (int i = 0; i < OCTAVE; i++){
|
||||
value += perlin(inCoord) * scale;
|
||||
inCoord *= 2.0;
|
||||
scale *= 0.5;
|
||||
}
|
||||
|
||||
return (smoothstep(minimum, 1.0, value) - minimum) / (1.0 - minimum);
|
||||
}
|
||||
|
||||
vec2 warpCoords(vec2 coord, float warpAmount) {
|
||||
float angle = perlin(coord * 0.5) * 6.28318 * warpAmount;
|
||||
float strength = perlin(coord * 0.7 + 0.5) * warpAmount;
|
||||
vec2 offset = vec2(cos(angle), sin(angle)) * strength;
|
||||
return coord + offset;
|
||||
}
|
||||
|
||||
vec3 GetNightNebula(vec3 viewPos, float VdotU, float VdotS) {
|
||||
float VdotUFactor = max0(VdotU);
|
||||
float starsAroundSun = 1.0;
|
||||
#ifdef CELESTIAL_BOTH_HEMISPHERES
|
||||
VdotUFactor = VdotU;
|
||||
#ifdef SUN_MOON_HORIZON
|
||||
starsAroundSun = max0(sign(VdotU));
|
||||
#endif
|
||||
#endif
|
||||
float originalVdotUFactor = VdotUFactor;
|
||||
float horizonPower = NEBULA_HORIZON_STRENGTH * 0.05 + 0.5;
|
||||
|
||||
#if NEBULA_HORIZON_STRENGTH < 10
|
||||
VdotUFactor = pow(VdotUFactor, horizonPower);
|
||||
#endif
|
||||
|
||||
float nebulaFactor = pow2(VdotUFactor * min1(nightFactor * 2.0));
|
||||
|
||||
#if NEBULA_HORIZON_STRENGTH < 10
|
||||
float brightnessCompensation = 1.0 - (1.0 - horizonPower) * 0.5 * max0(originalVdotUFactor);
|
||||
nebulaFactor *= brightnessCompensation;
|
||||
#endif
|
||||
|
||||
#ifdef CLEAR_SKY_WHEN_RAINING
|
||||
nebulaFactor *= min1(invRainFactor + 0.4);
|
||||
#else
|
||||
nebulaFactor *= invRainFactor;
|
||||
#endif
|
||||
|
||||
nebulaFactor -= maxBlindnessDarkness;
|
||||
|
||||
#if NEBULA_MOON_CONDITION == 1
|
||||
if (moonPhase != 4) return vec3(0.0);
|
||||
#elif NEBULA_MOON_CONDITION == 2
|
||||
if (moonPhase != 0) return vec3(0.0);
|
||||
#elif NEBULA_MOON_CONDITION == 3
|
||||
if (moonPhase == 0 || moonPhase == 4) return vec3(0.0);
|
||||
#elif NEBULA_MOON_CONDITION == 4
|
||||
nebulaFactor *= step(0.5, hash11(float(worldDay) + float(moonPhase) * 37.0));
|
||||
#elif NEBULA_MOON_CONDITION == 5
|
||||
nebulaFactor *= clamp01(max(moonPhase, 1) % 4);
|
||||
#endif
|
||||
|
||||
if (nebulaFactor < 0.001) return vec3(0.0);
|
||||
|
||||
vec2 UV = GetStarCoord(viewPos, 0.75);
|
||||
float TIME = syncedTime * 0.003 + 15.0;
|
||||
float timescaled = TIME * timescale;
|
||||
|
||||
float sinTime = sinM(0.07 * timescaled);
|
||||
float cosTime06 = cosM(0.06 * timescaled);
|
||||
float cosTime07 = cosM(0.07 * timescaled);
|
||||
|
||||
float tide = 0.05 * sinM(TIME);
|
||||
float tide2 = 0.06 * cosM(0.3 * TIME);
|
||||
|
||||
vec4 nebulaTexture = vec4(vec3(0.0), 0.5 + 0.2 * sinM(0.23 * TIME + UV.x - UV.y));
|
||||
|
||||
#if PIXELATED_NEBULA > 0
|
||||
float pixelFactor = PIXELATED_NEBULA * 2.0;
|
||||
vec2 baseUV = floor(UV * pixelFactor) / pixelFactor;
|
||||
#else
|
||||
vec2 baseUV = UV;
|
||||
#endif
|
||||
|
||||
vec2 scaledUV = baseUV * zoomScale;
|
||||
vec2 cloudUV2 = vec2(scaledUV.x + 0.03 * timescaled * sinTime, scaledUV.y + 0.03 * timescaled * cosTime06);
|
||||
vec2 cloudUV3 = vec2(scaledUV.x + 0.027 * timescaled * sinTime, scaledUV.y + 0.025 * timescaled * cosTime06);
|
||||
vec2 cloudUV4 = vec2(scaledUV.x + 0.021 * timescaled * sinTime, scaledUV.y + 0.021 * timescaled * cosTime07);
|
||||
|
||||
#if NEBULA_PATTERN_WARP > 0
|
||||
cloudUV2 = warpCoords(cloudUV2, NEBULA_PATTERN_WARP * 0.1);
|
||||
cloudUV3 = warpCoords(cloudUV3, NEBULA_PATTERN_WARP * 0.1);
|
||||
cloudUV4 = warpCoords(cloudUV4, NEBULA_PATTERN_WARP * 0.1);
|
||||
#endif
|
||||
|
||||
nebulaTexture += fbmCloud2(cloudUV3, 0.24 + tide) * CLOUD1_COL;
|
||||
nebulaTexture += fbmCloud(cloudUV2 * 0.9, 0.33 - tide) * CLOUD2_COL;
|
||||
nebulaTexture = mix(nebulaTexture, CLOUD3_COL, fbmCloud(vec2(0.9 * cloudUV4.x, 0.9 * cloudUV4.y), 0.25 + tide2));
|
||||
|
||||
nebulaFactor *= 1.0 - pow2(pow2(pow2(abs(VdotS)))) * starsAroundSun;
|
||||
nebulaTexture.a *= min1(pow2(pow2(nebulaTexture.a))) * nebulaFactor;
|
||||
|
||||
float starFactor = 1024.0;
|
||||
UV /= STAR_SIZE * (0.75 + 0.25 * NEBULA_STAR_SIZE);
|
||||
vec2 starCoord = floor(UV * 0.25 * starFactor) / starFactor;
|
||||
vec2 fractPart = fract(UV * 0.25 * starFactor);
|
||||
|
||||
float starAmount = (2.0 - NEBULA_STAR_AMOUNT) * 0.1;
|
||||
float starIntensity = GetStarNoise(starCoord) * GetStarNoise(starCoord + 0.1) - (starAmount + 0.5);
|
||||
starIntensity *= getStarEdgeFactor(fractPart, STAR_ROUNDNESS_OW / 10.0, STAR_SOFTNESS_OW);
|
||||
|
||||
#if TWINKLING_STARS > 0
|
||||
starIntensity *= getTwinklingStars(starCoord * 4, float(TWINKLING_STARS));
|
||||
#endif
|
||||
|
||||
float starGlow = pow2(clamp(starIntensity, 0.0, 0.3 + starAmount)) * starBrightness * NEBULA_STAR_BRIGHTNESS;
|
||||
|
||||
#ifdef NEBULA_ONLY_STARS
|
||||
nebulaTexture.a = step(0.15, nebulaTexture.a);
|
||||
nebulaTexture.rgb = vec3(3.0 * starGlow);
|
||||
#else
|
||||
nebulaTexture.rgb *= 1.5 + 10.0 * starGlow;
|
||||
#endif
|
||||
|
||||
#if NIGHT_NEBULA_I != 100
|
||||
#define NIGHT_NEBULA_IM NIGHT_NEBULA_I * 0.01
|
||||
nebulaTexture.a *= NIGHT_NEBULA_IM;
|
||||
#endif
|
||||
|
||||
#if NEBULA_SATURATION != 10
|
||||
nebulaTexture.rgb = rgb2hsv(nebulaTexture.rgb);
|
||||
nebulaTexture.g *= NEBULA_SATURATION * 0.1;
|
||||
nebulaTexture.rgb = hsv2rgb(nebulaTexture.rgb);
|
||||
#endif
|
||||
|
||||
#ifdef ATM_COLOR_MULTS
|
||||
nebulaTexture.rgb *= sqrtAtmColorMult; // C72380KD - Reduced atmColorMult impact on some things
|
||||
#endif
|
||||
|
||||
return max(nebulaTexture.rgb * nebulaTexture.a, vec3(0.0));
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
#include "/lib/colors/lightAndAmbientColors.glsl"
|
||||
|
||||
vec3 beamCol = normalize(ColorBeam) * 3.0 * (2.5 - 1.0 * vlFactor) * OVERWORLD_BEAMS_INTENSITY;
|
||||
|
||||
vec2 wind = vec2(syncedTime * 0.0056);
|
||||
|
||||
float BeamNoise(vec2 planeCoord, vec2 wind) {
|
||||
float noise = texture2DLod(noisetex, planeCoord * 0.275 - wind * 0.0625, 0.0).b;
|
||||
noise+= texture2DLod(noisetex, planeCoord * 0.34375 + wind * 0.0575, 0.0).b * 10.0;
|
||||
|
||||
return noise;
|
||||
}
|
||||
|
||||
vec4 DrawOverworldBeams(float VdotU, vec3 playerPos, vec3 viewPos) {
|
||||
float visibility = 1.0 - sunVisibility - maxBlindnessDarkness;
|
||||
#if OVERWORLD_BEAMS_CONDITION == 0
|
||||
visibility -= moonPhase;
|
||||
#endif
|
||||
if (visibility > 0.0) {
|
||||
vec3 result = vec3(0.0);
|
||||
|
||||
int sampleCount = 8;
|
||||
|
||||
float VdotUM = 1.0 - VdotU * VdotU;
|
||||
float VdotUM2 = VdotUM + smoothstep1(pow2(pow2(1.0 - abs(VdotU)))) * 0.2;
|
||||
|
||||
vec4 beams = vec4(0.0);
|
||||
float gradientMix = 1.0;
|
||||
|
||||
#ifdef AURORA_INFLUENCE
|
||||
beamCol = getAuroraAmbientColor(beamCol, viewPos, 1.0, AURORA_CLOUD_INFLUENCE_INTENSITY, 0.85) * OVERWORLD_BEAMS_INTENSITY;
|
||||
#endif
|
||||
|
||||
for(int i = 0; i < sampleCount; i++) {
|
||||
vec2 planeCoord = (playerPos.xz + cameraPosition.xz) * (1.0 + i * 6.0 / sampleCount) * 0.0014;
|
||||
|
||||
float noise = BeamNoise(planeCoord, wind);
|
||||
noise = max(0.92 - 1.0 / abs(noise - (2.5 + VdotUM * 2.0)), 0.0) * 2.5;
|
||||
|
||||
if (noise > 0.0) {
|
||||
noise *= 0.55;
|
||||
float fireNoise = texture2DLod(noisetex, abs(planeCoord * 0.2) - wind, 0.0).b;
|
||||
noise *= 0.5 * fireNoise + 0.75;
|
||||
noise = noise * noise * 3.0 / sampleCount;
|
||||
noise *= mix(1.0, sqrt3(VdotUM2), 0.25);
|
||||
|
||||
vec3 beamColor = beamCol;
|
||||
beamColor *= gradientMix / sampleCount;
|
||||
|
||||
noise *= exp2(-6.0 * i / float(sampleCount));
|
||||
beams += vec4(noise * beamColor, noise);
|
||||
}
|
||||
gradientMix += 1.0;
|
||||
}
|
||||
beams.rgb *= beams.a * beams.a * beams.a * 5000.0;
|
||||
beams.rgb *= sqrt(beams.rgb);
|
||||
result = sqrt(beams.rgb);
|
||||
|
||||
if(any(isnan(result.rgb))) result.rgb = vec3(0.0);
|
||||
|
||||
return vec4(result * visibility / sampleCount, beams.a);
|
||||
}
|
||||
return vec4(1.0);
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
#define RAINBOW_DIAMETER 1.00 //[0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 2.05 2.10 2.15 2.20 2.25 2.30 2.35 2.40 2.45 2.50 2.55 2.60 2.65 2.70 2.75 2.80 2.85 2.90 2.95 3.00 3.05 3.10 3.15 3.20 3.25 3.30 3.35 3.40 3.45 3.50 3.55 3.60 3.65 3.70 3.75 3.80 3.85 3.90 3.95 4.00 4.25 4.50 4.75 5.00 5.25 5.50 5.75 6.00 6.25 6.50 6.75 7.00 7.50 8.00]
|
||||
|
||||
vec3 GetRainbow(vec3 translucentMult, vec3 nViewPos, float z0, float z1, float lViewPos, float lViewPos1, float VdotL, float VdotU, float dither) {
|
||||
vec3 rainbow = vec3(0.0);
|
||||
|
||||
float rainbowTime = min1(max0(SdotU - 0.1) / 0.15);
|
||||
rainbowTime = clamp(rainbowTime - pow2(pow2(pow2(noonFactor))) * 8.0, 0.0, 0.85);
|
||||
#if RAINBOWS == 1 // After Rain
|
||||
rainbowTime *= sqrt2(max0(wetness - 0.333) * 1.5) * invRainFactor * inRainy;
|
||||
#endif
|
||||
|
||||
if (rainbowTime > 0.001) {
|
||||
float rainbowLength = far * 0.9;
|
||||
if (z1 == 1.0) lViewPos1 = rainbowLength;
|
||||
|
||||
float cloudLinearDepth = texelFetch(colortex5, texelCoord, 0).a;
|
||||
float cloudDisMult = pow2(cloudLinearDepth + OSIEBCA * dither);
|
||||
lViewPos1 *= cloudDisMult;
|
||||
|
||||
#if RAINBOW_STYLE == 1
|
||||
float pixelScale = 45.0;
|
||||
vec3 shadowDir = mat3(shadowModelView) * mat3(gbufferModelViewInverse) * nViewPos;
|
||||
|
||||
shadowDir.z += 0.0065 * (dither - 0.5); // Blurs the pixelation
|
||||
|
||||
shadowDir /= abs(shadowDir.z); // Corrects distortion
|
||||
shadowDir.xy = floor(shadowDir.xy * pixelScale) / pixelScale;
|
||||
|
||||
VdotL = shadowDir.z * inversesqrt(dot(shadowDir, shadowDir));
|
||||
#endif
|
||||
|
||||
float rainbowCoord = clamp01(1.0 - (VdotL + 0.75) / (0.0625 * RAINBOW_DIAMETER));
|
||||
float rainbowFactor = rainbowCoord * (1.0 - rainbowCoord);
|
||||
rainbowFactor = pow2(pow2(rainbowFactor * 3.7));
|
||||
rainbowFactor *= pow2(min1(lViewPos1 / rainbowLength));
|
||||
rainbowFactor *= rainbowTime;
|
||||
rainbowFactor *= 1.0 - GetCaveFactor();
|
||||
|
||||
if (rainbowFactor > 0.0) {
|
||||
float rainbowCoordM = pow(rainbowCoord, 1.4 + max(rainbowCoord - 0.5, 0.0) * 1.6);
|
||||
rainbowCoordM = smoothstep(0.0, 1.0, rainbowCoordM) * 0.85;
|
||||
rainbowCoordM += (dither - 0.5) * 0.1;
|
||||
|
||||
rainbow += clamp(abs(mod(rainbowCoordM * 6.0 + vec3(-0.55,4.3,2.2) ,6.0)-3.0)-1.0, 0.0, 1.0);
|
||||
rainbowCoordM += 0.1;
|
||||
rainbow += clamp(abs(mod(rainbowCoordM * 6.0 + vec3(-0.55,4.3,2.2) ,6.0)-3.0)-1.0, 0.0, 1.0);
|
||||
rainbowCoordM -= 0.2;
|
||||
rainbow += clamp(abs(mod(rainbowCoordM * 6.0 + vec3(-0.55,4.3,2.2) ,6.0)-3.0)-1.0, 0.0, 1.0);
|
||||
rainbow /= 3.0;
|
||||
|
||||
rainbow.r += pow2(max(rainbowCoord - 0.5, 0.0)) * (max(1.0 - rainbowCoord, 0.0)) * 26.0;
|
||||
rainbow = pow(rainbow, vec3(2.2)) * vec3(0.25, 0.075, 0.25) * 3.0;
|
||||
|
||||
if (z1 > z0 && lViewPos < rainbowLength)
|
||||
rainbow *= mix(translucentMult, vec3(1.0), lViewPos / rainbowLength);
|
||||
|
||||
if (isEyeInWater != 0) rainbow *= sqrt1(VdotU);
|
||||
|
||||
rainbow *= rainbowFactor;
|
||||
}
|
||||
}
|
||||
|
||||
return rainbow;
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
// Shooting stars implementation based on https://www.shadertoy.com/view/ttVXDy and also based on https://github.com/OUdefie17/Photon-GAMS
|
||||
|
||||
#define SHOOTING_STARS_SIZE 0.50 //[0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75]
|
||||
#define SHOOTING_STARS_SPEED 8.0 //[4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5 15.0]
|
||||
#define SHOOTING_STARS_CHANCE 0.5 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0]
|
||||
#define SHOOTING_STARS_COUNT 4 //[1 2 3 4 5 6 7 8 9 10]
|
||||
#define SHOOTING_STARS_LINE_THICKNESS 0.60 //[0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00]
|
||||
#define SHOOTING_STARS_TRAIL_LENGTH 0.60 //[0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85]
|
||||
|
||||
// Calculate distance from point p to line segment from a to b
|
||||
float DistLine(vec2 p, vec2 a, vec2 b) {
|
||||
vec2 pa = p - a;
|
||||
vec2 ba = b - a;
|
||||
float t = clamp01(dot(pa, ba) / dot(ba, ba));
|
||||
return length(pa - ba * t);
|
||||
}
|
||||
|
||||
// Draw a line with smooth edges
|
||||
float DrawLine(vec2 p, vec2 a, vec2 b) {
|
||||
float d = DistLine(p, a, b);
|
||||
float m = smoothstep(SHOOTING_STARS_LINE_THICKNESS * 0.01, 0.00001, d);
|
||||
float d2 = length(a - b);
|
||||
m *= smoothstep(1.0, 0.5, d2) + smoothstep(0.04, 0.03, abs(d2 - 0.75));
|
||||
return m;
|
||||
}
|
||||
|
||||
// Generate a single shooting star
|
||||
float ShootingStar(vec2 uv, vec2 startPos, vec2 direction) {
|
||||
vec2 id = floor(uv * 0.5);
|
||||
float h = hash12(id);
|
||||
|
||||
float newMoonVisibility = 1.0 - abs(moonPhase - 4) / 4.0;
|
||||
float moonPhaseFactor = mix(0.8, 1.5, newMoonVisibility);
|
||||
|
||||
if (h >= pow1_5(SHOOTING_STARS_CHANCE * 0.065) * moonPhaseFactor) return 0.0;
|
||||
|
||||
vec2 gv = fract(uv * 0.5) * 2.0 - 1.0;
|
||||
float line = DrawLine(gv, startPos, startPos + direction * 0.9);
|
||||
|
||||
vec2 toStart = gv - startPos;
|
||||
float alongTrail = dot(toStart, direction);
|
||||
float trail = smoothstep(SHOOTING_STARS_TRAIL_LENGTH, -0.1, alongTrail);
|
||||
|
||||
float headBrightness = 1.0 + 3.0 / (1.0 + pow2((alongTrail - 1.0) * 8.0));
|
||||
|
||||
return line * trail * headBrightness;
|
||||
}
|
||||
|
||||
vec3 GetShootingStars(vec2 starCoord, float VdotU, float VdotS) {
|
||||
float starsAroundSun = 1.0;
|
||||
#ifdef CELESTIAL_BOTH_HEMISPHERES
|
||||
float starBelowHorizonBrightness = 1.0;
|
||||
float horizonFactor = exp(-pow(VdotU / 0.1, 2.0));
|
||||
#ifdef SUN_MOON_HORIZON
|
||||
starsAroundSun = max0(sign(VdotU));
|
||||
#endif
|
||||
#else
|
||||
if (VdotU < 0.0) return vec3(0.0);
|
||||
float starBelowHorizonBrightness = min1(VdotU * 3.0);
|
||||
float horizonFactor = 0.0;
|
||||
#endif
|
||||
|
||||
float visibility = max0(1.0 - 1.0 / (1.0 + abs(VdotS) * 1000.0) * starsAroundSun) * starBelowHorizonBrightness - horizonFactor * 0.5;
|
||||
|
||||
#ifndef DAYLIGHT_STARS
|
||||
visibility *= pow2(pow2(invNoonFactor2)) * (1.0 - 0.5 * sunVisibility);
|
||||
#endif
|
||||
|
||||
#ifdef CLEAR_SKY_WHEN_RAINING
|
||||
visibility *= min1(invRainFactor + 0.4);
|
||||
#else
|
||||
visibility *= invRainFactor;
|
||||
#endif
|
||||
|
||||
if (visibility <= 0.01) return vec3(0.0);
|
||||
|
||||
vec2 uv = starCoord * 6.0 * (1.0 - SHOOTING_STARS_SIZE);
|
||||
float speed = frameTimeCounter * SHOOTING_STARS_SPEED;
|
||||
|
||||
vec2 startPositions[10] = vec2[](
|
||||
vec2(-0.4, 0.3),
|
||||
vec2(0.2, 0.4),
|
||||
vec2(-0.1, -0.3),
|
||||
vec2(0.3, -0.2),
|
||||
vec2(-0.3, 0.1),
|
||||
vec2(0.5, 0.2),
|
||||
vec2(-0.5, -0.1),
|
||||
vec2(0.1, 0.5),
|
||||
vec2(-0.2, -0.4),
|
||||
vec2(0.4, -0.3)
|
||||
);
|
||||
|
||||
vec2 directions[10] = vec2[](
|
||||
vec2(0.7071, 0.7071),
|
||||
vec2(0.7071, -0.7071),
|
||||
vec2(-1.0, 0.0),
|
||||
vec2(1.0, 0.0),
|
||||
vec2(0.5299, 0.8480),
|
||||
vec2(-0.6000, 0.8000),
|
||||
vec2(0.9134, -0.4067),
|
||||
vec2(-0.8000, -0.6000),
|
||||
vec2(0.3015, 0.9535),
|
||||
vec2(-0.2000, -0.9798)
|
||||
);
|
||||
|
||||
float stars = 0.0;
|
||||
int dayIndex = int(worldDay) % 10;
|
||||
vec2 todayDirection = directions[dayIndex];
|
||||
|
||||
for (int i = 0; i < SHOOTING_STARS_COUNT; i++) {
|
||||
float offsetAngle = (hash12(vec2(i, worldDay)) - 0.5) * 0.66;
|
||||
vec2 starDirection = rotate(offsetAngle) * todayDirection;
|
||||
|
||||
vec2 offsetUV = uv + starDirection * speed * (0.8 + 0.04 * float(i));
|
||||
stars += ShootingStar(offsetUV, startPositions[i], starDirection);
|
||||
}
|
||||
|
||||
vec3 shootingStarColor = vec3(0.38, 0.4, 0.5) * 2.0 * starBrightness;
|
||||
float intensity = min(stars * visibility * 10.0, 1.0);
|
||||
return shootingStarColor * intensity;
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
#ifndef INCLUDE_SKY
|
||||
#define INCLUDE_SKY
|
||||
|
||||
#define SUN_GLARE_AMOUNT 10 // [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30]
|
||||
#define MOON_GLARE_AMOUNT 10 // [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30]
|
||||
|
||||
#include "/lib/colors/lightAndAmbientColors.glsl"
|
||||
#include "/lib/colors/skyColors.glsl"
|
||||
|
||||
#ifdef CAVE_FOG
|
||||
#include "/lib/atmospherics/fog/caveFactor.glsl"
|
||||
#endif
|
||||
|
||||
vec3 GetSky(float VdotU, float VdotS, float dither, bool doGlare, bool doGround) {
|
||||
// Prepare variables
|
||||
float nightFactorSqrt2 = sqrt2(nightFactor);
|
||||
float nightFactorM = sqrt2(nightFactorSqrt2) * 0.4;
|
||||
float VdotSM1 = pow2(max(VdotS, 0.0));
|
||||
float VdotSM2 = pow2(VdotSM1);
|
||||
float VdotSM3 = pow2(pow2(max(-VdotS, 0.0)));
|
||||
float VdotSML = sunVisibility > 0.5 ? VdotS : -VdotS;
|
||||
|
||||
float VdotUmax0 = max(VdotU, 0.0);
|
||||
float VdotUmax0M = 1.0 - pow2(VdotUmax0);
|
||||
|
||||
// Prepare colors
|
||||
vec3 upColor = mix(nightUpSkyColor * (1.5 - 0.5 * nightFactorSqrt2 + nightFactorM * VdotSM3 * 1.5), dayUpSkyColor, sunFactor);
|
||||
vec3 middleColor = mix(nightMiddleSkyColor * (3.0 - 2.0 * nightFactorSqrt2), dayMiddleSkyColor * (1.0 + VdotSM2 * 0.3), sunFactor);
|
||||
vec3 downColor = mix(nightDownSkyColor, dayDownSkyColor, (sunFactor + sunVisibility) * 0.5);
|
||||
|
||||
// Mix the colors
|
||||
// Set sky gradient
|
||||
float scatteredGroundMixerMult = 1.0;
|
||||
float VdotUM1 = pow2(1.0 - VdotUmax0);
|
||||
VdotUM1 = pow(VdotUM1, 1.0 - VdotSM2 * 0.4);
|
||||
VdotUM1 = mix(VdotUM1, 1.0, rainFactor2 * 0.15);
|
||||
vec3 finalSky = mix(upColor, middleColor, VdotUM1);
|
||||
|
||||
// Add sunset color
|
||||
float VdotUM2 = pow2(1.0 - abs(VdotU));
|
||||
VdotUM2 = VdotUM2 * VdotUM2 * (3.0 - 2.0 * VdotUM2);
|
||||
VdotUM2 *= (0.7 - nightFactorM + VdotSM1 * (0.3 + nightFactorM)) * invNoonFactor * sunFactor;
|
||||
finalSky = mix(finalSky, sunsetDownSkyColorP * (1.0 + VdotSM1 * 0.3), VdotUM2 * invRainFactor);
|
||||
|
||||
// Add sky ground with fake light scattering
|
||||
float VdotUM3 = min(max0(-VdotU + 0.08) / 0.35, 1.0);
|
||||
VdotUM3 = smoothstep1(VdotUM3);
|
||||
vec3 scatteredGroundMixer = vec3(VdotUM3 * VdotUM3, sqrt1(VdotUM3), sqrt3(VdotUM3));
|
||||
scatteredGroundMixer = mix(vec3(VdotUM3), scatteredGroundMixer, 0.75 - 0.5 * rainFactor);
|
||||
finalSky = mix(finalSky, downColor, scatteredGroundMixer * scatteredGroundMixerMult);
|
||||
//
|
||||
|
||||
// Sky Ground
|
||||
if (doGround)
|
||||
finalSky *= smoothstep1(pow2(1.0 + min(VdotU, 0.0)));
|
||||
|
||||
// Apply Underwater Fog
|
||||
if (isEyeInWater == 1)
|
||||
finalSky = mix(finalSky * 3.0, waterFogColor, VdotUmax0M);
|
||||
|
||||
// Sun/Moon Glare
|
||||
#if SUN_GLARE_AMOUNT > 0 || MOON_GLARE_AMOUNT > 0
|
||||
if (doGlare) {
|
||||
if (0.0 < VdotSML) {
|
||||
float glareScatter = 3.0 * (2.0 - clamp01(VdotS * 1000.0));
|
||||
#ifndef SUN_MOON_DURING_RAIN
|
||||
glareScatter *= 1.0 - 0.75 * rainFactor2;
|
||||
#endif
|
||||
float VdotSM4 = pow(abs(VdotS), glareScatter);
|
||||
|
||||
float visfactor = 0.075;
|
||||
float glare = visfactor / (1.0 - (1.0 - visfactor) * VdotSM4) - visfactor;
|
||||
glare *= 0.7;
|
||||
|
||||
float glareWaterFactor = isEyeInWater * sunVisibility;
|
||||
vec3 glareColor = mix(vec3(0.38, 0.4, 0.5) * 0.3, vec3(1.5, 0.7, 0.3) + vec3(0.0, 0.5, 0.5) * noonFactor, sunVisibility);
|
||||
#if BLOOD_MOON > 0
|
||||
glareColor = mix(glareColor, vec3(0.6314, 0.0431, 0.0431), getBloodMoon(sunVisibility));
|
||||
#endif
|
||||
glareColor = glareColor + glareWaterFactor * vec3(7.0);
|
||||
|
||||
#ifdef SUN_MOON_DURING_RAIN
|
||||
glare *= 1.0 - 0.6 * rainFactor;
|
||||
#else
|
||||
glare *= 1.0 - 0.8 * rainFactor;
|
||||
#endif
|
||||
#if RAIN_STYLE == 1
|
||||
float glareDesaturateFactor = 0.5 * rainFactor;
|
||||
#elif RAIN_STYLE == 2
|
||||
float glareDesaturateFactor = rainFactor;
|
||||
#endif
|
||||
glareColor = mix(glareColor, vec3(GetLuminance(glareColor)), glareDesaturateFactor);
|
||||
|
||||
glare *= mix(MOON_GLARE_AMOUNT * 0.1, SUN_GLARE_AMOUNT * 0.1, sunVisibility);
|
||||
|
||||
finalSky += glare * shadowTime * glareColor;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CAVE_FOG
|
||||
// Apply Cave Fog
|
||||
finalSky = mix(finalSky, caveFogColor, GetCaveFactor() * VdotUmax0M);
|
||||
#endif
|
||||
|
||||
// Dither to fix banding
|
||||
finalSky += (dither - 0.5) / 128.0;
|
||||
|
||||
#if RETRO_LOOK == 1
|
||||
finalSky = vec3(0.0);
|
||||
#elif RETRO_LOOK ==2
|
||||
finalSky = mix(finalSky, vec3(0.0), nightVision);
|
||||
#endif
|
||||
|
||||
return finalSky;
|
||||
}
|
||||
|
||||
vec3 GetLowQualitySky(float VdotU, float VdotS, float dither, bool doGlare, bool doGround) {
|
||||
// Prepare variables
|
||||
float VdotUmax0 = max(VdotU, 0.0);
|
||||
float VdotUmax0M = 1.0 - pow2(VdotUmax0);
|
||||
|
||||
// Prepare colors
|
||||
vec3 upColor = mix(nightUpSkyColor, dayUpSkyColor, sunFactor);
|
||||
vec3 middleColor = mix(nightMiddleSkyColor, dayMiddleSkyColor, sunFactor);
|
||||
|
||||
// Mix the colors
|
||||
// Set sky gradient
|
||||
float VdotUM1 = pow2(1.0 - VdotUmax0);
|
||||
VdotUM1 = mix(VdotUM1, 1.0, rainFactor2 * 0.2);
|
||||
vec3 finalSky = mix(upColor, middleColor, VdotUM1);
|
||||
|
||||
// Add sunset color
|
||||
float VdotUM2 = pow2(1.0 - abs(VdotU));
|
||||
VdotUM2 *= invNoonFactor * sunFactor * (0.8 + 0.2 * VdotS);
|
||||
finalSky = mix(finalSky, sunsetDownSkyColorP * (shadowTime * 0.6 + 0.2), VdotUM2 * invRainFactor);
|
||||
//
|
||||
|
||||
// Sky Ground
|
||||
finalSky *= pow2(pow2(1.0 + min(VdotU, 0.0)));
|
||||
|
||||
// Apply Underwater Fog
|
||||
if (isEyeInWater == 1)
|
||||
finalSky = mix(finalSky, waterFogColor, VdotUmax0M);
|
||||
|
||||
// Sun/Moon Glare
|
||||
finalSky *= 1.0 + mix(nightFactor, 0.5 + 0.7 * noonFactor, VdotS * 0.5 + 0.5) * pow2(pow2(pow2(VdotS)));
|
||||
|
||||
#ifdef CAVE_FOG
|
||||
// Apply Cave Fog
|
||||
finalSky = mix(finalSky, caveFogColor, GetCaveFactor() * VdotUmax0M);
|
||||
#endif
|
||||
|
||||
#if RETRO_LOOK == 1 || RETRO_LOOK == 2
|
||||
finalSky = vec3(0.0);
|
||||
#endif
|
||||
|
||||
return finalSky;
|
||||
}
|
||||
|
||||
#endif //INCLUDE_SKY
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
#if !defined STARS_FILE_INCLUDED
|
||||
#define STARS_FILE_INCLUDED
|
||||
#include "/lib/colors/skyColors.glsl"
|
||||
#include "/lib/shaderSettings/stars.glsl"
|
||||
|
||||
vec2 GetStarCoord(vec3 viewPos, float sphereness) {
|
||||
vec3 wpos = normalize((gbufferModelViewInverse * vec4(viewPos * 1000.0, 1.0)).xyz);
|
||||
float ySign = sign(wpos.y);
|
||||
float yMagnitude = abs(wpos.y);
|
||||
|
||||
vec3 adjustedWpos = vec3(wpos.x, yMagnitude, wpos.z);
|
||||
vec3 starCoord = adjustedWpos / (adjustedWpos.y + length(adjustedWpos.xz) * sphereness);
|
||||
|
||||
if (ySign >= 0.0) {
|
||||
starCoord.x += 0.006 * syncedTime; // Top hemisphere (original direction)
|
||||
} else {
|
||||
starCoord.x = starCoord.x - 0.006 * syncedTime + 0.37; // Bottom hemisphere with offset
|
||||
starCoord.z += 0.21;
|
||||
}
|
||||
|
||||
return starCoord.xz;
|
||||
}
|
||||
|
||||
vec3 GetStars(vec2 starCoord, float VdotU, float VdotS, float sizeMult, float starAmount) {
|
||||
#if NIGHT_STAR_AMOUNT == 0
|
||||
return vec3(0.0, 0.0, 0.0);
|
||||
#endif
|
||||
float starsAroundSun = 1.0;
|
||||
#ifdef CELESTIAL_BOTH_HEMISPHERES
|
||||
float starBelowHorizonBrightness = 1.0;
|
||||
float horizonFactor = exp(-pow(VdotU / 0.1, 2.0));
|
||||
#ifdef SUN_MOON_HORIZON
|
||||
starsAroundSun = max0(sign(VdotU));
|
||||
#endif
|
||||
#else
|
||||
if (VdotU < 0.0) return vec3(0.0);
|
||||
float starBelowHorizonBrightness = min1(VdotU * 3.0);
|
||||
float horizonFactor = 0.0;
|
||||
#endif
|
||||
|
||||
starCoord *= 0.2 / (STAR_SIZE * sizeMult);
|
||||
|
||||
const float starFactor = 1024.0;
|
||||
|
||||
vec2 fractPart = fract(starCoord * starFactor);
|
||||
|
||||
starCoord = floor(starCoord * starFactor) / starFactor;
|
||||
|
||||
float star = GetStarNoise(starCoord.xy) * GetStarNoise(starCoord.xy+0.1) * GetStarNoise(starCoord.xy+0.23);
|
||||
|
||||
#if NIGHT_STAR_AMOUNT == 1
|
||||
star -= 0.82;
|
||||
star *= 2.0;
|
||||
#elif NIGHT_STAR_AMOUNT == 2
|
||||
star -= 0.7;
|
||||
#elif NIGHT_STAR_AMOUNT == 3
|
||||
star -= 0.62;
|
||||
star *= 0.75;
|
||||
#elif NIGHT_STAR_AMOUNT == 4
|
||||
star -= 0.52;
|
||||
star *= 0.55;
|
||||
#endif
|
||||
|
||||
star = max0(star - starAmount * 0.1);
|
||||
star *= getStarEdgeFactor(fractPart, STAR_ROUNDNESS_OW / 10.0, STAR_SOFTNESS_OW);
|
||||
star *= star;
|
||||
|
||||
star *= max0(1.0 - pow(abs(VdotS) * 1.002, 100.0) * starsAroundSun) * starBelowHorizonBrightness - horizonFactor * 0.5;
|
||||
#ifndef DAYLIGHT_STARS
|
||||
star *= pow2(pow2(invNoonFactor2)) * (1.0 - 0.5 * sunVisibility);
|
||||
#endif
|
||||
|
||||
#ifdef CLEAR_SKY_WHEN_RAINING
|
||||
star *= min1(invRainFactor + 0.4);
|
||||
#else
|
||||
star *= invRainFactor;
|
||||
#endif
|
||||
|
||||
vec3 starColor = GetStarColor(starCoord,
|
||||
vec3(0.38, 0.4, 0.5),
|
||||
vec3(STAR_COLOR_1_OW_R, STAR_COLOR_1_OW_G, STAR_COLOR_1_OW_B),
|
||||
vec3(STAR_COLOR_2_OW_R, STAR_COLOR_2_OW_G, STAR_COLOR_2_OW_B),
|
||||
vec3(STAR_COLOR_3_OW_R, STAR_COLOR_3_OW_G, STAR_COLOR_3_OW_B),
|
||||
float(STAR_COLOR_VARIATION_OW));
|
||||
|
||||
vec3 stars = 40.0 * star * starColor * starBrightness;
|
||||
|
||||
#if TWINKLING_STARS > 0
|
||||
stars *= getTwinklingStars(starCoord, float(TWINKLING_STARS));
|
||||
#endif
|
||||
|
||||
return stars;
|
||||
}
|
||||
#endif
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
// Volumetric tracing from Robobo1221, highly modified
|
||||
#include "/lib/shaderSettings/volumetricLight.glsl"
|
||||
#include "/lib/shaderSettings/endBeams.glsl"
|
||||
#include "/lib/shaderSettings/endFlash.glsl"
|
||||
#include "/lib/colors/lightAndAmbientColors.glsl"
|
||||
//#define BEDROCK_NOISE
|
||||
|
||||
float GetDepth(float depth) {
|
||||
return 2.0 * near * far / (far + near - (2.0 * depth - 1.0) * (far - near));
|
||||
}
|
||||
|
||||
float GetDistX(float dist) {
|
||||
return (far * (dist - near)) / (dist * (far - near));
|
||||
}
|
||||
|
||||
vec4 DistortShadow(vec4 shadowpos, float distortFactor) {
|
||||
shadowpos.xy *= 1.0 / distortFactor;
|
||||
shadowpos.z = shadowpos.z * 0.2;
|
||||
shadowpos = shadowpos * 0.5 + 0.5;
|
||||
|
||||
return shadowpos;
|
||||
}
|
||||
|
||||
vec4 GetVolumetricLight(inout vec3 color, inout float vlFactor, vec3 translucentMult, float lViewPos0, float lViewPos1, vec3 nViewPos, float VdotL, float VdotU, vec2 texCoord, float z0, float z1, float dither) {
|
||||
vec4 volumetricLight = vec4(0.0);
|
||||
#if defined BEDROCK_NOISE && defined OVERWORLD
|
||||
if ((cameraPosition.y < bedrockLevel) && (eyeBrightnessM < 0.4)) return vec4(0.0);
|
||||
#endif
|
||||
float vlMult = 1.0 - maxBlindnessDarkness;
|
||||
|
||||
#if SHADOW_QUALITY > -1
|
||||
// Optifine for some reason doesn't provide correct shadowMapResolution if Shadow Quality isn't 1x
|
||||
vec2 shadowMapResolutionM = textureSize(shadowtex0, 0);
|
||||
#endif
|
||||
|
||||
#ifdef IRIS_FEATURE_FADE_VARIABLE
|
||||
vec3 texture6 = texelFetch(colortex6, texelCoord, 0).rgb;
|
||||
float chunkFade = texture6.b > 0.50001 ? (1.0 - texture6.b) * 2.0 : 1.0;
|
||||
float chunkFadeM = mix(1.0, chunkFade, pow2(clamp01(lViewPos0 * 0.015))); // don't do fade very close to the player
|
||||
lViewPos1 = mix(far, lViewPos1, chunkFadeM);
|
||||
#endif
|
||||
|
||||
#ifdef OVERWORLD
|
||||
vec3 vlColor = lightColor;
|
||||
vec3 vlColorReducer = vec3(1.0);
|
||||
float vlSceneIntensity = isEyeInWater != 1 ? vlFactor : 1.0;
|
||||
|
||||
#ifdef SPECIAL_BIOME_WEATHER
|
||||
vlSceneIntensity = mix(vlSceneIntensity, 1.0, inDry * rainFactor);
|
||||
vlColor *= 1.0 + 0.6 * inDry * rainFactor;
|
||||
#endif
|
||||
|
||||
if (sunVisibility < 0.5) {
|
||||
vlSceneIntensity = 0.0;
|
||||
|
||||
float vlMultNightModifier = (0.3 + 0.4 * rainFactor2 + 0.5 * max0(far - lViewPos1) / far);
|
||||
#ifdef SPECIAL_PALE_GARDEN_LIGHTSHAFTS
|
||||
vlMultNightModifier = mix(vlMultNightModifier, 1.0, inPaleGarden);
|
||||
#endif
|
||||
vlMult *= vlMultNightModifier;
|
||||
|
||||
vlColor = normalize(pow(vlColor, vec3(1.0 - max0(1.0 - 1.5 * nightFactor) + rainFactor)));
|
||||
vlColor *= 0.0766 + 0.0766 * vsBrightness;
|
||||
} else {
|
||||
vlColorReducer = 1.0 / sqrt(vlColor);
|
||||
}
|
||||
|
||||
#if BLOOD_MOON > 0
|
||||
vec3 hsvVlColor = rgb2hsv(vlColor);
|
||||
vlColor = mix(vlColor, hsv2rgb(vec3(0, max(0.8, hsvVlColor.y), hsvVlColor.z * 1.7)), getBloodMoon(sunVisibility));
|
||||
#endif
|
||||
|
||||
#ifdef SPECIAL_PALE_GARDEN_LIGHTSHAFTS
|
||||
vlSceneIntensity = mix(vlSceneIntensity, 1.0, inPaleGarden);
|
||||
vlMult *= 1.0 + (3.0 * inPaleGarden) * (1.0 - sunVisibility);
|
||||
#endif
|
||||
|
||||
float rainyNight = (1.0 - sunVisibility) * rainFactor;
|
||||
float VdotLM = max((VdotL + 1.0) / 2.0, 0.0);
|
||||
float VdotUmax0 = max(VdotU, 0.0);
|
||||
float VdotUM = mix(pow2(1.0 - VdotUmax0), 1.0, 0.5 * vlSceneIntensity);
|
||||
VdotUM = smoothstep1(VdotUM);
|
||||
VdotUM = pow(VdotUM, min(lViewPos1 / far, 1.0) * (3.0 - 2.0 * vlSceneIntensity));
|
||||
vlMult *= mix(VdotUM * VdotLM, 1.0, 0.4 * rainyNight) * vlTime;
|
||||
vlMult *= mix(invNoonFactor2 * 0.875 + 0.125, 1.0, max(vlSceneIntensity, rainFactor2));
|
||||
|
||||
#if LIGHTSHAFT_QUALI == 4
|
||||
int sampleCount = vlSceneIntensity < 0.5 ? 30 : 50;
|
||||
#elif LIGHTSHAFT_QUALI == 3
|
||||
int sampleCount = vlSceneIntensity < 0.5 ? 15 : 30;
|
||||
#elif LIGHTSHAFT_QUALI == 2
|
||||
int sampleCount = vlSceneIntensity < 0.5 ? 10 : 20;
|
||||
#elif LIGHTSHAFT_QUALI == 1
|
||||
int sampleCount = vlSceneIntensity < 0.5 ? 6 : 12;
|
||||
#endif
|
||||
|
||||
#ifndef TAA
|
||||
sampleCount *= 2;
|
||||
#endif
|
||||
|
||||
#ifdef LIGHTSHAFT_SMOKE
|
||||
float totalSmoke = 0.0;
|
||||
#endif
|
||||
#else
|
||||
translucentMult = sqrt(translucentMult); // Because we pow2() the vl result in composite for the End dimension
|
||||
|
||||
float vlSceneIntensity = 0.0;
|
||||
|
||||
#ifndef LOW_QUALITY_ENDER_NEBULA
|
||||
int sampleCount = 16;
|
||||
#else
|
||||
int sampleCount = 10;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float addition = 1.0;
|
||||
float maxDist = mix(max(far, 96.0) * 0.55, 80.0, vlSceneIntensity);
|
||||
|
||||
#if WATER_FOG_MULT != 100
|
||||
if (isEyeInWater == 1) {
|
||||
#define WATER_FOG_MULT_M WATER_FOG_MULT * 0.01;
|
||||
maxDist /= WATER_FOG_MULT_M;
|
||||
}
|
||||
#endif
|
||||
|
||||
float distMult = maxDist / (sampleCount + addition);
|
||||
float sampleMultIntense = isEyeInWater != 1 ? 1.0 : 0.85;
|
||||
|
||||
float viewFactor = 1.0 - 0.7 * pow2(dot(nViewPos.xy, nViewPos.xy));
|
||||
|
||||
float depth0 = GetDepth(z0);
|
||||
float depth1 = GetDepth(z1);
|
||||
#ifdef END
|
||||
if (z0 == 1.0) depth0 = 1000.0;
|
||||
if (z1 == 1.0) depth1 = 1000.0;
|
||||
#endif
|
||||
|
||||
// Fast but inaccurate perspective distortion approximation
|
||||
maxDist *= viewFactor;
|
||||
distMult *= viewFactor;
|
||||
|
||||
#ifdef IRIS_FEATURE_FADE_VARIABLE
|
||||
depth1 = mix(depth1, far, pow2(pow2(1.0 - chunkFadeM)));
|
||||
#endif
|
||||
|
||||
#ifdef OVERWORLD
|
||||
float maxCurrentDist = min(depth1, maxDist);
|
||||
#else
|
||||
float maxCurrentDist = min(depth1, far);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
float currentDist = (i + dither) * distMult + addition;
|
||||
|
||||
if (currentDist > maxCurrentDist) break;
|
||||
|
||||
vec4 viewPos = gbufferProjectionInverse * (vec4(texCoord, GetDistX(currentDist), 1.0) * 2.0 - 1.0);
|
||||
viewPos /= viewPos.w;
|
||||
vec4 wpos = gbufferModelViewInverse * viewPos;
|
||||
vec3 playerPos = wpos.xyz / wpos.w;
|
||||
#if defined END && defined END_BEAMS
|
||||
playerPos *= 512.0 / far;
|
||||
vec4 enderBeamSample = vec4(DrawEnderBeams(VdotU, playerPos, nViewPos), 1.0);
|
||||
enderBeamSample /= sampleCount;
|
||||
#endif
|
||||
#if defined OVERWORLD && defined OVERWORLD_BEAMS
|
||||
vec4 overworldBeamSample = DrawOverworldBeams(VdotU, playerPos, viewPos.xyz);
|
||||
#endif
|
||||
|
||||
float shadowSample = 1.0;
|
||||
vec3 vlSample = vec3(1.0);
|
||||
#if SHADOW_QUALITY > -1
|
||||
wpos = shadowModelView * wpos;
|
||||
wpos = shadowProjection * wpos;
|
||||
wpos /= wpos.w;
|
||||
float distb = sqrt(wpos.x * wpos.x + wpos.y * wpos.y);
|
||||
float distortFactor = 1.0 - shadowMapBias + distb * shadowMapBias;
|
||||
vec4 shadowPosition = DistortShadow(wpos,distortFactor);
|
||||
//shadowPosition.z += 0.0001;
|
||||
|
||||
#ifdef OVERWORLD
|
||||
float percentComplete = currentDist / maxDist;
|
||||
float sampleMult = mix(percentComplete * 3.0, sampleMultIntense, max(rainFactor, vlSceneIntensity));
|
||||
if (currentDist < 5.0) sampleMult *= smoothstep1(clamp(currentDist / 5.0, 0.0, 1.0));
|
||||
sampleMult /= sampleCount;
|
||||
#endif
|
||||
|
||||
if (length(shadowPosition.xy * 2.0 - 1.0) < 1.0) {
|
||||
// 28A3DK6 We need to use texelFetch here or a lot of Nvidia GPUs can't get a valid value
|
||||
shadowSample = texelFetch(shadowtex0, ivec2(shadowPosition.xy * shadowMapResolutionM), 0).x;
|
||||
shadowSample = clamp((shadowSample-shadowPosition.z)*65536.0,0.0,1.0);
|
||||
|
||||
vlSample = vec3(shadowSample);
|
||||
|
||||
#ifdef END_FLASH_SHADOW_INTERNAL
|
||||
vlSample = mix(vec3(1.0), vlSample, endFlashIntensity);
|
||||
#endif
|
||||
|
||||
#if SHADOW_QUALITY >= 1
|
||||
if (shadowSample == 0.0) {
|
||||
float testsample = shadow2D(shadowtex1, shadowPosition.xyz).z;
|
||||
if (testsample == 1.0) {
|
||||
vec3 colsample = texture2D(shadowcolor1, shadowPosition.xy).rgb * 4.0;
|
||||
colsample *= colsample;
|
||||
vlSample = colsample;
|
||||
shadowSample = 1.0;
|
||||
#ifdef OVERWORLD
|
||||
vlSample *= vlColorReducer;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef OVERWORLD
|
||||
// For water-tinting the water surface when observed from below the surface
|
||||
if (translucentMult != vec3(1.0) && currentDist > depth0) {
|
||||
vec3 tinter = vec3(1.0);
|
||||
if (isEyeInWater == 1) {
|
||||
vec3 translucentMultM = translucentMult * 2.8;
|
||||
tinter = pow(translucentMultM, vec3(sunVisibility * 3.0 * clamp01(playerPos.y * 0.03)));
|
||||
} else {
|
||||
tinter = 0.1 + 0.9 * pow2(pow2(translucentMult * 1.7));
|
||||
}
|
||||
vlSample *= mix(vec3(1.0), tinter, clamp01(oceanAltitude - cameraPosition.y));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isEyeInWater == 1 && translucentMult == vec3(1.0)) vlSample = vec3(0.0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (currentDist > depth0) vlSample *= translucentMult;
|
||||
|
||||
#ifdef OVERWORLD
|
||||
#ifdef LIGHTSHAFT_SMOKE
|
||||
vec3 smokePos = 0.0015 * (playerPos + cameraPosition);
|
||||
vec3 smokeWind = frameTimeCounter * vec3(0.0, 0.001, -0.002);
|
||||
float smoke = 0.65 * Noise3D(smokePos + smokeWind)
|
||||
+ 0.25 * Noise3D((smokePos - smokeWind) * 3.0)
|
||||
+ 0.10 * Noise3D((smokePos + smokeWind) * 9.0);
|
||||
smoke = smoothstep1(smoothstep1(smoothstep1(smoke)));
|
||||
totalSmoke += smoke * shadowSample * sampleMult;
|
||||
#endif
|
||||
vec4 volumetricLightAdd = vec4(vlSample, shadowSample) * sampleMult;
|
||||
#ifdef OVERWORLD_BEAMS
|
||||
volumetricLight += volumetricLightAdd * mix(vec4(1.0), overworldBeamSample, overworldBeamSample.a);
|
||||
#else
|
||||
volumetricLight += volumetricLightAdd;
|
||||
#endif
|
||||
#else
|
||||
#ifdef END_BEAMS
|
||||
volumetricLight += vec4(vlSample, shadowSample) * enderBeamSample;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LIGHTSHAFT_SMOKE
|
||||
volumetricLight *= pow(totalSmoke / volumetricLight.a, min(1.0 - volumetricLight.a, 0.5));
|
||||
volumetricLight.rgb /= pow(0.5, 1.0 - volumetricLight.a);
|
||||
#endif
|
||||
|
||||
// Decision of Intensity for Scene Aware Light Shafts //
|
||||
#if defined OVERWORLD && LIGHTSHAFT_BEHAVIOUR == 1 && SHADOW_QUALITY >= 1
|
||||
if (viewWidth + viewHeight - gl_FragCoord.x - gl_FragCoord.y < 1.5) {
|
||||
if (frameCounter % int(0.06666 / frameTimeSmooth + 0.5) == 0) { // Change speed is not too different above 10 fps
|
||||
int salsX = 5;
|
||||
int salsY = 5;
|
||||
float heightThreshold = 6.0;
|
||||
|
||||
vec2 viewM = 1.0 / vec2(salsX, salsY);
|
||||
float salsSampleSum = 0.0;
|
||||
int salsSampleCount = 0;
|
||||
for (float i = 0.25; i < salsX; i++) {
|
||||
for (float h = 0.45; h < salsY; h++) {
|
||||
vec2 coord = 0.3 + 0.4 * viewM * vec2(i, h);
|
||||
ivec2 icoord = ivec2(coord * shadowMapResolutionM);
|
||||
float salsSample = texelFetch(shadowtex0, icoord, 0).x; // read 28A3DK6
|
||||
if (salsSample < 0.55) {
|
||||
float sampledHeight = texture2D(shadowcolor1, coord).a;
|
||||
if (sampledHeight > 0.0) {
|
||||
sampledHeight = max0(sampledHeight - 0.25) / 0.05; // consistencyMEJHRI7DG
|
||||
salsSampleSum += sampledHeight;
|
||||
salsSampleCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float salsCheck = salsSampleSum / salsSampleCount;
|
||||
int reduceAmount = 2;
|
||||
|
||||
int skyCheck = 0;
|
||||
for (float i = 0.1; i < 1.0; i += 0.2) {
|
||||
skyCheck += int(texelFetch(depthtex0, ivec2(view.x * i, view.y * 0.9), 0).x == 1.0);
|
||||
}
|
||||
if (skyCheck >= 4) {
|
||||
salsCheck = 0.0;
|
||||
reduceAmount = 3;
|
||||
}
|
||||
|
||||
if (salsCheck > heightThreshold) {
|
||||
vlFactor = min(vlFactor + OSIEBCA, 1.0);
|
||||
} else {
|
||||
vlFactor = max(vlFactor - OSIEBCA * reduceAmount, 0.0);
|
||||
}
|
||||
}
|
||||
} else vlFactor = 0.0;
|
||||
//if (gl_FragCoord.y < 50) color.rgb = vec3(1,0,1) * float(salsCheck / heightThreshold > gl_FragCoord.x / 1920.0);
|
||||
|
||||
/*for (float i = 0.25; i < salsX; i++) {
|
||||
for (float h = 0.45; h < salsY; h++) {
|
||||
if (length(texCoord - (0.3 + 0.4 * viewM * vec2(i, h))) < 0.01) return vec4(1,0,1,1);
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
|
||||
#ifdef OVERWORLD
|
||||
vlColor = pow(vlColor, vec3(0.5 + (0.5 + LIGHTSHAFT_SUNSET_SATURATION * sunVisibility) * invNoonFactor * invRainFactor + 0.3 * rainFactor));
|
||||
vlColor *= 1.0 - (0.3 + 0.3 * noonFactor) * rainFactor - 0.5 * rainyNight + sunVisibility * pow2(invNoonFactor) * invRainFactor;
|
||||
|
||||
#if LIGHTSHAFT_DAY_I != 100 || LIGHTSHAFT_NIGHT_I != 100 || LIGHTSHAFT_RAIN_I != 100
|
||||
#define LIGHTSHAFT_DAY_IM LIGHTSHAFT_DAY_I * 0.01
|
||||
#define LIGHTSHAFT_NIGHT_IM LIGHTSHAFT_NIGHT_I * 0.01
|
||||
#define LIGHTSHAFT_RAIN_IM LIGHTSHAFT_RAIN_I * 0.01
|
||||
|
||||
if (isEyeInWater == 0) {
|
||||
#if LIGHTSHAFT_DAY_I != 100 || LIGHTSHAFT_NIGHT_I != 100
|
||||
vlColor.rgb *= mix(LIGHTSHAFT_NIGHT_IM, LIGHTSHAFT_DAY_IM, sunVisibility);
|
||||
#endif
|
||||
#if LIGHTSHAFT_RAIN_I != 100
|
||||
vlColor.rgb *= mix(1.0, LIGHTSHAFT_RAIN_IM, rainFactor);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
volumetricLight.rgb *= vlColor;
|
||||
#endif
|
||||
|
||||
volumetricLight.rgb *= vlMult;
|
||||
volumetricLight = max(volumetricLight, vec4(0.0));
|
||||
|
||||
#if defined DISTANT_HORIZONS && defined OVERWORLD
|
||||
if (isEyeInWater == 0) {
|
||||
float lViewPosM = lViewPos0;
|
||||
if (z0 >= 1.0) {
|
||||
float z0DH = texelFetch(dhDepthTex, texelCoord, 0).r;
|
||||
vec4 screenPosDH = vec4(texCoord, z0DH, 1.0);
|
||||
vec4 viewPosDH = dhProjectionInverse * (screenPosDH * 2.0 - 1.0);
|
||||
viewPosDH /= viewPosDH.w;
|
||||
lViewPosM = length(viewPosDH.xyz);
|
||||
}
|
||||
lViewPosM = min(lViewPosM, renderDistance * 0.6);
|
||||
|
||||
float dhVlStillIntense = max(max(vlSceneIntensity, rainFactor), nightFactor * 0.5);
|
||||
|
||||
volumetricLight *= mix(0.0003 * lViewPosM, 1.0, dhVlStillIntense);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef END
|
||||
#ifndef DISTANT_HORIZONS
|
||||
volumetricLight *= sqrt1(min1(lViewPos1 * 2.0 / 512.0));
|
||||
#else
|
||||
volumetricLight *= min1(lViewPos1 * 3.0 / renderDistance);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if RETRO_LOOK == 1
|
||||
volumetricLight *= vec4(0.0);
|
||||
#elif RETRO_LOOK == 2
|
||||
volumetricLight *= mix(vec4(1.0), vec4(0.0), nightVision);
|
||||
#endif
|
||||
|
||||
return volumetricLight;
|
||||
}
|
||||
Reference in New Issue
Block a user