Skip to content

Instantly share code, notes, and snippets.

@jcm2606
Created January 13, 2017 15:41
Show Gist options
  • Save jcm2606/4e44311f0be959c713fd7ff84639efc6 to your computer and use it in GitHub Desktop.
Save jcm2606/4e44311f0be959c713fd7ff84639efc6 to your computer and use it in GitHub Desktop.
#version 120
/*
Clarity Shader Pack for Minecraft. Written by jcm2606, credit to Chocapic13 and the author of "bump-shadow-waving-0.9.9-140906".
Please read "license.txt" at the root of the shader pack before editing this file. Any edits done to this file fall under the terms outlined in "license.txt".
*/
#include "/common/materials.glsl"
#include "/common/colouring.glsl"
#include "/common/visualisation.glsl"
/////////////////////////
// START FEATURE OPTIONS
/////////////////////////
// GODSRAYS
#define GODSRAYS
#define GODSRAYS_SAMPLES 25 // Sample count for godsrays. This affects how many iterations are made for calculating gods rays. More samples means more accuracy, at the cost of performance. Less samples means better performance, at the cost of accuracy and producing 'banding'. [15 20 25 30 50]
#define GODSRAYS_DECAYFACTOR 2.5 // Influences how quick godsrays 'decay'. Higher values mean godsrays decay quicker, hence causing them to be shorter. Lower values mean godsrays are projected longer, but causes banding to become very apparent. [2 2.5 3 3.5 4 4.5 5 5.5 6 8 12 16]
#define GODSRAYS_DECAYMULTIPLIER 1.0 // Final decay multiplier. Used for adjustment. [0.7 0.8 0.9 1.0 1.1 1.2]
#define GODSRAYS_MASKINTENSITY 0.1 // Intensity used to calculate the mask for godsrays. Omitted from godsrays settings due to being redundant except for finer tweaking. [0.025 0.05 0.1 0.2 0.3]
#define GODSRAYS_MOONRAYS // When enabled, renders godsrays during the night from the moon, attuned to the colour of moonlight.
// SHADOWING
#define SHADOWING // Enables use of direct lighting in Clarity. Having this on will impact performance, especially with a larger shadow map resolution. When off, Clarity will use purely ambient lighting.
#define SHADOW_BIAS 0.8
#define SHADOW_FILTER // Uses offsets to smooth shadowing. Can improve quality of shadows at lower resolutions.
//#define SHADOW_HQ_FILTER // Uses more offsets to give a better quality result, at the cost of FPS.
//#define SHADOW_LQ_FILTER // Uses less offsets to reduce the impact on performance, at the cost of quality.
#define SHADOW_FILTER_STEP 0.625 // Influences how blurred shadows will be with the filter enabled. A high step value can seriously help to hide aliasing. [0.15625 0.3125 0.625 1.25 2.5]
#define WATER_CAUSTICS // Draws caustics in water simulating the absorption and scattering of light through water.
// SSAO
#define SSAO // Effect toggle for screen-space ambient occlusion. The SSAO implementation is a modified edge detection algorithm, with an upper and lower threshold to isolate edges that overlap nearby surfaces.
#define SSAO_OFFSET_RADIUS 0.015 // The radius the shader uses to offset the samples. [0.005 0.01 0.015 0.02 0.025]
#define SSAO_SAMPLE_RADIUS 0.005 // The radius the samples themselves use. Shouldn't be changed.
#define SSAO_THRESHOLD 0.03 // The maximum distance SSAO will deem valid for occlusion. Higher threshold means occlusion is cut off further away, meaning more edge shadows. Too high can cause edge outlines. [0.015 0.02 0.025 0.03 0.035 0.04 0.05]
#define SSAO_THRESHOLD_FOLIAGE 0.05 // The maximum distance SSAO will deem valid for occlusion when sampling foliage. Same as regular threshold, just amplified to give foliage better shading without tarnishing other blocks. [0.015 0.02 0.025 0.03 0.05 0.08 0.085 0.09 0.095 0.1 0.11 0.1125 0.125 0.15 0.175 0.2]
#define SSAO_INTENSITY 7.5 // The intensity of occlusion. Higher means darker AO shadows.[7.5]
// LIGHTING
#define LIGHTING_FOLIAGE_BOOST 1.15 // Boosts ambient lighting for foliage to make foliage blend with the terrain better. [1.05 1.1 1.15 1.2 1.25 1.3 1.35 1.4 1.45 1.5 1.55 1.6]
#define LIGHTING_BLOCK_RAIN_EFFECT // When enabled, attenuation and intensity will change during rain.
#define LIGHTING_BLOCK_COLOUR_RED 1.0 // Red value of block light colour. [0.0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1.0]
#define LIGHTING_BLOCK_COLOUR_GREEN 0.48 // Green value of block light colour. [0.0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.58 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1.0]
#define LIGHTING_BLOCK_COLOUR_BLUE 0.02 // Blue value of block light colour. [0.0 0.05 0.1 0.15 0.16 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1.0]
#define LIGHTING_BLOCK_ATTENUATION 4.8 // Block light attenuation. This affects the falloff curve of lighting, affecting how light "bunches up" near the source. Higher the attenuation, more intense the light is near the source. [3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4]
#define LIGHTING_BLOCK_MULTIPLIER 1.8 // Block light multiplier.
#define LIGHTING_BLOCK_INTENSITY 0.33 // Block light intensity. This affects how intense block lighting is. Lower values respect attenuation, though higher values can overcome attenuation. [2.8 3.0 3.1 3.2 3.3 3.4 3.5 3.6 4.0 5.0]
#define LIGHTING_BLOCK_ATTENUATION_RAIN 5.2 // Block light attenuation for rain. Only takes affect whilst it's raining. [3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4]
#define LIGHTING_BLOCK_MULTIPLIER_RAIN 1.8 // Block light multiplier for rain. Only takes affect whilst it's raining.
#define LIGHTING_BLOCK_INTENSITY_RAIN 0.34 // Block light intensity for rain. Only takes affect whilst it's raining. [2.8 3.0 3.1 3.2 3.3 3.4 3.5 3.6 4.0 5.0]
// SKY
#define SKY_NIGHT_PRESET 0 // Changes what colour the night sky is. [0 1]
#define VOLUMETRIC_LIGHT // Approximates scattering of light through particles in the air such as fog or smoke, causing distinct rays of light to be cast from the sun/moon volumetrically. Basically, this does what godsrays does, except much better in you don't have to be looking at the sun/moon to see the rays. With volumetric light enabled, you can either edit the final multiplier to tweak how strong the effect is globally, or edit specific strength values.
#define VL_QUALITY 2.0 // Affects the density of the dithering used to sample the shadow map. Higher values result in denser dithering, also impacting performance. Denser dithering can substantially improve the quality of volumetric light, reducing the "lattice structure" artifact. [1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0]
#define VL_DISTANCE 30.0
///////////////////////
// END FEATURE OPTIONS
///////////////////////
/* DRAWBUFFERS:3120 */
const int shadowMapResolution = 2048; // Shadow resolution. Increasing this improves the quality and accuracy of shadows, at the cost of performance. Render distance compounds the performance hit. [512 1024 2048 4096]
const float shadowDistance = 256; // Shadow distance. Increasing this allows the shadows to be projected and rendered farther, at the cost of quality. [32 64 96 128 160 192 256 320 384 448 512]
//const float shadowIntervalSize = 1.0f;
const bool shadowHardwareFiltering = true;
const int noiseTextureResolution = 64;
const int RGBA16 = 1;
const int compositeFormat = RGBA16;
const int gcolourFormat = RGBA16;
// ----------
uniform sampler2D gcolour; // colour buffer
uniform sampler2D gnormal; // screen normals
uniform sampler2D gdepth; // lightmap - skylight, blocklight, surface (0.05 water, 0.1 other transparent, 0.9 land, 0.2 shadow return, 0.3 hand, 1 sky, 0.4 entity, 0.5 weather, 0.91 lighting boost land)
uniform sampler2D composite; // effect data - godsrays mask, ssao occlusion, volumetric light
uniform sampler2D gaux1; // specular
uniform sampler2D gaux2; // weather
uniform sampler2D gaux3; // screen properties - surface material, sky mask, water mask
uniform sampler2D gaux4;
uniform sampler2D depthtex0;
uniform sampler2D depthtex1;
uniform sampler2D colortex1; // ambient light
uniform sampler2D noisetex;
uniform sampler2DShadow shadowtex0;
uniform sampler2DShadow shadowtex1;
#ifdef SHADOWING
uniform sampler2DShadow shadow;
uniform sampler2DShadow watershadow;
uniform sampler2DShadow shadowcolor;
uniform sampler2D shadowcolor0;
uniform sampler2D shadowcolor1;
#endif
uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferModelViewInverse;
uniform mat4 shadowProjection;
uniform mat4 shadowModelView;
uniform mat4 shadowProjectionInverse;
uniform mat4 shadowModelViewInverse;
uniform mat4 gbufferProjection;
uniform int fogMode;
uniform int worldTime;
uniform int isEyeInWater;
uniform float aspectRatio;
uniform float far;
uniform float near;
uniform float viewWidth;
uniform float viewHeight;
uniform float sunAngle;
uniform float rainStrength;
uniform float frameTimeCounter;
uniform vec3 sunPosition;
uniform vec3 moonPosition;
uniform vec3 cameraPosition;
uniform ivec2 eyeBrightnessSmooth;
varying vec4 texcoord;
//varying vec3 specMultiplier;
varying vec3 lightVector;
varying vec3 ambientLight; // go to '/common/lighting.glsl' to edit ambient lighting
varying vec3 directLight; // go to '/common/lighting.glsl' to edit direct lighting
varying vec3 sunVector;
varying vec3 moonVector;
varying vec3 upVector;
varying float hour;
varying float sunVisibility;
varying float moonVisibility;
varying float SdotU;
varying float MdotU;
vec3 normal = texture2D(gnormal, texcoord.st).rgb * 2.0 - 1.0;
const vec3 lightBlockColour = vec3(LIGHTING_BLOCK_COLOUR_RED, LIGHTING_BLOCK_COLOUR_GREEN, LIGHTING_BLOCK_COLOUR_BLUE);
const int FOGMODE_LINEAR = 9729;
const int FOGMODE_EXP = 2048;
const float PI = 3.1415927;
const float sunPathRotation = -27.3; // default 0.0
float rainx = clamp(rainStrength, 0.0f, 1.0f)/1.0f;
// gbufferProjectionInverse * (fpos0 * 2.0 - 1.0);
vec4 fpos0;
vec4 fpos1;
#ifdef SHADOWING
vec4 faux1 = texture2D(gaux1, texcoord.st);
vec4 faux2 = texture2D(gaux2, texcoord.st);
#endif
float depth0 = texture2D(depthtex0, texcoord.st).x;
float depth1 = texture2D(depthtex1, texcoord.st).x;
// Poisson distribution for shadow sampling with shadow filtering enabled.
const vec2 circleOffsets[25] = vec2[25](vec2(-0.4894566f,-0.3586783f),
vec2(-0.1717194f,0.6272162f),
vec2(-0.4709477f,-0.01774091f),
vec2(-0.9910634f,0.03831699f),
vec2(-0.2101292f,0.2034733f),
vec2(-0.7889516f,-0.5671548f),
vec2(-0.1037751f,-0.1583221f),
vec2(-0.5728408f,0.3416965f),
vec2(-0.1863332f,0.5697952f),
vec2(0.3561834f,0.007138769f),
vec2(0.2868255f,-0.5463203f),
vec2(-0.4640967f,-0.8804076f),
vec2(0.1969438f,0.6236954f),
vec2(0.6999109f,0.6357007f),
vec2(-0.3462536f,0.8966291f),
vec2(0.172607f,0.2832828f),
vec2(0.4149241f,0.8816f),
vec2(0.136898f,-0.9716249f),
vec2(-0.6272043f,0.6721309f),
vec2(-0.8974028f,0.4271871f),
vec2(0.5551881f,0.324069f),
vec2(0.9487136f,0.2605085f),
vec2(0.7140148f,-0.312601f),
vec2(0.0440252f,0.9363738f),
vec2(0.620311f,-0.6673451f)
);
const vec2 boffsets[] = vec2[] (
vec2(1,0),
vec2(-1,0),
vec2(0,1),
vec2(0,-1),
vec2(0.7, 0.7),
vec2(-0.7, 0.7),
vec2(0.7, -0.7),
vec2(-0.7, -0.7),
vec2(0.35, 0.9),
vec2(-0.35, 0.9),
vec2(0.35, -0.9),
vec2(-0.35, -0.9),
vec2(0.9, 0.35),
vec2(-0.9, 0.35),
vec2(0.9, -0.35),
vec2(-0.9, -0.35)
);
const vec2 conservativeOffsets[] = vec2[] (
vec2(1,0),
vec2(-1,0),
vec2(0,1),
vec2(0,-1),
vec2(0.7, 0.7),
vec2(-0.7, 0.7),
vec2(0.7, -0.7),
vec2(-0.7, -0.7)
);
vec4 fambient = texture2D(colortex1, texcoord.st);
bool godsraysIsDay = (hour >= 0.0 && hour <= 12.7) || hour >= 23000;
#include "/common/sky.glsl"
#include "/common/normaldistortion.glsl"
#include "/common/noise.glsl"
#include "/common/depth.glsl"
vec3 nvec3(vec4 pos) {
return pos.xyz/pos.w;
}
vec4 nvec4(vec3 pos) {
return vec4(pos.xyz, 1.0);
}
vec3 convertScreenSpaceToWorldSpace(vec2 co, float depth) {
vec4 fragposition = gbufferProjectionInverse * vec4(vec3(co, depth) * 2.0 - 1.0, 1.0);
fragposition /= fragposition.w;
return fragposition.xyz;
}
float getShadowBiasDistort(vec4 wpos) {
vec2 pos1 = abs(wpos.xy * 1.165);
float distb = pow(pow(pos1.x, 8.0) + pow(pos1.y, 8.0), 1.0 / 8.0);
return (1.0 - SHADOW_BIAS) + distb * SHADOW_BIAS;
}
vec4 biasShadowPosition(vec4 wpos) {
float distortionFactor = getShadowBiasDistort(wpos);
wpos.xy /= distortionFactor * 0.97;
wpos = wpos * vec4(0.5, 0.5, 0.2, 0.5) + vec4(0.5);
return wpos;
}
vec4 getShadowWorldPos(float shadowdepth, vec2 texcoord){
vec4 sfragposition = nvec4(convertScreenSpaceToWorldSpace(texcoord.st,shadowdepth));
sfragposition.xy *= mix(1.0, 0.817, float(isEyeInWater));
vec4 sworldposition = vec4(0.0);
sworldposition = gbufferModelViewInverse * sfragposition;
sworldposition = shadowModelView * sworldposition;
sworldposition = shadowProjection * sworldposition;
sworldposition /= sworldposition.w;
return sworldposition;
}
#ifdef VOLUMETRIC_LIGHT
float distx(float dist){
return (far * (dist - near)) / (dist * (far - near));
}
// dirived from: http://devlog-martinsh.blogspot.nl/2011/03/glsl-8x8-bayer-matrix-dithering.html
float find_closest(vec2 pos) {
const int ditherPattern[64] = int[64](
0, 32, 8, 40, 2, 34, 10, 42, /* 8x8 Bayer ordered dithering */
48, 16, 56, 24, 50, 18, 58, 26, /* pattern. Each input pixel */
12, 44, 4, 36, 14, 46, 6, 38, /* is scaled to the 0..63 range */
60, 28, 52, 20, 62, 30, 54, 22, /* before looking in this table */
3, 35, 11, 43, 1, 33, 9, 41, /* to determine the action. */
51, 19, 59, 27, 49, 17, 57, 25,
15, 47, 7, 39, 13, 45, 5, 37,
63, 31, 55, 23, 61, 29, 53, 21);
vec2 positon = vec2(0.0f);
positon.x = floor(mod(texcoord.s * viewWidth, 8.0f));
positon.y = floor(mod(texcoord.t * viewHeight, 8.0f));
int dither = ditherPattern[int(positon.x) + int(positon.y) * 8];
return float(dither) / 64.0f;
}
float dynamicExposure()
{
return mix(1.0,0.0,(pow(eyeBrightnessSmooth.y / 240.0f, 3.0f)));
}
float getVolumetricRays() {
///////////////////////Setting up functions///////////////////////
vec3 rSD = vec3(0.0);
rSD.x;
rSD.y = 6.0 / VL_QUALITY;
rSD.z = find_closest(texcoord.st);
//rSD.z = 1;
rSD.z *= rSD.y;
const float maxDist = (VL_DISTANCE);
float minDist = (0.01);
minDist += rSD.z;
float weight = (maxDist / rSD.y);
const vec2 diffthresh = vec2(0.0005, -0.001); // Fixes light leakage from walls
vec4 worldposition = vec4(0.0);
for (minDist; minDist < maxDist;) {
///////////////////////MAKING VL NOT GO THROUGH WALLS///////////////////////
if (depthExpToLinear(depth1) < minDist){
break;
}
///////////////////////Getting worldpositon///////////////////////
worldposition = getShadowWorldPos(distx(minDist),texcoord.st);
///////////////////////Rescaling ShadowMaps///////////////////////
worldposition = biasShadowPosition(worldposition);
///////////////////////Projecting shadowmaps on a linear depth plane///////////////////////
rSD.x += (shadow2D(shadowtex1, worldposition.rgb).z);
minDist = minDist + rSD.y;
}
///////////////////////Returning the program///////////////////////
rSD.x /= weight;
rSD.x *= 0.15 * maxDist / 32;
rSD.x = mix(rSD.x, clamp(rSD.x, 0.0, 0.1), dynamicExposure());
return rSD.x;
}
#else
float getVolumetricRays(){
return 0.0;
}
#endif
vec4 getFpos(){
vec4 fragposition = gbufferProjectionInverse * vec4(texcoord.s * 2.0f - 1.0f, texcoord.t * 2.0f - 1.0f, 2.0f * depth1 - 1.0f, 1.0f);
fragposition /= fragposition.w;
fragposition.xy *= mix(1.0, 0.831, float(isEyeInWater));
return fragposition;
}
vec4 getWpos(vec4 fragposition){
vec4 worldposition = vec4(0.0);
worldposition = gbufferModelViewInverse * fragposition;
//worldposition /= worldposition.w;
return worldposition;
}
vec3 getShadowShading(out float shading, out float solidshading, out float transparentshading, out vec3 sampledcolour, out vec3 sfpos, float translucent) {
vec4 shadowPosition = biasShadowPosition(getShadowWorldPos(depth1, texcoord.st));
sfpos = normalize(getFpos().xyz);
float distortion = getShadowBiasDistort(shadowPosition);
float step = 3.0 / shadowMapResolution * (1.0 + rainx * 5.0);
float NdotL = clamp(dot(normal, lightVector), 0.0, 1.0);
vec4 colourSample = vec4(0.0);
float colourAlpha;
vec3 colourShading = vec3(0.0);
//vec3 shading = vec3(0.0);
float shading2 = 0.0;
float diffthresh = pow(distortion, 4.0) / shadowMapResolution * tan(acos(max(NdotL, 0.0))) + pow(max(length(getFpos()), 0.0), 0.25) / shadowMapResolution;
diffthresh = mix(diffthresh, 0.001, translucent);
if(max(abs(shadowPosition.x), abs(shadowPosition.y)) < 0.99) {
if(NdotL > 0.0 || translucent > 0.9) {
shading *= 0.0;
shading2 *= 0.0;
colourShading *= 0.0;
}
int weight;
step = SHADOW_FILTER_STEP / shadowMapResolution * (1.0 + rainx * 5.0);
const vec2 shadowFilter[4] = vec2[4] (
vec2(1.0, 0.0),
vec2(-1.0, 0.0),
vec2(0.0, 1.0),
vec2(0.0, -1.0)
);
#if defined SHADOW_HQ_FILTER
const int shadowSamples = 25;
#elif defined SHADOW_LQ_FILTER
const int shadowSamples = 4;
#else
const int shadowSamples = 16;
#endif
#ifdef SHADOW_FILTER
for(int i = 0; i < shadowSamples; i++) {
#if defined SHADOW_HQ_FILTER
vec2 offset = circleOffsets[i];
#elif defined SHADOW_LQ_FILTER
vec2 offset = shadowFilter[i];
#else
vec2 offset = conservativeOffsets[i];
#endif
shading += shadow2D(shadowtex0, vec3(shadowPosition.xy + offset * step, shadowPosition.z - diffthresh)).z;
shading2 += shadow2D(shadowtex1, vec3(shadowPosition.xy + offset * step, shadowPosition.z - diffthresh)).z;
colourSample += shadow2D(shadowcolor, vec3(shadowPosition.xy + offset * step, shadowPosition.z - diffthresh)).rgba;
weight++;
}
colourSample /= weight;
shading /= weight;
shading2 /= weight;
colourShading = colourSample.rgb;
colourAlpha = colourSample.a;
#else
shading = shadow2D(shadowtex0, vec3(shadowPosition.xy, shadowPosition.z - diffthresh)).z;
shading2 += shadow2D(shadowtex1, vec3(shadowPosition.xy, shadowPosition.z - diffthresh)).z;
colourSample += shadow2D(shadowcolor, vec3(shadowPosition.xy, shadowPosition.z - diffthresh)).rgba;
colourShading = colourSample.rgb;
colourAlpha = colourSample.a;
#endif
shading = clamp(shading, 0.0, 1.0);
shading2 = clamp(shading2, 0.0, 1.0);
colourShading = clamp(colourShading * 1.4, 0.0, 1.0);
solidshading = shading;
transparentshading = shading2;
shading = ((shading-shading2)+shading2) * colourAlpha;
sampledcolour = colourShading;
colourShading *= shading2;
//shading = mix(colourShading, vec3(1.0), shading);
}
vec3 finalShading = mix(colourShading, vec3(1.0), shading);
finalShading *= mix(clamp(pow(NdotL, 1.0), 0.0, 1.0), 1.0, translucent);
return finalShading;
}
/*
vec3 pass_LightRays(vec3 bloompass, float blurStart, float blurWidth) {
vec2 pos = vec2(0.5, 0.5);
vec2 uv = texcoord.st - pos;
float distx = texcoord.x * aspectRatio - pos.x * aspectRatio;
float disty = texcoord.y - pos.y;
float decay = pow(max(1.0 - sqrt(distx * distx + disty * disty), 0.0), 1.0);
vec3 rayColour = vec3(0);
float density = 0.0;
const int center = (lightrays_Samples-1)/2;
const float sigma = 0.5;
float totalWeight = 0;
int i;
for(i = 0; i < lightrays_Samples; i++) {
float scale = blurStart + blurWidth * (i / float(lightrays_Samples));
vec2 uvpair = uv * scale + pos;
//float weight = 50 / i;
float dist = (i-float(center))/center;
float weight = exp(-(dist*dist)/(2.0*sigma));
density += ((getDepth(uvpair) / 16 < 0.7) ? pow(getDepth(uvpair), 1.1) : 1) * weight * 0.2 * (getDepth(uvpair) / 128 < 0.1 ? 1 : 0);
rayColour += (clip(vec3(0.0), vec3(1.0), bloompass)) * 16;
totalWeight += weight;
}
return (rayColour * (density / totalWeight)) / lightrays_Samples * decay * 0.3 * (getDepth(texcoord.st) < 1 ? 0 : 1);
}
*/
#ifdef GODSRAYS
float pass_GodsRays(vec2 pos) {
float sunmoonLevel = sin(sunAngle*(2*PI)); // > 0 -> day, < 0 -> night
vec2 uv = texcoord.st - pos;
float truepos = sunPosition.z/abs(sunPosition.z); // > 0 -> sun; < 0 -> moon
if(godsraysIsDay) {
// sun rays
if(truepos > 0) return 0;
} else {
// moon rays
#ifndef GODSRAYS_MOONRAYS
return 0;
#endif
if(truepos < 0) return 0;
}
float distx = texcoord.x * aspectRatio - pos.x * aspectRatio;
float disty = texcoord.y - pos.y;
float illuminationDecay = pow(max(1.0 - sqrt(distx*distx+disty*disty), 0.0), GODSRAYS_DECAYFACTOR) * GODSRAYS_DECAYMULTIPLIER;
float density = 0.0;
const int center = (GODSRAYS_SAMPLES-1)/2;
const float sigma = 0.5;
float totalWeight = 0;
int i;
const float blurStart = 1;
const float blurWidth = -1;
for(i = 0; i < GODSRAYS_SAMPLES; i++) {
float fi = float(i);
float scale = blurStart + blurWidth * (i / float(GODSRAYS_SAMPLES));
vec2 uvpair = uv * scale + pos;
float dist = ((i-float(center))/center);
float weight = exp(-(pow(dist, 2))/(2*sigma));
float newDepth = texture2D(depthtex0, uvpair).x;
density += ((depthExpToLinear(newDepth) / 128 > 0.9) ? depthExpToLinear(newDepth) : 0) * weight * GODSRAYS_MASKINTENSITY;
totalWeight += weight;
}
return (density / totalWeight / 20) * clamp(illuminationDecay, 0, 1);
}
#endif
#ifdef SSAO
float getOcclusion() {
float occlusion;
const float depthBias = 0.125;
float depth = depthExpToLinearMult(depth0, depthBias); // store the current pixel's depth
float threshold = SSAO_THRESHOLD;
float sample;
float diff;
const vec2[4] sampleOffsets = vec2[4] (
vec2(0,1),
vec2(1,0),
vec2(0,-1),
vec2(-1,0)
);
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 4; j++) {
vec2 uv = texcoord.st + (sampleOffsets[j] * (SSAO_SAMPLE_RADIUS)) + (conservativeOffsets[i] * SSAO_OFFSET_RADIUS);
float mat = texture2D(gaux3, uv).r * 255;
if(mat == MAT_WHEAT ||
mat == MAT_TALLGRASS ||
mat == MAT_ROSE ||
//mat*255.0 == MAT_VINES ||
mat == MAT_DANDELION ||
mat == MAT_LEAVES) threshold = SSAO_THRESHOLD_FOLIAGE;
sample = depthExpToLinearMult(texture2D(depthtex0, uv).x, depthBias);
diff += clamp(depth - sample, 0, 1) * (depth - sample < threshold ? 1 : 0);
}
}
diff /= 25;
//diff *= 1 - (depth / sampleDistance * 0.5);
diff *= SSAO_INTENSITY;
//diff *= 1 - depth;
return diff;
}
#endif
void main() {
fpos0 = gbufferProjectionInverse * (vec4(texcoord.st, texture2D(depthtex0, texcoord.st).x, 1.0) * 2.0 - 1.0);
fpos1 = gbufferProjectionInverse * (vec4(texcoord.st, texture2D(depthtex1, texcoord.st).x, 1.0) * 2.0 - 1.0);
vec3 nwfpos = fpos0.xyz;
fpos0 /= fpos0.w;
fpos1 /= fpos1.w;
vec3 worldpos0 = (gbufferModelViewInverse * fpos0).rgb;
vec3 worldpos1 = (gbufferModelViewInverse * fpos1).rgb;
vec3 relpos0 = worldpos0 + cameraPosition;
vec3 relpos1 = worldpos1 + cameraPosition;
vec3 b_colour = texture2D(gcolour, texcoord.st).rgb;
vec3 b_normal = texture2D(gnormal, texcoord.st).rgb;
vec4 b_depth = texture2D(gdepth, texcoord.st);
vec4 b_composite = vec4(0, texture2D(composite, texcoord.st).gba);
//vec4 b_aux1 = texture2D(gaux1, texcoord.st);
//vec4 b_aux2 = texture2D(gaux2, texcoord.st);
vec4 b_aux3 = texture2D(gaux3, texcoord.st);
//vec4 b_aux4 = texture2D(gaux4, texcoord.st);
float sland = float(b_depth.b == 0.9 || b_depth.b == 0.91);
float sland_boost = float(b_depth.b == 0.91);
float swater = float(b_depth.b > 0.04 && b_depth.b < 0.06);
float shand = float(b_depth.b == 0.3);
float sentity = float(b_depth.b == 0.4);
float stranslucent = float(b_depth.b <= 0.1);
float sice = float(b_depth.b > 0.07 && b_depth.b < 0.08);
float ssky = float(b_depth.b == 1.0);
float sweather = float(b_depth.b == 0.5);
float semissive = float(b_depth.b == 0.92);
float depth;
float shadowMask = 1.0;
depth = depthExpToLinearMult(depth0, 2);
vec3 sunmoonColor = directLight;
float sunmoonIntensity;
// extracting lighting data from the lightmap
float blockLightIntensity = b_depth.g;
float skyLightIntensity = b_depth.r;
vec3 blockLight = lightBlockColour * (pow(blockLightIntensity * LIGHTING_BLOCK_MULTIPLIER, LIGHTING_BLOCK_ATTENUATION) * LIGHTING_BLOCK_INTENSITY);
#ifdef LIGHTING_BLOCK_RAIN_EFFECT
blockLight = mix(blockLight, lightBlockColour * (pow(blockLightIntensity * LIGHTING_BLOCK_MULTIPLIER_RAIN, LIGHTING_BLOCK_ATTENUATION_RAIN) * LIGHTING_BLOCK_INTENSITY_RAIN), rainStrength);
#endif
vec3 skyLight = desaturate(ambientLight, 0.4) * skyLightIntensity;
vec3 ambient = blockLight + skyLight;
if(ssky > 0.0 || (isEyeInWater == 1 && swater > 0.0)) {
if(isEyeInWater == 0) b_colour.rgb = getSkyColor(nwfpos, worldTime / 1000.0f, false);
b_colour.rgb = drawSun(nwfpos, b_colour.rgb, float(b_depth.b == 1.0), false);
}
ambient *= mix(1.0, LIGHTING_FOLIAGE_BOOST, sland_boost);
if(shand > 0.0) {
b_colour = b_colour * ambient;
}
vec4 comp = vec4(0.0, 0.0, 0.0, 1.0);
if(sland > 0.0 || stranslucent > 0.0 || sentity > 0.0 || sweather > 0.0 || semissive > 0.0) {
if(normal == vec3(0.0) || normal == vec3(-1.0)) {
comp = vec4(b_colour * ambient, 1.0);
} else {
float deltaZ = 1.0;
#ifdef WATER_CAUSTICS
if((isEyeInWater == 0 && swater > 0.0) || (isEyeInWater == 1 && swater < 1.0)) {
vec3 posxz = relpos1.xyz;
vec3 noiseSample = getNoise2(posxz.xz / 1024.0, vec2(frameTimeCounter * 0.7), 64.0);
float causticNoise = noiseSample.x * noiseSample.y * noiseSample.z;
float time = mix(0.0, frameTimeCounter * WATER_RIPPLE_SPEED, min(swater + float(isEyeInWater), 1.0));
//float time = swater > 0.0 ? frameTimeCounter * WATER_RIPPLE_SPEED : 0.0;
float intensity = mix(0.0, WATER_RIPPLE_INTENSITY, min(swater + float(isEyeInWater), 1.0));
const float causticNoiseCurve = 1.02;
float f1 = mix(0.0, WATER_RIPPLE_CURVE_FACTOR + (causticNoise * causticNoiseCurve), min(swater + float(isEyeInWater), 1.0));
posxz.x += sin(posxz.z*2.0+time)*f1;
posxz.z += cos(posxz.x*1.0+time*0.5)*f1;
posxz.xz += sin(posxz.y);
//posxz *= swater > 0.0 ? 1.7 : 2.1; // distortion size
posxz *= mix(0.0, WATER_RIPPLE_SIZE, min(swater + float(isEyeInWater), 1.0));
float deltaPos = mix(0.0, 0.2, min(swater + float(isEyeInWater), 1.0));
float h0 = waterH(posxz, swater + float(isEyeInWater == 1.0), time) * intensity;
float h1 = waterH(posxz + vec3(deltaPos,0.0,0.0), swater + float(isEyeInWater == 1.0), time) * intensity;
float h2 = waterH(posxz + vec3(-deltaPos,0.0,0.0), swater + float(isEyeInWater == 1.0), time) * intensity;
float h3 = waterH(posxz + vec3(0.0,0.0,deltaPos), swater + float(isEyeInWater == 1.0), time) * intensity;
float h4 = waterH(posxz + vec3(0.0,0.0,-deltaPos), swater + float(isEyeInWater == 1.0), time) * intensity;
deltaZ = h3/deltaPos;
deltaZ = min(max(deltaZ, -4.0), 4.0);
}
#endif
float sshading;
float ssolid;
float stransparent;
vec3 scolour;
vec3 sfpos;
vec3 sfinal = getShadowShading(sshading, ssolid, stransparent, scolour, sfpos, stranslucent);
vec3 specularColor = faux1.rgb;
sfinal = mix(sfinal, sfinal * 0.1, rainStrength);
sshading = mix(sshading, sshading * 0.1, rainStrength);
normal = normalize(normal);
float s = max(dot(reflect(sfpos, normal), lightVector), 0.0);
comp = vec4(min(b_colour * ((ambient) + max(dot(normal, lightVector),0.0) * sunmoonColor * (sshading * 1.0)) + specularColor * s * s * s * sunmoonColor * sshading, 1), 1);
vec3 shading;
shading = (b_colour * sfinal * sunmoonColor * mix(1.0, mix(1.0, 0.86, deltaZ), swater)) + (b_colour * ambient);
shading *= mix(1.0, 0.52, swater);
comp = vec4(min(shading, 1), 1);
//comp.rgb = scolour;
//shadowMask = stransparent;
}
vec3 weather = faux2.rgb * ambient;
comp.rgb = mix(comp.rgb, weather, faux2.a);
b_colour = comp.rgb;
}
#ifdef GODSRAYS
vec4 tpos = vec4(sunPosition, 1.0) * gbufferProjection;
tpos.xyz /= tpos.w;
vec2 lpos = tpos.xy/tpos.z;
vec2 lightPos = lpos*0.5+0.5;
b_composite.r += pass_GodsRays(lightPos) * (1 - rainStrength * 0.8);
#endif
#ifdef SSAO
b_composite.g = getOcclusion();
#endif
#ifdef VOLUMETRIC_LIGHT
b_composite.b = getVolumetricRays() * 20;
#endif
gl_FragData[0] = vec4(b_colour, shadowMask);
gl_FragData[1] = b_depth;
gl_FragData[2] = vec4(b_normal, 1.0);
gl_FragData[3] = b_composite;
//gl_FragData[4] = b_aux1;
//gl_FragData[5] = b_aux2;
//gl_FragData[6] = b_aux3;
//gl_FragData[7] = b_aux4;
// visualise shadows
#if 0
if (texcoord.s < 0.18)
{
if (texcoord.t < 0.32)
{
/*
gl_FragData[0] = vec4(
texcoord.t*(1.0/0.32),
texture2D(shadow, texcoord.st*vec2(1.0/0.18,1.0/0.32)).r,
texture2D(watershadow,texcoord.st*vec2(1.0/0.18,1.0/0.32)).r,
1.0);
*/
gl_FragData[0] = vec4(texture2D(shadow, texcoord.st*vec2(1.0/0.18,1.0/0.32)).r);
}
else if (texcoord.t < 0.64)
{
//gl_FragData[0] = texture2D(shadowcolor,(texcoord.st-vec2(0.0,0.32))*vec2(1.0/0.18,1.0/0.32));
gl_FragData[0] = vec4(texture2D(watershadow, (texcoord.st-vec2(0.0,0.32))*vec2(1.0/0.18,1.0/0.32)).r);
}
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment