Skip to content

Instantly share code, notes, and snippets.

@jcm2606
Created January 13, 2017 15:44
Show Gist options
  • Save jcm2606/1139d64d88b1bb98348c7b6c91655b21 to your computer and use it in GitHub Desktop.
Save jcm2606/1139d64d88b1bb98348c7b6c91655b21 to your computer and use it in GitHub Desktop.
/*
Clarity Shader Pack for Minecraft. Written by jcm2606, credit to Chocapic13, Robobo1221 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".
*/
// INITIALISATION
#version 120
#include "/lib/arch/Pipeline.glsl"
#define STAGE COMPOSITE
#include "/lib/utility/Syntax.glsl"
#include "/lib/segment/Constant.glsl"
#include "/lib/segment/BufferFormat.glsl"
#include "/lib/Global.glsl"
#include "/lib/utility/Materials.glsl"
// SAMPLERS
#define USE_GCOLOUR
#define USE_GNORMAL
#define USE_GDEPTH
#define USE_GCOMPOSITE
#define USE_GAUX1
#define USE_GAUX2
#include "/lib/utility/Samplers.glsl"
uniform sampler2D depthtex0;
uniform sampler2D depthtex1;
uniform sampler2DShadow shadow;
uniform sampler2DShadow watershadow;
uniform sampler2DShadow shadowcolor;
// UNIFORM FIELDS
uniform mat4 gbufferProjectionInverse;
uniform mat4 gbufferProjection;
uniform mat4 gbufferModelViewInverse;
uniform mat4 gbufferModelView;
uniform mat4 shadowModelView;
uniform mat4 shadowProjection;
uniform int isEyeInWater;
uniform float rainStrength;
uniform float sunAngle;
uniform float near;
uniform float far;
uniform float viewWidth;
uniform float viewHeight;
uniform float frameTimeCounter;
uniform ivec2 eyeBrightnessSmooth;
uniform vec3 cameraPosition;
// VARYING FIELDS
varying vec2 texcoord;
varying vec3 lightVector;
varying vec3 sunVector;
varying vec3 moonVector;
varying vec3 upVector;
// STRUCTS
#include "/lib/struct/StructFragment.glsl"
#include "/lib/struct/StructShading.glsl"
#include "/lib/struct/StructPosition.glsl"
#include "/lib/struct/StructMaterial.glsl"
Fragment fragment;
SurfaceShading directShading;
Position position;
Material material;
// ARBITRARY FIELDS
RAIN_SCALAR;
vec3 directLight;
vec3 ambientLight;
vec3 dlSunlight;
vec3 dlMoonlight;
// FUNCTIONS
#include "/lib/feature/Shadow.glsl"
#include "/lib/utility/Colour.glsl"
#include "/lib/utility/Tonemap.glsl"
#include "/lib/utility/Worldtime.glsl"
#include "/lib/utility/Noise.glsl"
#include "/lib/feature/Lighting.glsl"
#include "/lib/feature/Sky.glsl"
#include "/lib/utility/LightingFunctions.glsl"
#include "/lib/feature/Textures.glsl"
#include "/lib/feature/Fog.glsl"
#include "/lib/feature/VolumetricLight.glsl"
#include "/lib/utility/Depth.glsl"
#include "/lib/feature/Reflection.glsl"
float getShadowBiasDistort(in vec4 worldpos) {
vec2 pos = abs(worldpos.xy * 1.165);
return (1.0 - SHADOW_BIAS) + (pow(pow(pos.x, 8.0) + pow(pos.y, 8.0), 1.0 / 8.0)) * SHADOW_BIAS;
}
vec4 biasShadowPosition(in vec4 worldpos) {
worldpos.xy /= getShadowBiasDistort(worldpos) * 0.97;
worldpos = worldpos * vec4(0.5, 0.5, 0.2, 0.5) + vec4(0.5);
return worldpos;
}
void distortShadowSpace(inout vec2 worldSpacePosition) {
worldSpacePosition = worldSpacePosition * 2.0 - 1.0;
worldSpacePosition /= (1.0 - SHADOW_BIAS) + fLength(worldSpacePosition) * SHADOW_BIAS;
worldSpacePosition = worldSpacePosition * 0.5 + 0.5;
}
vec4 getShadowWorldPos(in float shadowdepth, in vec2 texcoord){
vec4 sworldposition = gbufferModelViewInverse * getFragPosition(texcoord.st, shadowdepth, true);
sworldposition = shadowModelView * sworldposition;
sworldposition = shadowProjection * sworldposition;
sworldposition /= sworldposition.w;
return sworldposition * 0.5 + 0.5;
}
void calculateShading(in float translucent) {
mat2x4 shadowPositionMatrix;
#define shadowPosition shadowPositionMatrix[0]
#define shadowPositionSolid shadowPositionMatrix[1]
shadowPosition = getShadowWorldPos(position.depthTransparent, texcoord.st);
shadowPositionSolid = getShadowWorldPos(position.depthSolid, texcoord.st);
distortShadowSpace(shadowPosition.st);
distortShadowSpace(shadowPositionSolid.st);
mat3x4 shadingMatrix;
#define NdotL shadingMatrix[2].y
#define diffthresh 0.0005
#define shadowStep shadingMatrix[2].x
#define sampleColour shadingMatrix[1]
#define sampleSolid shadingMatrix[0].x
#define sampleTransparent shadingMatrix[0].y
#define sampleSurface shadingMatrix[0].z
#define sampleDifference shadingMatrix[0].w
#define shadingFinal shadingMatrix[1].a
NdotL = clamp(dot(fragment.normal.xyz * 2.0 - 1.0, lightVector), 0.0, 1.0);
const vec2 shadowFilter[16] = vec2[16] (
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)
);
int weight;
shadowPosition.z -= diffthresh;
shadowPositionSolid.z -= diffthresh;
if(max(abs(shadowPosition.x), abs(shadowPosition.y)) < 0.99) {
shadowStep = SHADOW_FILTER_STEP / shadowMapResolution;
#ifdef SHADOW_FILTER
#ifdef SHADOW_LQ_FILTER
for(int i = 0; i < 4; i++) {
#else
#ifdef SHADOW_HQ_FILTER
for(int i = 0; i < 16; i++) {
#else
for(int i = 0; i < 8; i++) {
#endif
#endif
sampleColour += shadow2D(shadowcolor, vec3(shadowPosition.st + shadowFilter[i] * shadowStep, shadowPosition.z));
sampleSolid += shadow2D(shadow, vec3(shadowPosition.st + shadowFilter[i] * shadowStep, shadowPosition.z)).r;
sampleTransparent += shadow2D(watershadow, vec3(shadowPosition.st + shadowFilter[i] * shadowStep, shadowPosition.z)).x;
sampleSurface += shadow2D(shadow, vec3(shadowPositionSolid.st + shadowFilter[i] * shadowStep, shadowPositionSolid.z)).x;
weight++;
}
sampleColour /= weight;
sampleSolid /= weight;
sampleTransparent /= weight;
sampleSurface /= weight;
#else
sampleColour = shadow2D(shadowcolor, vec3(shadowPosition.st, shadowPosition.z));
sampleSolid = shadow2D(shadow, vec3(shadowPosition.st, shadowPosition.z)).x;
sampleTransparent = shadow2D(watershadow, vec3(shadowPosition.st, shadowPosition.z)).x;
sampleSurface = shadow2D(shadow, vec3(shadowPositionSolid.st, shadowPositionSolid.z)).x;
#endif
}
sampleDifference = (sampleSolid - sampleTransparent);
shadingFinal = mix(sampleSolid, 1.0, sampleTransparent) * mix(clamp(NdotL, 0.0, 1.0), 1.0, min(1.0, translucent + material.foliage));
#ifdef LOCAL_SUBSURFACE_SCATTERING
if(material.foliage > 0.5) shadingFinal *= 1.0 + mix(0.0, 2.0, max(0.0, pow(dot(normalize(position.fragPositionSolid.xyz), lightVector), 16.0)));
#endif
directShading.final = sampleColour;
directShading.shading = vec4(sampleDifference, sampleSurface, 0.0, 0.0);
fragment.colour.a = directShading.shading.g;
#undef shadowPosition
#undef shadowPositionSolid
#undef NdotL
#undef diffthresh
#undef shadowStep
#undef sampleColour
#undef sampleSolid
#undef sampleTransparent
#undef sampleSurface
#undef sampleDifference
#undef shadingFinal
}
vec3 calculateLitShading(in vec3 colour) {
mat2x3 lightMatrix;
#define direct lightMatrix[0]
#define ambient lightMatrix[1]
direct = colour.rgb * (directLight * mix(vec3(1.0), directShading.finalShading_colour * SHADOW_TRANSLUCENCY_COLOUR_STRENGTH, directShading.finalShading_differenceMask));
ambient = colour.rgb * ambientLight * pow(fragment.skyLight, AL_SPREAD) * (isEyeInWater == 1 ? pow(fragment.skyLight, 3.0) : (material.water > 0.5 ? 0.5 : 1.0));
return mix(ambient, direct * (isEyeInWater == 1 ? max(DL_WATER_MINIMUM, pow(fragment.skyLight, DL_WATER_FALLOFF)) : 1.0), directShading.finalShading_shading) + colour.rgb * colourSaturate(BL_COLOUR, BL_SATURATION) * getBlockLight(fragment.blockLight);
#undef direct
#undef ambient
}
vec3 calculateBaseShading(in vec3 colour) {
vec3 ambient = colour.rgb * ambientLight * pow(fragment.skyLight, AL_SPREAD) * (isEyeInWater == 1 ? pow(fragment.skyLight, 3.0) : (material.water > 0.5 ? 0.5 : 1.0));
return ambient + colour.rgb * colourSaturate(BL_COLOUR, BL_SATURATION) * pow(fragment.blockLight * BL_STRENGTH, BL_ATTENUATION);
}
vec3 drawDepthFog(in vec3 colour, in float brightness, in float height) {
vec4 upos = gbufferProjectionInverse * vec4(vec3(texcoord.st, position.depthTransparent) * 2.0 - 1.0, 1.0);
upos /= upos.w;
vec3 uvec = position.fragPositionSolid.xyz - upos.xyz;
upos.w = sqrt(dot(uvec, uvec)) * abs(dot(normalize(uvec), fragment.normal.xyz * 2.0 - 1.0));
upos.w = 1-clamp(exp(-upos.w / height), 0.0, 1.0);
return mix(fragment.colour.rgb, colour * brightness * fragment.skyLight, upos.w);
}
float puddle(vec2 position, vec2 wind) {
vec2 dcVector = vec2(0.0); // density, cl
#define density dcVector.x
#define cl dcVector.y
density = generate2DNoise(position - wind * 0.25);
density += generate2DNoise(position * 3.5 - wind * 0.25) / 3.5;
density += generate2DNoise(position * 6.125 - wind * 0.25) / 6.125;
density += generate2DNoise(position * 12.25 - wind * 0.25) / 12.25;
density += generate2DNoise(position * 24.50 - wind * 0.25) / 24.50;
density += generate2DNoise(position * 49.0 - wind * 0.25) / 49.0;
density /= 0.13;
cl = max(density - 0.9, 0.0);
cl = max(cl, 0.0) * 0.05;
density = pow(max(1.0 - cl * 2.5, 0.0), 2.0) / 11.0 / 3.0;
density *= 20.0;
//density -= 0.1;
density = max(0.0, density);
density = mix(density, 0.0, pow(1.0 - density, 100.0));
return density * 3.0;
#undef density
#undef cl
}
float generatePuddles() {
vec3 worldpos = getWorldPosition(position.fragPositionSolid, true) + cameraPosition;
float puddle = puddle(worldpos.xz / REFLECTION_PUDDLE_SIZE, vec2(0.0));
return puddle;
}
#ifdef VOLUMETRIC_LIGHT
float distx(in 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(out vec4 sampledColour) {
///////////////////////Setting up functions///////////////////////
mat3x4 matrix0;
#define rSD matrix0[0]
#define worldposition matrix0[1]
#define colour matrix0[2]
rSD.x;
rSD.y = 6.0 / VL_QUALITY;
rSD.z = find_closest(texcoord.st);
rSD.z *= rSD.y;
mat2 matrix1;
#define minDist matrix1[0].x
#define weight matrix1[0].y
const float maxDist = (VL_DISTANCE);
minDist = (0.001);
minDist += rSD.z;
weight = (maxDist / rSD.y);
colour = vec4(vec3(0.25), 0.0);
bool colsample = false;
#define solidShadow matrix1[1].x
#define transparentShadow matrix1[1].y
for (minDist; minDist < maxDist;) {
if (linearDepth(position.depthTransparent) < minDist) break; // VL wall fix
worldposition = getShadowWorldPos(distx(minDist),texcoord.st);
distortShadowSpace(worldposition.st);
solidShadow = shadow2D(watershadow, worldposition.rgb).x;
#ifdef VL_TRANSPARENCY
transparentShadow = shadow2D(shadow, worldposition.rgb).x - solidShadow;
#ifdef VL_ADVANCED
if(transparentShadow > 0.0 && !colsample) colour = shadow2D(shadowcolor, worldposition.rgb);
if(transparentShadow > 0.0 && !colsample && isEyeInWater == 1) transparentShadow *= colour.a;
if(transparentShadow > 0.0 && !colsample) colsample = true;
#endif
solidShadow += transparentShadow;
#endif
rSD.x += solidShadow;
minDist = minDist + rSD.y;
}
#undef solidShadow
#undef transparentShadow
rSD.x /= weight;
rSD.x *= 0.15 * maxDist / 32;
#undef minDist
#undef weight
rSD.x = mix(rSD.x, clamp(rSD.x, 0.0, 0.1), dynamicExposure());
sampledColour = colour;
return rSD.x;
#undef rSD
#undef worldposition
#undef colour
}
#else
float getVolumetricRays(out vec4 sampledColour){
return 0.0;
}
#endif
float exponentialFog(float dist, float density) {
const float LOG2 = -1.442695;
float d = density * dist;
return 1.0 - clamp(exp2(d * d * LOG2), 0.0, 1.0);
}
void doUnderwaterFog(inout vec3 colour) {
float fog = exponentialFog(linearDepth(position.depthSolid) / UNDERWATER_FOG_DISTANCE, UNDERWATER_FOG_DENSITY);
colour = mix(colour, waterColour * UNDERWATER_FOG_BRIGHTNESS, fog);
}
void main() {
#if defined DEBUG_COMPARISON
#if DEBUG_COMPARISON_SHADER == -2 || DEBUG_COMPARISON_SHADER == STAGE
if(texcoord.x <= 0.5) gl_FragData[0] = texture2D(GCOLOUR, texcoord.xy);
if(texcoord.x <= 0.5) return;
#endif
#endif
// POPULATE STRUCTS
createFragment(fragment, texcoord.xy);
createPosition(position, texcoord.xy);
createMaterial(material, fragment);
createFragmentPosition(position, texcoord.xy, true, true);
if(material.water > 0.5) fragment.composite = vec4(0.08, 0.0, 0.0, 1.0);
if(material.translucent > 0.5) fragment.composite = vec4(0.2, 0.0, 0.0, 1.0);
// PERFORM GAMMA CORRECTION
fragment.aux1.rgb = gamma2linear(fragment.aux1.rgb);
fragment.aux2.rgb = gamma2linear(fragment.aux2.rgb);
// VARIABLES
float skyMask = SKY_MASK;
fragment.colour.a = fragment.aux1.a;
mat2x3 colour; // [0] bufferSolid, [1] bufferTransparent
colour[0] /* bufferSolid */ = fragment.aux1.rgb;
colour[1] /* bufferTransparent */ = fragment.aux2.rgb;
// CALCULATE SHADING
if(material.sky < 0.5) calculateShading(0.0);
// CALCULATE COLOUR OF DIRECT LIGHT
calculateDirectLightColour();
// DRAW THE SKY
if(1.0 - skyMask > 0.5 && material.hand < 0.5) colour[0] = drawSky(position.fragPositionTransparent, false);
// CALCULATE THE COLOUR OF AMBIENT LIGHT
if(material.sky < 0.5) calculateAmbientLightColour();
// PERFORM SHADING ON THE SOLID BUFFER
if(skyMask > 0.5) colour[0] /* bufferSolid */ = calculateLitShading(colour[0] /* bufferSolid */);
//if(material.weather > 0.5) colour[0] /* bufferSolid */ = calculateBaseShading(colour[0] /* bufferSolid */);
// TINT THE SOLID BUFFER BEFORE SHADING THE TRANSPARENT BUFFER
if(material.weather < 0.5 && any(greaterThan(colour[1] /* bufferTransparent */, vec3(0.0)))) colour[0] /* bufferSolid */ *= colour[1] /* bufferTransparent */ * TRANSPARENCY_TINT_STRENGTH;
// PERFORM SHADING ON THE TRANSPARENT BUFFER
colour[1] /* bufferTransparent */ = calculateBaseShading(colour[1] /* bufferTransparent */);
// COMBINE BUFFERS
fragment.colour.rgb = mix(colour[0], colour[1], fragment.aux2.a);
// DRAW DEPTH FOG
#ifdef DEPTH_FOG
if(isEyeInWater == 0 && material.water > 0.5) fragment.colour.rgb = drawDepthFog(waterColour, 0.05 * (DEPTH_FOG_WATER_BRIGHTNESS_HORIZON * HorizonAmb + DEPTH_FOG_WATER_BRIGHTNESS_NOON * Noon + DEPTH_FOG_WATER_BRIGHTNESS_MIDNIGHT * MidnightAmb), DEPTH_FOG_WATER_HEIGHT);
if(isEyeInWater == 0 && material.ice > 0.5) fragment.colour.rgb = drawDepthFog(iceColour, 0.03 * (DEPTH_FOG_ICE_BRIGHTNESS_HORIZON * HorizonAmb + DEPTH_FOG_ICE_BRIGHTNESS_NOON * Noon + DEPTH_FOG_ICE_BRIGHTNESS_MIDNIGHT * MidnightAmb), DEPTH_FOG_ICE_HEIGHT);
#endif
// CALCULATE VOLUMETRIC LIGHT SAMPLES
#ifdef VOLUMETRIC_LIGHT
vec4 vlColour = vec4(0.0);
fragment.aux3.a = getVolumetricRays(vlColour);
fragment.aux3.rgb = vlColour.rgb;
#endif
#ifdef UNDERWATER_FOG
if(isEyeInWater == 1) doUnderwaterFog(fragment.colour.rgb);
#endif
if(material.solid > 0.5) fragment.aux1.a = generatePuddles();
// POPULATE OUTGOING BUFFERS
/* DRAWBUFFERS:0 */
gl_FragData[0] = fragment.colour;
gl_FragData[1] = fragment.normal;
gl_FragData[2] = fragment.depth;
gl_FragData[3] = fragment.composite;
gl_FragData[4] = fragment.aux1;
gl_FragData[6] = fragment.aux3;
}
@zoroie
Copy link

zoroie commented Sep 2, 2022

ddn

@zoroie
Copy link

zoroie commented Sep 2, 2022

ddn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment