Files
Reimagined/shaderpacks/Reimagined - High/shaders/lib/materials/seasons.glsl
T
2026-05-07 21:38:27 +03:00

506 lines
32 KiB
GLSL

// Yes I hate myself for having done all of this in a big file and with functions. Thanks you me from a year ago
#include "/lib/shaderSettings/interactiveFoliage.glsl"
#include "/lib/shaderSettings/emissiveFlowers.glsl"
#include "/lib/shaderSettings/wavingBlocks.glsl"
#define SNOW_NOISE_INTENSITY 1.0 //[0.5 0.75 1.0 1.25 1.5 2.0]
#define SNOW_TRANSPARENCY 0.90 //[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 1.00]
#define MELTING_RADIUS 0.4 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0]
#define SNOW_SIZE 16 //[8 16 32 64 128]
//#define SSS_SEASON_SNOW
#define SNOW_NOISE_REMOVE_INTENSITY 1.00 //[0.00 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.60 1.70 1.80 1.90 2.00 2.25 2.50 2.75 3.00]
#define WINTER_GREEN_AMOUNT 0.0 //[0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0]
#define SUMMER_STRENGTH 1.0 //[0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.2 1.3 1.4 1.5]
#define LESS_LEAVES 3 //[0 1 2 3 4 5]
#define AUTUMN_NOISE_SIZE 1.0 //[0.5 0.6 0.7 0.8 0.9 1.0 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0]
#define AUTUMN_STRENGTH 0.5 //[0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0]
//#define EXTRA_FLOOR_LEAVES_IN_FORESTS
#define FLOWER_DENSITY 1.0 //[0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0]
#define FLOWER_SIZE 16 //[8 16 32 64 128]
#define FLOWER_AMOUNT 2 //[0 1 2 3 4 5 6 7 8 9 10]
#define SPRING_GREEN_INTENSITY 1.0 //[0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0]
//#define EMISSIVE_SPRING_FLOWERS
#define DISABLE_SPRING_IN_DRY_BIOMES
#ifdef EMISSIVE_SPRING_FLOWERS
#endif
#ifndef GBUFFERS_HAND
vec3 oldColor = color.rgb; // Needed for entities
#if SEASONS != 2 && SEASONS != 5
// Color Desaturation
vec3 desaturatedColor = color.rgb;
if (SEASON_COLOR_DESATURATION > 0.0) {
float desaturation = SEASON_COLOR_DESATURATION;
#if SEASONS == 1 || SEASONS == 4
if (winterTime > 0) {
// snow conditions
#if SNOW_CONDITION != 2
desaturation *= inSnowy; // make only appear in cold biomes
#elif SNOW_CONDITION == 0
desaturation *= rainFactor; // make only appear in rain
#endif
}
#endif
desaturatedColor = mix(color.rgb, vec3(GetLuminance(color.rgb)), clamp01(desaturation - lmCoord.x));
}
#endif
bool dhLeaves = true;
#ifdef DH_TERRAIN
if (BLOCK_LEAVES_SEASONS_DEFINE && (dhColor.r < 0.17 || dhColor.r > 0.7)) {
dhLeaves = false;
isFoliage = false;
}
#endif
#if defined GBUFFERS_TERRAIN || defined DH_TERRAIN
dhLeaves = dhLeaves && BLOCK_LEAVES_SEASONS_DEFINE && isFoliage;
#endif
#if SEASONS == 1 || SEASONS == 2
vec3 summerColor = color.rgb;
if (summerTime > 0) {
#if defined GBUFFERS_TERRAIN || defined DH_TERRAIN
if (dhLeaves || (mat == 10132 || mat == 10133) && glColor.b < 0.999) { // Normal Grass Block
summerColor = mix(summerColor, GetLuminance(summerColor) * vec3(1.0, 0.8941, 0.3725), 0.3 * SUMMER_STRENGTH);
}
#endif
}
#endif
float autumnOnlyForests = 1.0;
#ifdef AUTUMN_CONDITION
autumnOnlyForests = inForest;
#endif
#if SEASONS == 1 || SEASONS == 3
vec3 autumnColor = vec3(0);
if (autumnTime > 0) {
autumnColor = mix(color.rgb, desaturatedColor, 0.65 * autumnOnlyForests);
#if defined GBUFFERS_TERRAIN || defined GBUFFERS_BLOCK || defined DH_TERRAIN
const vec3 autumnLeafColor0 = vec3(0.9922, 0.5707, 0.098);
const vec3 autumnLeafColor1 = vec3(0.9922, 0.4786, 0.098);
const vec3 autumnLeafColor2 = vec3(0.9804, 0.4033, 0.1569);
const vec3 autumnLeafColor3 = vec3(0.9765, 0.3333, 0.149);
const vec3 autumnLeafColor4 = vec3(0.5608, 0.2275, 0.1686);
float noiseLeavesColor1 = smoothstep(0.4, 0.7, Noise3D(worldPos * 0.0001 * AUTUMN_NOISE_SIZE));
float noiseLeavesColor2 = smoothstep(0.3, 0.7, Noise3D(worldPos * 0.0003 * AUTUMN_NOISE_SIZE + 300.0));
float noiseLeavesColor3 = smoothstep(0.65, 0.7, Noise3D(worldPos * 0.0005 * AUTUMN_NOISE_SIZE + 700.0));
float noiseLeavesColor4 = smoothstep(0.7, 0.8, Noise3D(worldPos * 0.0003 * AUTUMN_NOISE_SIZE + 1000.0));
vec3 leafMainColor = mix(mix(mix(mix(autumnLeafColor0, autumnLeafColor1, noiseLeavesColor1), autumnLeafColor2, noiseLeavesColor2), autumnLeafColor3, noiseLeavesColor3), autumnLeafColor4, noiseLeavesColor4) * 1.5; // giant mix :p
bool isVine = mat == 10013 && inJungle < 0.5;
if (isFoliage) {
if (mat == 10009 || mat == 10011 || dhLeaves || isVine) { // Except some leaves
autumnColor *= mix(vec3(1.0), leafMainColor, autumnOnlyForests);
} else {
autumnColor *= mix(vec3(1.0), vec3(0.9882, 0.7725, 0.5725), autumnOnlyForests * 0.5);
}
} else { // leaves on the ground
if (((mat == 10132 || mat == 10133)
#ifdef DH_TERRAIN
|| mat == DH_BLOCK_GRASS
#endif
) && glColor.b < 0.999) { // Normal Grass Block, grass part
autumnColor *= mix(vec3(1.0), vec3(0.9882, 0.7725, 0.5725), autumnOnlyForests * 0.4);
}
#ifdef LEAVES_ON_GROUND
vec3 absPlayerPos = abs(playerPos);
float maxPlayerPosXZ = max(absPlayerPos.x, absPlayerPos.z);
float leafDecider = -clamp01(pow2(min1(maxPlayerPosXZ / 100) * 2.0)) + 1.0; // The effect will only be around the player
if (leafDecider > 0.001){
float noiseLeavesFloorColor = float(hash33(floor(mod(worldPos, vec3(100.0)) * 16 + 0.03) * 16)) * 0.25;
vec3 leafFloorColorRandomMess = mix(mix(mix(mix(autumnLeafColor0, autumnLeafColor1, noiseLeavesFloorColor), autumnLeafColor2, noiseLeavesFloorColor), autumnLeafColor3, noiseLeavesFloorColor), autumnLeafColor4, noiseLeavesFloorColor) * 2.0;
vec3 leafFloorColor = mix(leafFloorColorRandomMess, leafMainColor, 0.66); // this mixes between the random colors and the colors of the leaves at the world pos
float topCheck = abs(clamp01(dot(normal, upVec)));
float leafSide = 0.0;
if (((mat == 10132 || mat == 10133) && glColor.b < 0.999) || (mat == 10126 && color.b + color.g < color.r * 2.0 && color.b > 0.3 && color.g < 0.45) || (mat == 10493 && color.r > 0.52 && color.b < 0.30 && color.g > 0.41 && color.g + color.b * 0.95 > color.r * 1.2)) { // Normal Grass Block and Dirt Path
leafSide = 1.0;
topCheck = 1.0;
}
vec2 leafVec = getOverlayNoise(1, true, false, 0.1, 16, worldPos, 1.0, 0.0);
float leafFloorNoise = leafVec.y;
float leafVariable = leafVec.x;
leafFloorColor += 0.7 * leafFloorNoise; // make noisier
float skylightCheck = (1.0 - pow(lmCoord.y + 0.01, 30.0)) * pow(lmCoord.y + 0.01, 2.0);
#ifdef ACT_GROUND_LEAVES_FIX
if (skylightCheck > 0.001) {
uint underneathLeaves = 0u;
#define LEAVES_VOXEL_RANGE 20 // 20 blocks, increasing this to a large number would have a severe performance impact
float dither1 = 0.0, dither2 = 0.0, scatterAmount = 0.0;
#ifdef TAA
dither1 = fract(Bayer64(gl_FragCoord.xy) + goldenRatio * mod(float(frameCounter), 3600.0)) * 2.0 - 1.0;
dither2 = fract(Bayer64(0.5 * gl_FragCoord.xy + 23) - goldenRatio * mod(float(frameCounter), 3600.0)) * 2.0 - 1.0;
scatterAmount = 2.0;
#endif
vec3 voxelPos = SceneToLeavesVoxel(playerPos + scatterAmount * vec3(dither1, -0.1, dither2)); // -0.1 fixes flickering inside water
for (int i = 0; i < LEAVES_VOXEL_RANGE; i++) {
voxelPos.y += 1;
if (!CheckInsideLeavesVoxelVolume(voxelPos)) {
underneathLeaves = 1u; // We don't touch the detection outside of the voxel volume
break;
}
vec3 voxelSamplePos = clamp01(voxelPos / vec3(leaves_voxelVolumeSize));
uint voxelData = texture(leaves_sampler, voxelSamplePos).r;
if (voxelData != 0u) {
underneathLeaves = voxelData - 1u;
break;
}
}
leafVariable *= underneathLeaves;
leafFloorColor += 1.25 * leafFloorNoise * underneathLeaves;
}
#endif
leafVariable = sqrt4(leafVariable); // make the noise less noticeable
leafVariable *= skylightCheck;
#ifdef EXTRA_FLOOR_LEAVES_IN_FORESTS
float leafAddNoise1 = 1.0 - texture2DLod(noisetex, 0.0005 * (worldPos.xz + worldPos.y), 0.0).r * 1.3;
float leafAddNoise2 = 1.0 - texture2DLod(noisetex, 0.005 * (worldPos.xz + worldPos.y), 0.0).r * 1.3;
float leafAddNoise3 = texture2DLod(noisetex, 0.02 * (worldPos.xz + worldPos.y), 0.0).r * 1.3;
leafVariable += mix(0.0, lmCoord.y * 1.0 - clamp(2.0 * leafAddNoise1 + 0.70 * leafAddNoise2 + 0.2 * leafAddNoise1, 0.0, 1.0), inForest);
#endif
leafVariable = clamp01(leafVariable);
leafVariable *= topCheck; // make only appear on top of blocks
leafVariable *= leafDecider;
autumnColor *= mix(vec3(1.0), leafFloorColor, leafVariable * overlayNoiseIntensity * autumnOnlyForests * (1.0 - inPaleGarden));
}
#endif
}
#endif
#ifndef GBUFFERS_ENTITIES
autumnColor *= mix(vec3(1.0), vec3(1.0, 0.7, 0.5), autumnTime * 0.7 * autumnOnlyForests * AUTUMN_STRENGTH * (1.0 - inPaleGarden));
#endif
}
#endif
#if (SEASONS == 1 || SEASONS == 3 || SEASONS == 4) && (defined GBUFFERS_TERRAIN || defined DH_TERRAIN) && LESS_LEAVES > 0
if (mat == 10009 || mat == 10011) { // Except some leaves
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
float noiseLeaveAlpha = step(autumnWinterTime * LESS_LEAVES * 0.15, hash13(floor(mod(playerPos.xyz - 0.001 * (mat3(gbufferModelViewInverse) * normal) + cameraPosition.xyz, vec3(100.0)) * 4) * 4)); // remove some leaves with noise
noiseLeaveAlpha += step(autumnWinterTime * LESS_LEAVES * 0.13, hash13(floor(mod(playerPos.xyz - 0.001 * (mat3(gbufferModelViewInverse) * normal) + cameraPosition.xyz, vec3(100.0)) * 16) * 16));
color.a *= clamp01(noiseLeaveAlpha);
}
#endif
#if SEASONS == 1 || SEASONS == 4
vec3 winterColor = vec3(0);
if (winterTime > 0) {
float snowSide = 0.0;
#if !defined GBUFFERS_ENTITIES && defined GBUFFERS_TERRAIN
if (isFoliage) snowSide = mix(1.0, 0.0, 1.0 / (color.g * color.g) * 0.05); // make all foliage white
#ifndef DH_TERRAIN
if (((mat == 10132 || mat == 10133) && glColor.b < 0.999) || (mat == 10126 && color.b + color.g < color.r * 2.0 && color.b > 0.3 && color.g < 0.45) || (mat == 10493 && color.r > 0.52 && color.b < 0.30 && color.g > 0.41 && color.g + color.b * 0.95 > color.r * 1.2)) { // Normal Grass Block and Dirt Path
snowSide = mix(0.0, 1.0, pow(blockUV.y, 3.0));
#if defined SSS_SEASON_SNOW && (SEASONS == 1 || SEASONS == 4)
#if SNOW_CONDITION == 0
if (rainFactor > 0 && inSnowy > 0) subsurfaceMode = 3, noSmoothLighting = true, noDirectionalShading = true; // SSS
#elif SNOW_CONDITION == 1
if (inSnowy > 0) subsurfaceMode = 3, noSmoothLighting = true, noDirectionalShading = true;
#else
subsurfaceMode = 3, noSmoothLighting = true, noDirectionalShading = true;
#endif
#endif
} // add to the side of grass, mycelium, path blocks; in that order. Use blockUV to increase transparency the the further down the block it goes
#endif
if ((mat == 10132 || mat == 10133) && glColor.b < 0.999) snowSide += abs(color.g - color.g * 0.5); // Normal Grass Block, mute the grass colors a bit
if (((mat == 10132 || mat == 10133)
#ifdef DH_TERRAIN
|| mat == DH_BLOCK_GRASS
#endif
) && glColor.b < 0.999 || isFoliage || dhLeaves && mat != 10007) { // Foliage except some leaves
desaturatedColor = mix(desaturatedColor, mix(saturateColors(desaturatedColor, 0.4), desaturatedColor * vec3(0.9098, 0.6118, 0.4118), 0.5), winterTime * (1.0 - WINTER_GREEN_AMOUNT));
}
#endif
winterColor = desaturatedColor;
#if defined GBUFFERS_ENTITIES || defined GBUFFERS_COLORWHEEL
oldColor = mix(color.rgb, winterColor, winterTime);
#else
float winterAlpha = color.a;
vec3 snowColor = vec3(0.9713, 0.9691, 0.9891);
vec2 snowVec = getOverlayNoise(snowSide, false, false, MELTING_RADIUS, SNOW_SIZE, worldPos, SNOW_TRANSPARENCY, SNOW_NOISE_REMOVE_INTENSITY * 1.2);
float snowNoise = snowVec.y;
float snowVariable = snowVec.x;
snowColor *= 1.1;
snowColor += 0.23 * snowNoise * SNOW_NOISE_INTENSITY; // make the noise less noticeable & configurable with option
snowVariable *= (1.0 - inDry) * SNOW_TRANSPARENCY;
// snow conditions
#if SNOW_CONDITION != 2
snowVariable *= inSnowy; // make only appear in cold biomes
#endif
#if SNOW_CONDITION == 0
snowVariable *= rainFactor; // make only appear in rain
#endif
#if SNOW_CONDITION == 0
highlightMult = mix(highlightMult, 2.3 - subsurfaceMode * 0.1, snowVariable * IPBRMult * winterTime * rainFactor * inSnowy * overlayNoiseIntensity);
smoothnessG = mix(smoothnessG, 0.45 + 0.1 * snowNoise, snowVariable * IPBRMult * winterTime * rainFactor * inSnowy * overlayNoiseIntensity);
#elif SNOW_CONDITION == 1
highlightMult = mix(highlightMult, 2.3 - subsurfaceMode * 0.1, snowVariable * IPBRMult * winterTime * inSnowy * overlayNoiseIntensity);
smoothnessG = mix(smoothnessG, 0.45 + 0.1 * snowNoise, snowVariable * IPBRMult * winterTime * inSnowy * overlayNoiseIntensity);
#else
highlightMult = mix(highlightMult, 2.3 - subsurfaceMode * 0.1, snowVariable * IPBRMult * winterTime * overlayNoiseIntensity);
smoothnessG = mix(smoothnessG, 0.45 + 0.1 * snowNoise, snowVariable * IPBRMult * winterTime * overlayNoiseIntensity);
#endif
#ifdef SSS_SEASON_SNOW
if (dot(normal, upVec) > 0.99) {
#if SNOW_CONDITION == 0
if (rainFactor > 0 && inSnowy > 0) subsurfaceMode = 3, noSmoothLighting = true, noDirectionalShading = true;
#elif SNOW_CONDITION == 1
if (inSnowy > 0) subsurfaceMode = 3, noSmoothLighting = true, noDirectionalShading = true;
#else
subsurfaceMode = 3, noSmoothLighting = true, noDirectionalShading = true;
#endif
}
#endif
#ifdef GBUFFERS_TERRAIN
if (dot(normal, upVec) > 0.99) {
#if SNOW_CONDITION == 0
emission = mix(emission, emission * overlayNoiseEmission, rainFactor * inSnowy * winterTime * overlayNoiseIntensity); // make only appear in rain
#ifndef DH_TERRAIN
smoothnessD = mix(smoothnessD, 0.0, snowVariable * rainFactor * inSnowy * winterTime * overlayNoiseIntensity);
#endif
#elif SNOW_CONDITION == 1
emission = mix(emission, emission * overlayNoiseEmission, inSnowy * winterTime * overlayNoiseIntensity); // make only appear in cold biomes
#ifndef DH_TERRAIN
smoothnessD = mix(smoothnessD, 0.0, snowVariable * inSnowy * winterTime * overlayNoiseIntensity);
#endif
#else
emission = mix(emission, emission * overlayNoiseEmission, winterTime * overlayNoiseIntensity);
#ifndef DH_TERRAIN
smoothnessD = mix(smoothnessD, 0.0, snowVariable * winterTime * overlayNoiseIntensity);
#endif
#endif
}
#endif
#ifdef GBUFFERS_WATER
if (dot(normal, upVec) > 0.99) {
#if SNOW_CONDITION == 0
overlayNoiseTransparentOverwrite = mix(overlayNoiseTransparentOverwrite, overlayNoiseAlpha, rainFactor * inSnowy * winterTime);
fresnel = mix(fresnel, 0.01, snowVariable * overlayNoiseFresnelMult * winterTime * rainFactor * inSnowy);
#elif SNOW_CONDITION == 1
overlayNoiseTransparentOverwrite = mix(overlayNoiseTransparentOverwrite, overlayNoiseAlpha, inSnowy * winterTime);
fresnel = mix(fresnel, 0.01, snowVariable * overlayNoiseFresnelMult * winterTime * inSnowy);
#else
overlayNoiseTransparentOverwrite = mix(1.0, overlayNoiseAlpha, winterTime);
fresnel = mix(fresnel, 0.01, snowVariable * overlayNoiseFresnelMult * winterTime);
#endif
}
#endif
// final mix
winterColor = mix(winterColor, snowColor, snowVariable * overlayNoiseIntensity);
winterAlpha = mix(color.a, 1.0, clamp(overlayNoiseTransparentOverwrite * snowVariable, 0.0, 1.0));
color.a = mix(color.a, winterAlpha, winterTime * overlayNoiseIntensity);
#endif
}
#endif
#if SEASONS == 1 || SEASONS == 5
vec3 springColor = color.rgb;
if (springTime > 0) {
#ifdef GBUFFERS_TERRAIN
if (isFoliage || dhLeaves || (mat == 10132 || mat == 10133) && glColor.b < 0.999
#ifdef DH_TERRAIN
|| mat == DH_BLOCK_GRASS
#endif
) { // Foliage except some leaves, Normal Grass Block
if (glColor.b < 0.99) springColor = mix(springColor, GetLuminance(springColor) * vec3(0.3725, 1.0, 0.4235), 0.5 * SPRING_GREEN_INTENSITY);
}
#if FLOWER_AMOUNT > 0 && !defined DH_TERRAIN
if ((mat == 10132 || mat == 10133)) { // Normal Grass Block
float flowerNoiseAdd = step(texture2DLod(noisetex, 0.0005 * (worldPos.xz + atMidBlock.xz / 64), 0.0).r, 0.25) * 3.5 + 1.0; // Noise to add more flowers
float flowerNoiseRemove = clamp01(step(texture2DLod(noisetex, 0.003 * (worldPos.xz + atMidBlock.xz / 64), 0.0).g, 0.69) + 0.15); // Noise to reduce the amount of flowers
ivec2 flowerUV = ivec2(blockUV.xz * FLOWER_SIZE);
float flower1Variable = 0.0;
float flower2Variable = 0.0;
float flower3Variable = 0.0;
float flower4Variable = 0.0;
float flower5Variable = 0.0;
float flower4Emission = 0.0; // this exists to only make the purple part of the flower bud be emissive
float flowerEmissionMask = 0.0;
const ivec2 flower1Size = ivec2(3, 3);
const ivec2 flower2Size = ivec2(3, 3);
const ivec2 flower3Size = ivec2(1, 1);
const ivec2 flower4Size = ivec2(2, 2);
const ivec2 flower5Size = ivec2(5, 5);
vec4 flower1Pixels[flower1Size.x * flower1Size.y] = vec4[flower1Size.x * flower1Size.y](
vec4(0), vec4(1) , vec4(0),
vec4(1), vec4(1.0, 0.8784, 0.2706, 1.0), vec4(1),
vec4(0), vec4(1) , vec4(0)
);
vec4 flower2Pixels[flower2Size.x * flower2Size.y] = vec4[flower2Size.x * flower2Size.y](
vec4(0), vec4(0.9922, 0.7686, 0.4078, 1.0) , vec4(0),
vec4(0.9922, 0.7686, 0.4078, 1.0), vec4(0.8471, 0.5216, 0.0627, 1.0), vec4(0.9922, 0.7686, 0.4078, 1.0),
vec4(0), vec4(0.9922, 0.7686, 0.4078, 1.0) , vec4(0)
);
vec4 flower3Pixels[flower3Size.x] = vec4[flower3Size.x](vec4(1.0, 0.8784, 0.2706, 1.0));
vec4 flower4Pixels[flower4Size.x * flower4Size.y] = vec4[flower4Size.x * flower4Size.y](
vec4(0.1137, 0.3882, 0.1137, 1.0), vec4(0.5294, 0.2902, 0.5647, 1.0),
vec4(0.1059, 0.3333, 0.0863, 1.0), vec4(0.1137, 0.3882, 0.1137, 1.0)
);
vec4 flower5Pixels[flower5Size.x * flower5Size.y] = vec4[flower5Size.x * flower5Size.y](
vec4(0), vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0), vec4(0),
vec4(0), vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0.9137, 0.5882, 0.9647, 1.0), vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0.6627, 0.4118, 0.7373, 1.0),
vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0.9137, 0.5882, 0.9647, 1.0), vec4(0.8667, 0.2627, 0.9569, 1.0), vec4(0.9137, 0.5882, 0.9647, 1.0), vec4(0.6627, 0.4118, 0.7373, 1.0),
vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0.9137, 0.5882, 0.9647, 1.0), vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0),
vec4(0), vec4(0), vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0.6627, 0.4118, 0.7373, 1.0), vec4(0)
);
for (int i = 1; i <= FLOWER_AMOUNT; i++) {
if (NdotU > 0.99) {
ivec2 randomFlower1UV = ivec2((hash33(mod(floor(worldPos + atMidBlock / 64), vec3(200)) + i) * 0.5 + 0.5) * (FLOWER_SIZE + 1 - flower1Size.x)); // here the bigger component of flower1Size should be used, currently all flowers are symmetric
ivec2 randomFlower2UV = ivec2((hash33(mod(floor(worldPos + atMidBlock / 64), vec3(300)) + i) * 0.5 + 0.5) * (FLOWER_SIZE + 1 - flower2Size.x));
ivec2 randomFlower3UV = ivec2((hash33(mod(floor(worldPos + atMidBlock / 64), vec3(400)) + i) * 0.5 + 0.5) * (FLOWER_SIZE + 1 - flower3Size.x));
ivec2 randomFlower4UV = ivec2((hash33(mod(floor(worldPos + atMidBlock / 64), vec3(501))) * 0.5 + 0.5) * (FLOWER_SIZE + 1 - flower4Size.x)); // Only 1 flower should max generate on a block for flower4/5
ivec2 randomFlower5UV = ivec2((hash33(mod(floor(worldPos + atMidBlock / 64), vec3(500))) * 0.5 + 0.5) * (FLOWER_SIZE + 1 - flower5Size.x));
float randomFlower1Block = step(hash13(mod(floor(worldPos + atMidBlock / 64), vec3(300)) + i), 0.15 * flowerNoiseRemove * flowerNoiseAdd * FLOWER_DENSITY);
float randomFlower2Block = step(hash13(mod(floor(worldPos + atMidBlock / 64), vec3(200)) + i), 0.15 * flowerNoiseRemove * flowerNoiseAdd * FLOWER_DENSITY);
float randomFlower3Block = step(hash13(mod(floor(worldPos + atMidBlock / 64), vec3(500)) + i), 0.40 * flowerNoiseRemove * flowerNoiseAdd * FLOWER_DENSITY);
float randomFlower45Block = step(hash13(mod(floor(worldPos + atMidBlock / 64), vec3(400))) , 0.001 * flowerNoiseRemove * flowerNoiseAdd * FLOWER_DENSITY); // both purple flowers should appear only on the same block
float inverseRandomFlower45Block = randomFlower45Block * -1.0 + 1.0; // to remove other flower types on the block where the purple flower is on
ivec2 flower1RelCoord = flowerUV - randomFlower1UV;
ivec2 flower2RelCoord = flowerUV - randomFlower2UV;
ivec2 flower3RelCoord = flowerUV - randomFlower3UV;
ivec2 flower4RelCoord = flowerUV - randomFlower4UV;
ivec2 flower5RelCoord = flowerUV - randomFlower5UV;
if (all(greaterThanEqual(flower1RelCoord, ivec2(0))) && all(lessThan(flower1RelCoord, flower1Size))) { // if the position is inside the flower, do the flower
vec4 flower1Col = flower1Pixels[flower1RelCoord.x + flower1Size.x * flower1RelCoord.y]; // this flower pixel's colour
flower1Variable = flower1Col.a * randomFlower1Block * inverseRandomFlower45Block;
springColor = mix(springColor, flower1Col.rgb, flower1Variable); // apply the flower colour
}
if (all(greaterThanEqual(flower2RelCoord, ivec2(0))) && all(lessThan(flower2RelCoord, flower2Size))) {
vec4 flower2Col = flower2Pixels[flower2RelCoord.x + flower2Size.x * flower2RelCoord.y];
flower2Variable = flower2Col.a * randomFlower2Block * inverseRandomFlower45Block;
springColor = mix(springColor, flower2Col.rgb, flower2Variable);
}
if (all(greaterThanEqual(flower3RelCoord, ivec2(0))) && all(lessThan(flower3RelCoord, flower3Size))) {
vec4 flower3Col = flower3Pixels[flower3RelCoord.x + flower3RelCoord.y];
flower3Variable = flower3Col.a * randomFlower3Block * inverseRandomFlower45Block;
springColor = mix(springColor, flower3Col.rgb, flower3Variable);
}
if (all(greaterThanEqual(flower4RelCoord, ivec2(0))) && all(lessThan(flower4RelCoord, flower4Size))) {
vec4 flower4Col = flower4Pixels[flower4RelCoord.x + flower4Size.x * flower4RelCoord.y];
flower4Variable = flower4Col.a * randomFlower45Block;
flower4Emission = flower4Variable * (1.0 - step(flower4Col.r , 0.5));
springColor = mix(springColor, flower4Col.rgb, flower4Variable);
}
if (all(greaterThanEqual(flower5RelCoord, ivec2(0))) && all(lessThan(flower5RelCoord, flower5Size))) {
vec4 flower5Col = flower5Pixels[flower5RelCoord.x + flower5Size.x * flower5RelCoord.y];
flower5Variable = flower5Col.a * randomFlower45Block;
springColor = mix(springColor, flower5Col.rgb, flower5Variable);
}
#if EMISSIVE_FLOWERS > 0
flowerEmissionMask = max(emission, (flower1Variable + flower2Variable + flower3Variable + flower4Emission + flower5Variable)); // Emission Mask
#endif
}
}
#if EMISSIVE_FLOWERS > 0 && defined EMISSIVE_SPRING_FLOWERS
#if EMISSIVE_FLOWERS_TYPE == 1
if (color.b < max(color.r, color.g * 1.1) * 0.95) emission = 0.0;
#elif EMISSIVE_FLOWERS_TYPE == 2
if (color.r < max(color.b * 1.15, color.g * 1.1) * 0.95) emission = 0.0;
#endif
emission = 2.0 * skyLightCheck * flowerEmissionMask * pow3(springTime);
#if EMISSIVE_FLOWERS == 2
emission = max(emission, mix(0.0, rainFactor + 1.0 * rainFactor, flowerEmissionMask));
#endif
emission *= EMISSIVE_FLOWERS_STRENGTH;
#endif
}
#endif
#endif
float dryBiome = 1;
#ifdef DISABLE_SPRING_IN_DRY_BIOMES
dryBiome = 1.0 - inDry;
#endif
springColor = mix(color.rgb, springColor, springTime * dryBiome * (1.0 - inPaleGarden));
}
#endif
#if SEASONS == 1
vec3 summerToAutumn = mix(summerColor, autumnColor, summer);
vec3 autumnToWinter = mix(summerToAutumn, winterColor, autumn);
vec3 winterToSpring = mix(autumnToWinter, springColor, winter);
vec3 springToSummer = mix(winterToSpring, summerColor, spring);
#ifndef GBUFFERS_ENTITIES
color.rgb = springToSummer;
#endif
#elif SEASONS == 2
color.rgb = summerColor;
#elif SEASONS == 3
color.rgb = autumnColor;
#elif SEASONS == 4
color.rgb = winterColor;
#elif SEASONS == 5
color.rgb = springColor;
#endif
#ifdef GBUFFERS_ENTITIES
color.rgb = oldColor;
#endif
#endif