Files

486 lines
17 KiB
GLSL

#define NETHER_RELATED_SETTINGS
#define END_RELATED_SETTINGS
#define ATMOSPHERE_COEFF_RELATED_SETTINGS
#define SUN_AND_MOON_RELATED_SETTINGS
#define SKY_RELATED_SETTINGS
#define SHADOWMAP_CONSTANT_RELATED_SETTINGS
#define AMBIENT_LIGHT_RELATED_SETTINGS
#define SEASONS_RELATED_SETTINGS
#define VOLUMETRIC_CLOUD_RELATED_SETTINGS
#define VOLUMETRIC_FOG_RELATED_SETTINGS
#define SCENE_CONTROLLER_RELATED_SETTINGS
#include "/lib/settings.glsl"
#include "/lib/macro_lod_mod.glsl"
// this is an emergency plain text that will be visible as an the log error when a user tries to use voxy and DH both at once.
#if defined VOXY && defined DISTANT_HORIZONS
float errortext = THIS_IS_NOT_A_BUG_____YOU_CANNOT_USE_VOXY_AND_DISTANT_HORIZIONS_TOGETHER_____USE_ONE_OR_THE_OTHER;
#endif
#define DHVLFOG
#define ReflectedFog
flat varying vec3 averageSkyCol_Clouds;
flat varying vec3 averageSkyCol;
flat varying vec3 lightSourceColor;
flat varying vec3 sunColor;
flat varying vec3 sunColor2;
flat varying vec3 moonColor;
flat varying float exposure;
flat varying float avgBrightness;
flat varying float rodExposure;
flat varying float avgL2;
flat varying float centerDepth;
uniform sampler2D noisetex;
uniform sampler2D colortex1;
uniform float frameTime;
uniform int frameCounter;
uniform float frameTimeCounter;
uniform float rainStrength;
uniform float eyeAltitude;
uniform vec3 sunVec;
uniform vec2 texelSize;
uniform mat4 gbufferProjection;
uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferPreviousProjection;
uniform mat4 gbufferModelViewInverse;
uniform mat4 gbufferModelView;
uniform mat4 shadowModelView;
uniform mat4 shadowModelViewI;
uniform mat4 shadowProjection;
uniform float sunElevation;
uniform vec3 sunPosition;
uniform vec3 moonPosition;
uniform vec3 cameraPosition;
// uniform float far;
uniform ivec2 eyeBrightnessSmooth;
// uniform ivec2 eyeBrightness;
uniform float caveDetection;
uniform int isEyeInWater;
uniform float dayChangeSmooth;
uniform bool worldTimeChangeCheck;
uniform bool windowResizeCheck;
uniform int hideGUI;
uniform float near;
#include "/lib/util.glsl"
#include "/lib/ROBOBO_sky.glsl"
#include "/lib/sky_gradient.glsl"
#include "/lib/Shadow_Params.glsl"
// #include "/lib/waterBump.glsl"
vec4 lightCol = vec4(lightSourceColor, float(sunElevation > 1e-5)*2-1.);
vec3 WsunVec = mat3(gbufferModelViewInverse)*sunVec;
// vec3 WsunVec = normalize(LightDir);
vec2 decodeVec2(float a){
const vec2 constant1 = 65535. / vec2( 256., 65536.);
const float constant2 = 256. / 255.;
return fract( a * constant1 ) * constant2 ;
}
vec3 toLinear(vec3 sRGB){
return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);
}
vec3 toShadowSpaceProjected(vec3 p3){
p3 = mat3(gbufferModelViewInverse) * p3 + gbufferModelViewInverse[3].xyz;
p3 = mat3(shadowModelView) * p3 + shadowModelView[3].xyz;
p3 = diagonal3(shadowProjection) * p3 + shadowProjection[3].xyz;
return p3;
}
float interleaved_gradientNoise_temporal(){
return fract(52.9829189*fract(0.06711056*gl_FragCoord.x + 0.00583715*gl_FragCoord.y) + 1.0/1.6180339887 * frameCounter);
}
float interleaved_gradientNoise(){
vec2 coord = gl_FragCoord.xy;
float noise = fract(52.9829189*fract(0.06711056*coord.x + 0.00583715*coord.y));
return noise;
}
float R2_dither(){
vec2 alpha = vec2(0.75487765, 0.56984026);
return fract(alpha.x * gl_FragCoord.x + alpha.y * gl_FragCoord.y + 1.0/1.6180339887 * frameCounter) ;
}
float blueNoise(){
return fract(texelFetch(noisetex, ivec2(gl_FragCoord.xy)%512, 0).a + 1.0/1.6180339887 * frameCounter);
}
// #define diagonal3(m) vec3((m)[0].x, (m)[1].y, m[2].z)
// #define projMAD(m, v) (diagonal3(m) * (v) + (m)[3].xyz)
vec3 toScreenSpace(vec3 p) {
vec4 iProjDiag = vec4(gbufferProjectionInverse[0].x, gbufferProjectionInverse[1].y, gbufferProjectionInverse[2].zw);
vec3 feetPlayerPos = p * 2. - 1.;
vec4 viewPos = iProjDiag * feetPlayerPos.xyzz + gbufferProjectionInverse[3];
return viewPos.xyz / viewPos.w;
}
#include "/lib/DistantHorizons_projections.glsl"
vec3 DH_toScreenSpace(vec3 p) {
vec4 iProjDiag = vec4(LOD_PROJECTION_INVERSE[0].x, LOD_PROJECTION_INVERSE[1].y, LOD_PROJECTION_INVERSE[2].zw);
vec3 feetPlayerPos = p * 2. - 1.;
vec4 viewPos = iProjDiag * feetPlayerPos.xyzz + LOD_PROJECTION_INVERSE[3];
return viewPos.xyz / viewPos.w;
}
vec3 DH_toClipSpace3(vec3 viewSpacePosition) {
return projMAD(LOD_PROJECTION, viewSpacePosition) / -viewSpacePosition.z * 0.5 + 0.5;
}
float DH_ld(float dist) {
return (2.0 * LOD_NEARPLANE) / (LOD_FARPLANE + LOD_NEARPLANE - dist * (LOD_FARPLANE - LOD_NEARPLANE));
}
float DH_inv_ld (float lindepth){
return -((2.0*LOD_NEARPLANE/lindepth)-LOD_FARPLANE-LOD_NEARPLANE)/(LOD_FARPLANE-LOD_NEARPLANE);
}
float linearizeDepthFast(const in float depth, const in float near, const in float far) {
return (near * far) / (depth * (near - far) + far);
}
float invLinZ (float lindepth){
return -((2.0*near/lindepth)-far-near)/(far-near);
}
// #define LIGHTNINGFLASH_VL
#include "/lib/lightning_stuff.glsl"
#ifdef OVERWORLD_SHADER
// uniform sampler2D colortex4;
// uniform sampler2D colortex12;
// const bool shadowHardwareFiltering = true;
uniform sampler2DShadow shadow;
// #undef TRANSLUCENT_COLORED_SHADOWS
#ifdef TRANSLUCENT_COLORED_SHADOWS
uniform sampler2D shadowcolor0;
uniform sampler2DShadow shadowtex0;
uniform sampler2DShadow shadowtex1;
#endif
#define TIMEOFDAYFOG
#define USE_SCENE_CONTROLLER_SETTINGS
#include "/lib/scene_controller.glsl"
#define VL_CLOUDS_DEFERRED
#include "/lib/volumetricClouds.glsl"
#include "/lib/climate_settings.glsl"
#include "/lib/overworld_fog.glsl"
#endif
#ifdef NETHER_SHADER
uniform sampler2D colortex4;
#include "/lib/nether_fog.glsl"
#endif
#ifdef END_SHADER
uniform sampler2D colortex4;
#include "/lib/end_fog.glsl"
#endif
vec3 rodSample(vec2 Xi)
{
float r = sqrt(1.0f - Xi.x*Xi.y);
float phi = 2 * 3.14159265359 * Xi.y;
return normalize(vec3(cos(phi) * r, sin(phi) * r, Xi.x)).xzy;
}
//Low discrepancy 2D sequence, integration error is as low as sobol but easier to compute : http://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
vec2 R2_samples(float n){
vec2 alpha = vec2(0.75487765, 0.56984026);
return fract(alpha * n);
}
float HG_phase(float x, float g){
float gg = g * g;
return (gg * -0.25 + 0.25) * pow(-2.0 * (g * x) + (gg + 1.0), -1.5) / 3.14;
}
vec3 doPixelTimer(in vec3 targetValue, in vec3 prevFrameValue){
// do not transition if the shader has just loaded or if the window resized.
if(frameCounter < 2 || windowResizeCheck) return targetValue;
// if the value is below the target value, add time. if the value is above the target value, subtract time.
// this polarity variable determines what direction on the numberline to go.
vec3 polarity = floor(clamp((targetValue - prevFrameValue)*65000.0,-1.0,1.0));
// values that are extremely small interpolate *too fast* with a constant rate.
// so scale the rate to be slower when the target value is very small.
prevFrameValue += polarity * (frameTime/(15.0 * (1.0/clamp(targetValue,0.1,1.0)))) * (float(SCENE_CONTROLLER_TRANSITION_RATE)/100.0f);
return prevFrameValue;
}
void main() {
/* RENDERTARGETS:4 */
gl_FragData[0] = vec4(0.0);
//Temporally accumulate sky and light values
vec3 frameHistory = texelFetch(colortex4,ivec2(gl_FragCoord.xy),0).rgb;
float mixhistory = 0.06;
if(windowResizeCheck || frameCounter < 2){
mixhistory = 1.0;
}
#ifdef OVERWORLD_SHADER
///////////////////////////////
/// --- STORE COLOR LUT --- ///
///////////////////////////////
vec3 AmbientLightTint = vec3(AmbientLight_R, AmbientLight_G, AmbientLight_B);
// --- the color of the atmosphere + the average color of the atmosphere.
vec3 skyGroundCol = skyFromTex(vec3(0, -1 ,0), colortex4).rgb;// * clamp(WsunVec.y*2.0,0.2,1.0);
/// --- Save light values
if (gl_FragCoord.x < 1. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 ){
gl_FragData[0] = vec4(averageSkyCol_Clouds * AmbientLightTint,1.0);
if(worldTimeChangeCheck) mixhistory = 1.0;
}
if (gl_FragCoord.x > 1. && gl_FragCoord.x < 2. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 ){
gl_FragData[0] = vec4((skyGroundCol/150.0) * AmbientLightTint,1.0);
if(worldTimeChangeCheck) mixhistory = 1.0;
}
#ifdef ambientLight_only
if (gl_FragCoord.x > 6. && gl_FragCoord.x < 7. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 )
gl_FragData[0] = vec4(0.0,0.0,0.0,1.0);
if (gl_FragCoord.x > 8. && gl_FragCoord.x < 9. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 )
gl_FragData[0] = vec4(0.0,0.0,0.0,1.0);
if (gl_FragCoord.x > 13. && gl_FragCoord.x < 14. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 )
gl_FragData[0] = vec4(0.0,0.0,0.0,1.0);
#else
if (gl_FragCoord.x > 6. && gl_FragCoord.x < 7. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 ){
gl_FragData[0] = vec4(lightSourceColor,1.0);
if(worldTimeChangeCheck) mixhistory = 1.0;
}
if (gl_FragCoord.x > 8. && gl_FragCoord.x < 9. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 ){
gl_FragData[0] = vec4(sunColor,1.0);
if(worldTimeChangeCheck) mixhistory = 1.0;
}
if (gl_FragCoord.x > 9. && gl_FragCoord.x < 10. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 ){
gl_FragData[0] = vec4(moonColor,1.0);
if(worldTimeChangeCheck) mixhistory = 1.0;
}
#endif
// #if defined FLASHLIGHT && defined FLASHLIGHT_BOUNCED_INDIRECT
// // sample center pixel of albedo color, and interpolate it overtime.
// if (gl_FragCoord.x > 15 && gl_FragCoord.x < 16 && gl_FragCoord.y > 2 && gl_FragCoord.y < 3){
// mixhistory = 0.01;
// vec3 data = texelFetch(colortex1, ivec2(0.5/texelSize), 0).rgb;
// vec3 decodeAlbedo = vec3(decodeVec2(data.x).x,decodeVec2(data.y).x, decodeVec2(data.z).x);
// vec3 albedo = toLinear(decodeAlbedo);
// albedo = normalize(albedo + 1e-7) * (dot(albedo,vec3(0.21, 0.72, 0.07))*0.5+0.5);
// gl_FragData[0] = vec4(albedo,1.0);
// }
// #endif
////////////////////////////////
/// --- ATMOSPHERE IMAGE --- ///
////////////////////////////////
/// --- Sky only
if (gl_FragCoord.x > 18. && gl_FragCoord.y > 1. && gl_FragCoord.x < 18+257){
vec2 p = clamp(floor(gl_FragCoord.xy-vec2(18.,1.))/256.,0.0,1.0);
vec3 viewVector = cartToSphere(p);
vec2 planetSphere = vec2(0.0);
vec3 sky = vec3(0.0);
vec3 skyAbsorb = vec3(0.0);
vec3 mC = vec3(fog_coefficientMieR*1e-6, fog_coefficientMieG*1e-6, fog_coefficientMieB*1e-6);
sky = calculateAtmosphere(averageSkyCol*2000.0, viewVector, vec3(0.0,1.0,0.0), WsunVec, -WsunVec, planetSphere, skyAbsorb, 10, blueNoise());
// fade atmosphere conditions for rain away when you pass above the cloud plane.
float heightRelativeToClouds = clamp(1.0 - max(eyeAltitude - CloudLayer0_height,0.0) / 200.0 ,0.0,1.0);
if(rainStrength > 0.0) sky = mix(sky, averageSkyCol * 2000.0 * (skyAbsorb*0.7+0.3), clamp(1.0 - exp(pow(clamp(-viewVector.y+0.9,0.0,1.0),2) * -5.0),0.0,1.0) * heightRelativeToClouds * rainStrength);
#ifdef AEROCHROME_MODE
sky *= vec3(0.0, 0.18, 0.35);
#endif
gl_FragData[0] = vec4(sky / 4000.0 , 1.0);
if(worldTimeChangeCheck) mixhistory = 1.0;
}
/// --- Sky + clouds + fog
if (gl_FragCoord.x > 18.+257. && gl_FragCoord.y > 1. && gl_FragCoord.x < 18+257+257.){
vec2 p = clamp(floor(gl_FragCoord.xy-vec2(18.+257,1.))/256.,0.0,1.0);
vec3 viewVector = cartToSphere(p);
vec3 viewPos = mat3(gbufferModelView)*viewVector*1024.0;
float noise = interleaved_gradientNoise_temporal();
WsunVec = normalize(mat3(gbufferModelViewInverse) * sunPosition + gbufferModelViewInverse[3].xyz);// * ( float(sunElevation > 1e-5)*2.0-1.0 );
vec3 WmoonVec = normalize(mat3(gbufferModelViewInverse) * moonPosition + gbufferModelViewInverse[3].xyz);// * ( );
if(dot(-WmoonVec, WsunVec) < 0.9999) WmoonVec = -WmoonVec;
WsunVec = mix(WmoonVec, WsunVec, clamp(float(sunElevation > 1e-5)*2.0-1.0 ,0,1));
vec3 sky = texelFetch(colortex4,ivec2(gl_FragCoord.xy)-ivec2(257,0),0).rgb/150.0;
sky = mix(averageSkyCol_Clouds * AmbientLightTint * 0.25, sky, pow(clamp(viewVector.y+1.0,0.0,1.0),5.0));
vec3 suncol = lightSourceColor;
#ifdef ambientLight_only
suncol = vec3(0.0);
#endif
// the idea is to interpolate between 4 HG function calls with different G parameters
float SdotV = dot(WsunVec, normalize(mat3(gbufferModelViewInverse) * viewPos + gbufferModelViewInverse[3].xyz));
float backScatterPhase = HG_phase(-SdotV, 0.25) * 2.0;
vec4 phaseLevels = vec4(HG_phase(SdotV, 0.80), HG_phase(SdotV, 0.55), HG_phase(SdotV, 0.35), HG_phase(SdotV, 0.10));
float cloudPlaneDistance = 0.0;
vec4 volumetricClouds = GetVolumetricClouds(viewPos, vec2(noise, 1.0-noise), WsunVec, suncol*2.5, skyGroundCol/30.0, cloudPlaneDistance, phaseLevels, backScatterPhase);
vec4 volumetricFog = GetVolumetricFog(viewPos,vec2(noise, 1.0-noise), WsunVec, suncol*2.5, skyGroundCol/30.0, averageSkyCol_Clouds*5.0, cloudPlaneDistance, phaseLevels, backScatterPhase);
sky = sky * volumetricClouds.a + volumetricClouds.rgb / 5.0;
sky = sky * volumetricFog.a + volumetricFog.rgb / 5.0;
gl_FragData[0] = vec4(sky,1.0);
if(worldTimeChangeCheck) mixhistory = 1.0;
}
#ifdef FAKE_PLANET
vec2 pixelPos2 = vec2(16,1);
if (gl_FragCoord.x > pixelPos2.x && gl_FragCoord.x < pixelPos2.x + 1 && gl_FragCoord.y > pixelPos2.y){
if(worldTimeChangeCheck) mixhistory = 1.0;
vec3 pos = vec3(0.0);
pos.y = clamp(gl_FragCoord.y/256.0,0.0,1.0);
// approximate how much atmosphere the sun is travelling through and scale abso
pos.y = pos.y / (1.0/abs(WsunVec.y))*5.0;
vec2 variable = vec2(0);
vec3 absorb = vec3(0.0);
vec3 transmittance = calculateAtmosphere(vec3(0.0), pos, vec3(0.0,1.0,0.0), pos, vec3(0.0), variable, absorb, 25, 0.0);
transmittance = min(sunColor2 * absorb, sunColor2);
gl_FragData[0] = vec4(transmittance, 1.0);
}
#endif
#endif
#if defined NETHER_SHADER || defined END_SHADER
vec2 fogPos = vec2(256.0 - 256.0*0.12,1.0);
//Sky gradient with clouds
if (gl_FragCoord.x > (fogPos.x - fogPos.x*0.22) && gl_FragCoord.y > 0.4 && gl_FragCoord.x < 535){
vec2 p = clamp(floor(gl_FragCoord.xy-fogPos)/256.,-0.2,1.2);
vec3 viewVector = cartToSphere(p);
float noise = interleaved_gradientNoise_temporal();
vec3 BackgroundColor = vec3(0.0);
vec4 VL_Fog = GetVolumetricFog(mat3(gbufferModelView)*viewVector*256., noise, 1.0-noise);
BackgroundColor += VL_Fog.rgb;
gl_FragData[0] = vec4(BackgroundColor*8.0, 1.0);
}
#endif
/// resolve
vec3 currentFrame = gl_FragData[0].rgb*150.0;
gl_FragData[0].rgb = clamp(mix(frameHistory, currentFrame, clamp(mixhistory,0.0,1.0)),0.0,65000.0);
//////////////////////////////////////////////
/// --- STORE DAILY WEATHER PARAMETERS --- ///
//////////////////////////////////////////////
#if defined OVERWORLD_SHADER
// the idea is to store the 8 values, coverage + density of 3 cloud layers and 2 fog density values.
if (gl_FragCoord.x > 1 && gl_FragCoord.x < 4 && gl_FragCoord.y > 1 && gl_FragCoord.y < 4){
struct sceneControlleree {
vec2 smallCumulus_N;
vec2 largeCumulus_N;
vec2 altostratus_N;
vec2 fog_N;
vec2 localFog_N;
vec3 localFogColor_N;
} parameters_new;
applySceneControllerParameters(
parameters_new.smallCumulus_N.x, parameters_new.smallCumulus_N.y,
parameters_new.largeCumulus_N.x, parameters_new.largeCumulus_N.y,
parameters_new.altostratus_N.x, parameters_new.altostratus_N.y,
parameters_new.fog_N.x, parameters_new.fog_N.y,
parameters_new.localFog_N.x, parameters_new.localFog_N.y, parameters_new.localFogColor_N.rgb
);
vec3 targetParameterValues = writeSceneControllerParameters(
gl_FragCoord.xy,
parameters_new.smallCumulus_N,
parameters_new.largeCumulus_N,
parameters_new.altostratus_N,
parameters_new.fog_N,
parameters_new.localFog_N,
parameters_new.localFogColor_N
);
#if SCENE_CONTROLLER_TRANSITION_RATE > 1000
gl_FragData[0].rgb = targetParameterValues;
#elif SCENE_CONTROLLER_TRANSITION_RATE <= 1000
gl_FragData[0].rgb = doPixelTimer(targetParameterValues, frameHistory);
#endif
}
#endif
//////////////////////////////////////////////
//////////// --- END STUFF --- ///////////////
//////////////////////////////////////////////
#ifdef END_SHADER
/* ---------------------- POSITION ---------------------- */
vec2 pixelPos2 = vec2(2,1);
if (gl_FragCoord.x > pixelPos2.x && gl_FragCoord.x < pixelPos2.x + 1 && gl_FragCoord.y > pixelPos2.y && gl_FragCoord.y < pixelPos2.y + 1){
vec3 PrevPos = frameHistory*2.0-1.0;
float travelledDist = length(PrevPos.xyz);
vec3 randomDir = normalize(randomPosXYZ.xyz);
// guide the bolt back to the origin with randomized jagged movement.
float heuristic = clamp(dot(-randomDir,normalize(PrevPos)),-1.0,1.0) * (1.0-clamp(10.0-travelledDist,0.0,1.0));
float rate = frameTime*500.0;
vec3 CurrPos = PrevPos + randomDir * rate * heuristic;
if(travelledDist > 384.0 || (travelledDist < 10.0 && randomPosXYZ.w > 0.8) ) CurrPos = randomDir*384.0;
gl_FragData[0] = vec4(CurrPos*0.5+0.5, 1.0);
}
#endif
//Exposure values
if (gl_FragCoord.x > 10. && gl_FragCoord.x < 11. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 )
gl_FragData[0] = vec4(exposure, avgBrightness, avgL2, 1.0);
if (gl_FragCoord.x > 14. && gl_FragCoord.x < 15. && gl_FragCoord.y > 19.+18. && gl_FragCoord.y < 19.+18.+1 )
gl_FragData[0] = vec4(rodExposure, centerDepth, 0.0, 1.0);
}