Загрузка данных


#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
}