Загрузка данных
#version 120
/* DRAWBUFFERS:02 */ //0=gcolor, 2=gnormal for normals
/*
Sildur's enhanced default, before editing, remember the agreement you've accepted by downloading this shaderpack:
http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1291396-1-6-4-1-12-1-sildurs-shaders-pc-mac-intel
You are allowed to:
- Modify it for your own personal use only, so don't share it online.
You are not allowed to:
- Rename and/or modify this shaderpack and upload it with your own name on it.
- Provide mirrors by reuploading my shaderpack, if you want to link it, use the link to my thread found above.
- Copy and paste code or even whole files into your "own" shaderpack.
*/
/*---------------------------
/////ADJUSTABLE VARIABLES/////
----------------------------*/
//#define Celshading //Cel shades everything, making it look somewhat like Borderlands.
#define Reflections //Toggle reflections, also adjust in gbuffers_textured.fsh
#define Refl_Quality 1 //[1 2] 1=fast 2=fancy
//#define Godrays //Toggle godrays
#define grays_quality 1 //[1 2] 1=fast 2=fancy
#define grays_intensity 0.65 //Adjust godrays intensity [0.35 0.5 0.65 0.70 0.85 1.0]
//Debugging stuff
//#define depthbuffer //Draw depth buffer
//#define draw_refnormals //Draw reflection normals, actually composite normals but only reflections are stored in the buffer.
/*---------------------------
//END OF ADJUSTABLE VARIABLES//
----------------------------*/
varying vec2 texcoord;
varying vec4 color;
uniform vec3 shadowLightPosition;
uniform mat4 gbufferProjectionInverse;
uniform sampler2D texture;
uniform sampler2D gnormal; //used by reflections and celshading
uniform sampler2D depthtex0;
uniform sampler2D depthtex1;
uniform float viewWidth;
uniform float viewHeight;
uniform float near;
uniform float far;
uniform int isEyeInWater;
// ========== ДОБАВЛЕНО ДЛЯ УПРАВЛЕНИЯ ТЕНЯМИ ==========
uniform float shadowDistance;
// =====================================================
float cdist(vec2 coord) {
return clamp(1.0 - max(abs(coord.s-0.5),abs(coord.t-0.5))*2.0, 0.0, 1.0);
}
vec3 screenSpace(vec2 coord, float depth){
vec4 pos = gbufferProjectionInverse * (vec4(coord, depth, 1.0) * 2.0 - 1.0);
return pos.xyz/pos.w;
}
#ifdef Reflections
uniform mat4 gbufferProjection;
vec3 nvec3(vec4 pos) {
return pos.xyz/pos.w;
}
vec4 raytrace(vec4 color, vec3 normal) {
vec3 fragpos0 = screenSpace(texcoord.xy, texture2D(depthtex0, texcoord.xy).x);
vec3 rvector = reflect(fragpos0.xyz, normal.xyz);
rvector = normalize(rvector);
vec3 start = fragpos0 + rvector;
vec3 tvector = rvector;
int sr = 0;
#if Refl_Quality == 1 //fast
const int maxf = 3; //number of refinements
const float ref = 0.2; //refinement multiplier
const int rsteps = 15;
#elif Refl_Quality == 2 //fancy
const int maxf = 6;
const float ref = 0.07;
const int rsteps = 25;
#endif
const float inc = 2.2; //increasement factor at each step
for(int i=0;i<rsteps;i++){
vec3 pos = nvec3(gbufferProjection * vec4(start, 1.0)) * 0.5 + 0.5;
if(pos.x < 0 || pos.x > 1 || pos.y < 0 || pos.y > 1 || pos.z < 0 || pos.z > 1.0) break;
vec3 fragpos1 = screenSpace(pos.xy, texture2D(depthtex1, pos.st).x);
float err = distance(start, fragpos1);
if(err < pow(length(rvector),1.35)){
sr++;
if(sr >= maxf){
color = texture2D(texture, pos.st);
color.a = cdist(pos.st);
break;
}
tvector -= rvector;
rvector *= ref;
}
rvector *= inc;
tvector += rvector;
start = fragpos0 + tvector;
}
return color;
}/*--------------------------------------*/
#endif
#ifdef Celshading
float pw = 1.0/ viewWidth;
float ph = 1.0/ viewHeight;
float getdepth(vec2 coord) {
return texture2D(depthtex1,coord).x;
}
vec3 celshade(vec3 c) {
//edge detect
float dtresh = 1/(far-near)* 0.0005;
vec4 dc = vec4(getdepth(texcoord.xy));
vec4 sa = vec4(getdepth(texcoord.xy + vec2(-pw,-ph)),
getdepth(texcoord.xy + vec2(pw,-ph)),
getdepth(texcoord.xy + vec2(-pw,0.0)),
getdepth(texcoord.xy + vec2(0.0,ph)));
//opposite side samples
vec4 sb = vec4(getdepth(texcoord.xy + vec2(pw,ph)),
getdepth(texcoord.xy + vec2(-pw,ph)),
getdepth(texcoord.xy + vec2(pw,0.0)),
getdepth(texcoord.xy + vec2(0.0,-ph)));
vec4 dd = abs(2.0* dc - sa - sb) - dtresh;
dd = step(dd.xyzw, vec4(0.0));
float e = clamp(dot(dd,vec4(0.25f)),0.0,1.0);
return c*e;
}
#endif
#ifdef Godrays
varying vec2 lightPos;
float land = 1.0-near/far/far;
float getnoise(vec2 pos) {
return fract(sin(dot(pos ,vec2(18.9898f,28.633f))) * 4378.5453f);
}
vec3 calcRays(vec3 color){
vec2 deltatexcoord = vec2(lightPos - texcoord) * 0.04;
#if grays_quality == 1
vec2 noisetc = texcoord; //fast unfiltered
#elif grays_quality == 2
vec2 noisetc = texcoord + deltatexcoord*getnoise(texcoord); //slow filtered
#endif
float gr = 1.0;
for (int i = 0; i < 20; i++) {
float depth0 = texture2D(depthtex0, noisetc).x;
noisetc += deltatexcoord;
gr += dot(step(land, depth0), 1.0)*cdist(noisetc);
}
gr /= 20.0;
vec3 gfragpos0 = screenSpace(texcoord.xy, texture2D(depthtex0, texcoord.xy).x);
float lightpos = clamp(dot(normalize(gfragpos0.xyz), normalize(shadowLightPosition.xyz)), 0.0, 1.0)*gr*grays_intensity;
return color *= 1.0+lightpos*color * (1.0 - isEyeInWater);
}
#endif
void main() {
// ========== ПРИНУДИТЕЛЬНАЯ УСТАНОВКА ДАЛЬНОСТИ ТЕНЕЙ ==========
// Теперь тени рисуются на 512 блоков (32 чанка) вместо 96
shadowDistance = 512.0;
// ==============================================================
vec4 tex = texture2D(texture, texcoord.xy)*color;
vec4 normal = texture2D(gnormal, texcoord.xy) * 2.0 - 1.0; //vec3 for normals, alpha for is reflective
#ifdef Celshading
if(normal.a < 1.0 && isEyeInWater < 0.9)tex.rgb = celshade(tex.rgb);
#endif
#ifdef Reflections
if(normal.a > 0.99 && isEyeInWater < 0.9){
vec4 reflection = raytrace(tex, normal.xyz);
tex.rgb = mix(tex.rgb, reflection.rgb, tex.a*reflection.a);
}
#endif
#ifdef Godrays
tex.rgb = calcRays(tex.rgb);
#endif
#ifdef depthbuffer
float nearplane = 1.0;
float farplane = 1024.0;
float c = (2.0 * nearplane) / (farplane + nearplane - texture2D(depthtex0, texcoord.xy).z * (farplane - nearplane)); //convert to linear values
tex.rgb = vec3(c);
#endif
#ifdef draw_refnormals
tex.rgb = normal.rgb;
#endif
gl_FragData[0] = tex;
gl_FragData[1] = vec4(0.0); //improves performance
}