+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
@@ -20,7 +35,7 @@
-
+
@@ -28,7 +43,7 @@
-
+
@@ -36,7 +51,7 @@
-
+
@@ -44,20 +59,28 @@
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
diff --git a/data/gui/options_video.stkgui b/data/gui/options_video.stkgui
index c90eb4851..9f679add6 100644
--- a/data/gui/options_video.stkgui
+++ b/data/gui/options_video.stkgui
@@ -40,16 +40,6 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/data/shaders/MLAA_COPYING b/data/shaders/MLAA_COPYING
new file mode 100644
index 000000000..cb39bd220
--- /dev/null
+++ b/data/shaders/MLAA_COPYING
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2010 Jorge Jimenez (jorge@iryoku.com)
+ * Copyright (C) 2010 Belen Masia (bmasia@unizar.es)
+ * Copyright (C) 2010 Jose I. Echevarria (joseignacioechevarria@gmail.com)
+ * Copyright (C) 2010 Fernando Navarro (fernandn@microsoft.com)
+ * Copyright (C) 2010 Diego Gutierrez (diegog@unizar.es)
+ * Copyright (C) 2011 Lauri Kasanen (cand@gmx.com)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the following statement:
+ *
+ * "Uses Jimenez's MLAA. Copyright (C) 2010 by Jorge Jimenez, Belen Masia,
+ * Jose I. Echevarria, Fernando Navarro and Diego Gutierrez."
+ *
+ * Only for use in the Mesa project, this point 2 is filled by naming the
+ * technique Jimenez's MLAA in the Mesa config options.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the copyright holders.
+ */
diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag
new file mode 100644
index 000000000..f00f76c1e
--- /dev/null
+++ b/data/shaders/bloom.frag
@@ -0,0 +1,13 @@
+uniform sampler2D tex;
+uniform float low;
+
+void main()
+{
+ vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709
+ vec3 col = texture2D(tex, gl_TexCoord[0].xy).xyz;
+ float luma = dot(weights, col);
+
+ col *= smoothstep(low, 0.9, luma);
+
+ gl_FragColor = vec4(col, 1.0);
+}
diff --git a/data/shaders/bloomblend.frag b/data/shaders/bloomblend.frag
new file mode 100644
index 000000000..6cb0ec93d
--- /dev/null
+++ b/data/shaders/bloomblend.frag
@@ -0,0 +1,10 @@
+uniform sampler2D tex;
+
+void main()
+{
+ vec4 col = texture2D(tex, gl_TexCoord[0].xy);
+
+ col.xyz *= 10.0 * col.a;
+
+ gl_FragColor = vec4(col.xyz, 1.0);
+}
diff --git a/data/shaders/bloompower.frag b/data/shaders/bloompower.frag
new file mode 100644
index 000000000..441090cb6
--- /dev/null
+++ b/data/shaders/bloompower.frag
@@ -0,0 +1,11 @@
+uniform float power;
+uniform sampler2D tex;
+
+void main()
+{
+ vec4 col = texture2D(tex, gl_TexCoord[0].xy);
+ if (col.a < 0.5)
+ discard;
+
+ gl_FragColor = vec4(col.xyz, power);
+}
diff --git a/data/shaders/bubble.frag b/data/shaders/bubble.frag
index 9fc686210..6e900c98e 100644
--- a/data/shaders/bubble.frag
+++ b/data/shaders/bubble.frag
@@ -15,13 +15,12 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-uniform sampler2D main_texture;
+uniform sampler2D tex;
uniform float transparency;
varying vec2 uv;
void main()
{
- gl_FragColor = texture2D(main_texture, uv);
- gl_FragColor.a *= transparency;
+ gl_FragColor = texture2D(tex, uv);
+ gl_FragColor.a *= transparency;
}
diff --git a/data/shaders/caustics.frag b/data/shaders/caustics.frag
new file mode 100644
index 000000000..8ce7a6303
--- /dev/null
+++ b/data/shaders/caustics.frag
@@ -0,0 +1,17 @@
+uniform sampler2D tex;
+uniform sampler2D caustictex;
+uniform vec2 dir;
+uniform vec2 dir2;
+
+void main()
+{
+ vec2 tc = gl_TexCoord[0].xy;
+
+ vec3 col = texture2D(tex, tc).xyz;
+ float caustic = texture2D(caustictex, tc + dir).x;
+ float caustic2 = texture2D(caustictex, (tc.yx + dir2 * vec2(-0.6, 0.3)) * vec2(0.6)).x;
+
+ col += caustic * caustic2 * 10.0;
+
+ gl_FragColor = vec4(col, 1.0);
+}
diff --git a/data/shaders/collapse.frag b/data/shaders/collapse.frag
new file mode 100644
index 000000000..7e2e8b64c
--- /dev/null
+++ b/data/shaders/collapse.frag
@@ -0,0 +1,25 @@
+uniform sampler2D tex;
+uniform sampler2D oldtex;
+uniform vec2 pixel;
+uniform vec2 multi;
+uniform int size;
+
+void main()
+{
+ float res = 0.0;
+ vec2 tc = gl_TexCoord[0].xy;
+// tc.y = 1.0 - tc.y;
+ tc *= multi;
+
+ for (int i = 0; i < size; i++)
+ {
+ float col = texture2D(tex, tc).x;
+ res = max(col, res);
+
+ tc += pixel;
+ }
+
+ float old = texture2D(oldtex, gl_TexCoord[0].xy).x;
+
+ gl_FragColor = vec4(mix(old, res, 0.7));
+}
diff --git a/data/shaders/colorize.frag b/data/shaders/colorize.frag
new file mode 100644
index 000000000..2e44f6a07
--- /dev/null
+++ b/data/shaders/colorize.frag
@@ -0,0 +1,6 @@
+uniform vec3 col;
+
+void main()
+{
+ gl_FragColor = vec4(col, 1.0);
+}
diff --git a/data/shaders/colorize_ref.frag b/data/shaders/colorize_ref.frag
new file mode 100644
index 000000000..c7dac6c99
--- /dev/null
+++ b/data/shaders/colorize_ref.frag
@@ -0,0 +1,11 @@
+uniform vec3 col;
+uniform sampler2D tex;
+
+void main()
+{
+ float alpha = texture2D(tex, gl_TexCoord[0].xy).a;
+ if (alpha < 0.5)
+ discard;
+
+ gl_FragColor = vec4(col, 1.0);
+}
diff --git a/data/shaders/displace.frag b/data/shaders/displace.frag
new file mode 100644
index 000000000..4ab1a4feb
--- /dev/null
+++ b/data/shaders/displace.frag
@@ -0,0 +1,40 @@
+uniform sampler2D tex;
+uniform vec2 screen;
+uniform vec2 dir;
+uniform vec2 dir2;
+
+varying float camdist;
+
+void main()
+{
+ vec2 tc = gl_TexCoord[0].xy;
+
+ vec4 col = vec4(0.0);
+ const float maxlen = 0.02;
+
+ float horiz = texture2D(tex, tc + dir).x;
+ float vert = texture2D(tex, (tc.yx + dir2) * vec2(0.9)).x;
+
+ vec2 offset = vec2(horiz, vert);
+ offset *= 2.0;
+ offset -= 1.0;
+
+ // Fade according to distance to cam
+ float fade = 1.0 - smoothstep(1.0, 40.0, camdist);
+
+ // Fade according to distance from the edges
+ vec2 edger = gl_TexCoord[1].xy;
+ const float mindist = 0.1;
+ fade *= smoothstep(0.0, mindist, edger.x) * smoothstep(0.0, mindist, edger.y) *
+ (1.0 - smoothstep(1.0 - mindist, 1.0, edger.x)) *
+ (1.0 - smoothstep(1.0 - mindist, 1.0, edger.y));
+
+ offset *= 50.0 * fade * maxlen;
+
+ col.r = step(offset.x, 0.0) * -offset.x;
+ col.g = step(0.0, offset.x) * offset.x;
+ col.b = step(offset.y, 0.0) * -offset.y;
+ col.a = step(0.0, offset.y) * offset.y;
+
+ gl_FragColor = col;
+}
diff --git a/data/shaders/displace.vert b/data/shaders/displace.vert
new file mode 100644
index 000000000..f2fe1c59f
--- /dev/null
+++ b/data/shaders/displace.vert
@@ -0,0 +1,9 @@
+varying float camdist;
+
+void main() {
+ gl_Position = ftransform();
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[1] = gl_MultiTexCoord1;
+
+ camdist = length((gl_ModelViewMatrix * gl_Vertex).xyz);
+}
diff --git a/data/shaders/farplane.vert b/data/shaders/farplane.vert
new file mode 100644
index 000000000..a15bb824f
--- /dev/null
+++ b/data/shaders/farplane.vert
@@ -0,0 +1,6 @@
+void main() {
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[1] = gl_MultiTexCoord1;
+ gl_Position = (gl_ModelViewProjectionMatrix * gl_Vertex).xyww;
+ gl_FrontColor = gl_Color;
+}
diff --git a/data/shaders/flip.frag b/data/shaders/flip.frag
new file mode 100644
index 000000000..dda3a7076
--- /dev/null
+++ b/data/shaders/flip.frag
@@ -0,0 +1,9 @@
+uniform sampler2D tex;
+
+void main()
+{
+ vec2 texc = gl_TexCoord[0].xy;
+ texc.y = 1.0 - texc.y;
+
+ gl_FragColor = texture2D(tex, texc);
+}
diff --git a/data/shaders/fog.frag b/data/shaders/fog.frag
new file mode 100644
index 000000000..f2ed93327
--- /dev/null
+++ b/data/shaders/fog.frag
@@ -0,0 +1,34 @@
+uniform sampler2D tex;
+
+uniform float fogmax;
+uniform float startH;
+uniform float endH;
+uniform float start;
+uniform float end;
+uniform vec3 col;
+uniform vec3 campos;
+uniform mat4 ipvmat;
+
+float decdepth(vec4 rgba) {
+ return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
+}
+
+void main()
+{
+ float z = decdepth(vec4(texture2D(tex, gl_TexCoord[0].xy).xyz, 0.0));
+
+ vec3 tmp = vec3(gl_TexCoord[0].xy, z);
+ tmp = tmp * 2.0 - 1.0;
+
+ vec4 xpos = vec4(tmp, 1.0);
+ xpos = ipvmat * xpos;
+ xpos.xyz /= xpos.w;
+
+ float dist = distance(campos, xpos.xyz);
+ float fog = smoothstep(start, end, dist);
+ fog *= 1.0 - smoothstep(startH, endH, xpos.y);
+
+ fog = min(fog, fogmax);
+
+ gl_FragColor = vec4(col, fog);
+}
diff --git a/data/shaders/gaussian3h.frag b/data/shaders/gaussian3h.frag
new file mode 100644
index 000000000..f1ec80b89
--- /dev/null
+++ b/data/shaders/gaussian3h.frag
@@ -0,0 +1,19 @@
+uniform sampler2D tex;
+uniform vec2 pixel;
+
+// Gaussian separated blur with radius 3.
+
+void main()
+{
+ vec4 sum = vec4(0.0);
+ float X = gl_TexCoord[0].x;
+ float Y = gl_TexCoord[0].y;
+
+ sum += texture2D(tex, vec2(X - 3.0 * pixel.x, Y)) * 0.03125;
+ sum += texture2D(tex, vec2(X - 1.3333 * pixel.x, Y)) * 0.328125;
+ sum += texture2D(tex, vec2(X, Y)) * 0.273438;
+ sum += texture2D(tex, vec2(X + 1.3333 * pixel.x, Y)) * 0.328125;
+ sum += texture2D(tex, vec2(X + 3.0 * pixel.x, Y)) * 0.03125;
+
+ gl_FragColor = sum;
+}
diff --git a/data/shaders/gaussian3v.frag b/data/shaders/gaussian3v.frag
new file mode 100644
index 000000000..fec9ce8b1
--- /dev/null
+++ b/data/shaders/gaussian3v.frag
@@ -0,0 +1,19 @@
+uniform sampler2D tex;
+uniform vec2 pixel;
+
+// Gaussian separated blur with radius 3.
+
+void main()
+{
+ vec4 sum = vec4(0.0);
+ float X = gl_TexCoord[0].x;
+ float Y = gl_TexCoord[0].y;
+
+ sum += texture2D(tex, vec2(X, Y - 3.0 * pixel.y)) * 0.03125;
+ sum += texture2D(tex, vec2(X, Y - 1.3333 * pixel.y)) * 0.328125;
+ sum += texture2D(tex, vec2(X, Y)) * 0.273438;
+ sum += texture2D(tex, vec2(X, Y + 1.3333 * pixel.y)) * 0.328125;
+ sum += texture2D(tex, vec2(X, Y + 3.0 * pixel.y)) * 0.03125;
+
+ gl_FragColor = sum;
+}
diff --git a/data/shaders/gaussian6h.frag b/data/shaders/gaussian6h.frag
new file mode 100644
index 000000000..3aad9b7c0
--- /dev/null
+++ b/data/shaders/gaussian6h.frag
@@ -0,0 +1,21 @@
+uniform sampler2D tex;
+uniform vec2 pixel;
+
+// Gaussian separated blur with radius 6.
+
+void main()
+{
+ vec4 sum = vec4(0.0);
+ float X = gl_TexCoord[0].x;
+ float Y = gl_TexCoord[0].y;
+
+ sum += texture2D(tex, vec2(X - 5.13333 * pixel.x, Y)) * 0.00640869;
+ sum += texture2D(tex, vec2(X - 3.26667 * pixel.x, Y)) * 0.083313;
+ sum += texture2D(tex, vec2(X - 1.4 * pixel.x, Y)) * 0.305481;
+ sum += texture2D(tex, vec2(X, Y)) * 0.209473;
+ sum += texture2D(tex, vec2(X + 1.4 * pixel.x, Y)) * 0.305481;
+ sum += texture2D(tex, vec2(X + 3.26667 * pixel.x, Y)) * 0.083313;
+ sum += texture2D(tex, vec2(X + 5.13333 * pixel.x, Y)) * 0.00640869;
+
+ gl_FragColor = sum;
+}
diff --git a/data/shaders/gaussian6v.frag b/data/shaders/gaussian6v.frag
new file mode 100644
index 000000000..5b3e70ee2
--- /dev/null
+++ b/data/shaders/gaussian6v.frag
@@ -0,0 +1,21 @@
+uniform sampler2D tex;
+uniform vec2 pixel;
+
+// Gaussian separated blur with radius 6.
+
+void main()
+{
+ vec4 sum = vec4(0.0);
+ float X = gl_TexCoord[0].x;
+ float Y = gl_TexCoord[0].y;
+
+ sum += texture2D(tex, vec2(X, Y - 5.13333 * pixel.y)) * 0.00640869;
+ sum += texture2D(tex, vec2(X, Y - 3.26667 * pixel.y)) * 0.083313;
+ sum += texture2D(tex, vec2(X, Y - 1.4 * pixel.y)) * 0.305481;
+ sum += texture2D(tex, vec2(X, Y)) * 0.209473;
+ sum += texture2D(tex, vec2(X, Y + 1.4 * pixel.y)) * 0.305481;
+ sum += texture2D(tex, vec2(X, Y + 3.26667 * pixel.y)) * 0.083313;
+ sum += texture2D(tex, vec2(X, Y + 5.13333 * pixel.y)) * 0.00640869;
+
+ gl_FragColor = sum;
+}
diff --git a/data/shaders/glow.frag b/data/shaders/glow.frag
new file mode 100644
index 000000000..3932dc42e
--- /dev/null
+++ b/data/shaders/glow.frag
@@ -0,0 +1,16 @@
+uniform sampler2D tex;
+uniform vec2 res;
+
+void main()
+{
+ vec2 coords = gl_FragCoord.xy / res;
+
+ vec4 col = texture2D(tex, coords);
+ float alpha = col.a;
+
+ if (alpha < 0.04) discard;
+
+ col *= vec4(vec3(4.0), 1.5);
+
+ gl_FragColor = col;
+}
diff --git a/data/shaders/godfade.frag b/data/shaders/godfade.frag
new file mode 100644
index 000000000..659742738
--- /dev/null
+++ b/data/shaders/godfade.frag
@@ -0,0 +1,16 @@
+uniform sampler2D tex;
+uniform vec3 col;
+
+void main()
+{
+ vec4 res = texture2D(tex, gl_TexCoord[0].xy);
+
+ // Keep the sun fully bright, but fade the sky
+ float mul = distance(res.xyz, col);
+ mul = step(mul, 0.02);
+ mul *= 0.97;
+
+ res = res * vec4(mul);
+
+ gl_FragColor = res;
+}
diff --git a/data/shaders/godray.frag b/data/shaders/godray.frag
new file mode 100644
index 000000000..0e06dfb03
--- /dev/null
+++ b/data/shaders/godray.frag
@@ -0,0 +1,29 @@
+uniform sampler2D tex;
+uniform vec2 sunpos;
+
+#define SAMPLES 12
+
+const float decaystep = 0.88;
+
+void main()
+{
+ vec2 texc = gl_TexCoord[0].xy;
+ vec2 tosun = sunpos - texc;
+
+ if (dot(tosun, tosun) > 0.49) discard;
+
+ vec2 dist = tosun * 1.0/(float(SAMPLES) * 1.12);
+
+ vec3 col = texture2D(tex, texc).xyz;
+ float decay = 1.0;
+
+ for (int i = 0; i < SAMPLES; i++) {
+ texc += dist;
+ vec3 here = texture2D(tex, texc).xyz;
+ here *= decay;
+ col += here;
+ decay *= decaystep;
+ }
+
+ gl_FragColor = vec4(col, 1.0) * 0.8;
+}
diff --git a/data/shaders/grass.frag b/data/shaders/grass.frag
index e70be4351..9bd1e0555 100644
--- a/data/shaders/grass.frag
+++ b/data/shaders/grass.frag
@@ -1,54 +1,8 @@
-// SuperTuxKart - a fun racing game with go-kart
-// Copyright (C) 2013 the SuperTuxKart team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 3
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-uniform vec4 fogColor;
-uniform float fogFrom;
-uniform float fogTo;
-uniform int fog;
uniform sampler2D tex;
-varying vec4 coord;
void main()
{
- vec4 color = texture2D(tex, gl_TexCoord[0].st);
- vec4 solidColor = vec4(color.r, color.g, color.b, 1);
+ vec4 color = texture2D(tex, gl_TexCoord[0].st);
- if (fog == 1)
- {
- if (coord.z > fogTo)
- {
- gl_FragColor = fogColor;
- gl_FragColor.a = color.a;
- }
- else if (coord.z > fogFrom)
- {
- float fogIntensity = (coord.z - fogFrom) / (fogTo - fogFrom);
- vec4 color2 = fogIntensity*fogColor + (1.0 - fogIntensity)*solidColor;
- color2.a = color.a;
- gl_FragColor = color2;
- }
- else
- {
- gl_FragColor = color;
- }
- }
- else
- {
- gl_FragColor = color;
- }
+ gl_FragColor = color;
}
diff --git a/data/shaders/grass.vert b/data/shaders/grass.vert
index 8aeee783c..e2208de2c 100644
--- a/data/shaders/grass.vert
+++ b/data/shaders/grass.vert
@@ -1,33 +1,11 @@
-// SuperTuxKart - a fun racing game with go-kart
-// Copyright (C) 2013 the SuperTuxKart team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 3
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-
-uniform float angle;
-uniform float amplitude;
-varying vec4 coord;
-
+uniform vec3 windDir;
void main()
{
- gl_TexCoord[0] = gl_MultiTexCoord0;
- vec4 vertexPosition = ftransform(); //gl_ModelViewMatrix * gl_Vertex;
- vertexPosition += vec4(1,0,0,0) * amplitude * gl_Color.r * sin(angle);
- gl_Position = vertexPosition;
- gl_FrontColor = vec4(1,1,1,1);
- gl_BackColor = vec4(1,1,1,1);
- coord = vertexPosition;
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+
+ vec4 vertexPosition = gl_Vertex;
+ vertexPosition.xyz += windDir * gl_Color.r;
+
+ gl_Position = gl_ModelViewProjectionMatrix * vertexPosition;
}
diff --git a/data/shaders/lightblend.frag b/data/shaders/lightblend.frag
new file mode 100644
index 000000000..64530205e
--- /dev/null
+++ b/data/shaders/lightblend.frag
@@ -0,0 +1,19 @@
+uniform sampler2D tex;
+uniform vec3 ambient;
+uniform sampler2D spectex;
+
+void main()
+{
+ vec2 texc = gl_TexCoord[0].xy;
+
+ vec4 col = texture2D(tex, texc);
+ vec4 specular = texture2D(spectex, texc);
+
+ col.xyz += ambient;
+ float spec = col.a - 0.05;
+ spec *= specular.a;
+ col.xyz += spec;
+ col.a = 1.0;
+
+ gl_FragColor = col;
+}
diff --git a/data/shaders/mipviz.frag b/data/shaders/mipviz.frag
new file mode 100644
index 000000000..e6bd31741
--- /dev/null
+++ b/data/shaders/mipviz.frag
@@ -0,0 +1,52 @@
+#version 120
+
+uniform sampler2D tex;
+uniform vec2 texsize;
+uniform int notex;
+
+float miplevel(in vec2 texture_coordinate)
+{
+ // The OpenGL Graphics System: A Specification 4.2
+ // - chapter 3.9.11, equation 3.21
+
+ vec2 dx_vtc = dFdx(texture_coordinate);
+ vec2 dy_vtc = dFdy(texture_coordinate);
+ float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
+
+ return 0.5 * log2(delta_max_sqr); // == log2(sqrt(delta_max_sqr));
+}
+
+void main() {
+
+ if (notex != 0) {
+ gl_FragColor = gl_Color;
+ return;
+ }
+
+ // Buggy Intel windows driver workaround
+ vec4 levels[6] = vec4[](
+ vec4(0.0, 0.0, 1.0, 0.8),
+ vec4(0.0, 0.5, 1.0, 0.4),
+ vec4(1.0, 1.0, 1.0, 0.0),
+ vec4(1.0, 0.7, 0.0, 0.2),
+ vec4(1.0, 0.3, 0.0, 0.6),
+ vec4(1.0, 0.0, 0.0, 0.8)
+ );
+
+ float mip = miplevel(texsize * gl_TexCoord[0].xy) + 2.0;
+ mip = clamp(mip, 0.0, 5.0);
+
+ int lowmip = int(mip);
+ int highmip = lowmip + 1;
+ if (highmip > 5)
+ highmip = 5;
+
+ float mixer = fract(mip);
+
+ vec4 mixcol = mix(levels[lowmip], levels[highmip], mixer);
+ vec4 tcol = texture2D(tex, gl_TexCoord[0].xy);
+
+ vec3 col = mix(tcol.xyz, mixcol.xyz, mixcol.a);
+
+ gl_FragColor = vec4(col, tcol.a);
+}
diff --git a/data/shaders/mlaa_blend2.frag b/data/shaders/mlaa_blend2.frag
new file mode 100644
index 000000000..0be80576b
--- /dev/null
+++ b/data/shaders/mlaa_blend2.frag
@@ -0,0 +1,112 @@
+#define MAX_SEARCH_STEPS 8.0
+#define MAX_DISTANCE 33.0
+
+#extension GL_ARB_shader_texture_lod: enable
+
+uniform sampler2D edgesMap;
+uniform sampler2D areaMap;
+
+uniform vec2 PIXEL_SIZE;
+
+/**
+ * This one just returns the first level of a mip map chain, which allow us to
+ * avoid the nasty ddx/ddy warnings, even improving the performance a little
+ * bit.
+ */
+vec4 tex2Doffset(sampler2D map, vec2 texcoord, vec2 offset) {
+ return texture2DLod(map, texcoord + PIXEL_SIZE * offset, 0.0);
+}
+
+float SearchXLeft(vec2 texcoord) {
+ // We compare with 0.9 to prevent bilinear access precision problems.
+ float i;
+ float e = 0.0;
+ for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) {
+ e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0)).g;
+ if (e < 0.9) break;
+ }
+ return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
+}
+
+float SearchXRight(vec2 texcoord) {
+ float i;
+ float e = 0.0;
+ for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) {
+ e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0)).g;
+ if (e < 0.9) break;
+ }
+ return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
+}
+
+float SearchYDown(vec2 texcoord) {
+ float i;
+ float e = 0.0;
+ for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0) {
+ e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0).yx).r;
+ if (e < 0.9) break;
+ }
+ return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
+}
+
+float SearchYUp(vec2 texcoord) {
+ float i;
+ float e = 0.0;
+ for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0) {
+ e = tex2Doffset(edgesMap, texcoord, vec2(i, 0.0).yx).r;
+ if (e < 0.9) break;
+ }
+ return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
+}
+
+
+vec2 round(vec2 invec) {
+ return vec2(floor(abs(invec) + vec2(0.5)) * sign(invec));
+}
+
+vec2 Area(vec2 distance, float e1, float e2) {
+ // * By dividing by areaSize - 1.0 below we are implicitely offsetting to
+ // always fall inside of a pixel
+ // * Rounding prevents bilinear access precision problems
+ float areaSize = MAX_DISTANCE * 5.0;
+ vec2 pixcoord = MAX_DISTANCE * round(4.0 * vec2(e1, e2)) + distance;
+ vec2 texcoord = pixcoord / (areaSize - 1.0);
+ return texture2DLod(areaMap, texcoord, 0.0).ra;
+}
+
+void main() {
+ vec4 areas = vec4(0.0);
+
+ vec2 e = texture2D(edgesMap, gl_TexCoord[0].xy).rg;
+
+ if (e.g != 0.0) { // Edge at north
+
+ // Search distances to the left and to the right:
+ vec2 d = vec2(SearchXLeft(gl_TexCoord[0].xy), SearchXRight(gl_TexCoord[0].xy));
+
+ // Now fetch the crossing edges. Instead of sampling between edgels, we
+ // sample at 0.25, to be able to discern what value has each edgel:
+ vec4 coords = vec4(d.x, 0.25, d.y + 1.0, 0.25) * PIXEL_SIZE.xyxy + gl_TexCoord[0].xyxy;
+ float e1 = texture2DLod(edgesMap, coords.xy, 0.0).r;
+ float e2 = texture2DLod(edgesMap, coords.zw, 0.0).r;
+
+ // Ok, we know how this pattern looks like, now it is time for getting
+ // the actual area:
+ areas.rg = Area(abs(d), e1, e2);
+ }
+
+ if (e.r != 0.0) { // Edge at west
+
+ // Search distances to the top and to the bottom:
+ vec2 d = vec2(SearchYUp(gl_TexCoord[0].xy), SearchYDown(gl_TexCoord[0].xy));
+
+ // Now fetch the crossing edges (yet again):
+ vec4 coords = vec4(-0.25, d.x, -0.25, d.y - 1.0) * PIXEL_SIZE.xyxy + gl_TexCoord[0].xyxy;
+ float e1 = texture2DLod(edgesMap, coords.xy, 0.0).g;
+ float e2 = texture2DLod(edgesMap, coords.zw, 0.0).g;
+
+ // Get the area for this direction:
+ areas.ba = Area(abs(d), e1, e2);
+ }
+
+ gl_FragColor = areas;
+}
diff --git a/data/shaders/mlaa_color1.frag b/data/shaders/mlaa_color1.frag
new file mode 100644
index 000000000..44ac9965b
--- /dev/null
+++ b/data/shaders/mlaa_color1.frag
@@ -0,0 +1,25 @@
+varying vec4 offset[2];
+
+uniform sampler2D colorMapG;
+const float threshold = 0.1f;
+
+void main() {
+ vec3 weights = vec3(0.2126,0.7152, 0.0722); // ITU-R BT. 709
+
+ /**
+ * Luma calculation requires gamma-corrected colors:
+ */
+ float L = dot(texture2D(colorMapG, gl_TexCoord[0].xy).rgb, weights);
+ float Lleft = dot(texture2D(colorMapG, offset[0].xy).rgb, weights);
+ float Ltop = dot(texture2D(colorMapG, offset[0].zw).rgb, weights);
+ float Lright = dot(texture2D(colorMapG, offset[1].xy).rgb, weights);
+ float Lbottom = dot(texture2D(colorMapG, offset[1].zw).rgb, weights);
+
+ vec4 delta = abs(vec4(L) - vec4(Lleft, Ltop, Lright, Lbottom));
+ vec4 edges = step(vec4(threshold), delta);
+
+ if (dot(edges, vec4(1.0)) == 0.0)
+ discard;
+
+ gl_FragColor = edges;
+}
diff --git a/data/shaders/mlaa_neigh3.frag b/data/shaders/mlaa_neigh3.frag
new file mode 100644
index 000000000..6f9bfabb0
--- /dev/null
+++ b/data/shaders/mlaa_neigh3.frag
@@ -0,0 +1,38 @@
+varying vec4 offset[2];
+
+uniform sampler2D blendMap;
+uniform sampler2D colorMap;
+
+void main() {
+ // Fetch the blending weights for current pixel:
+ vec4 topLeft = texture2D(blendMap, gl_TexCoord[0].xy);
+ float bottom = texture2D(blendMap, offset[1].zw).g;
+ float right = texture2D(blendMap, offset[1].xy).a;
+ vec4 a = vec4(topLeft.r, bottom, topLeft.b, right);
+
+ // Up to 4 lines can be crossing a pixel (one in each edge). So, we perform
+ // a weighted average, where the weight of each line is 'a' cubed, which
+ // favors blending and works well in practice.
+ vec4 w = a * a * a;
+
+ // There is some blending weight with a value greater than 0.0?
+ float sum = dot(w, vec4(1.0));
+ if (sum < 1e-5)
+ discard;
+
+ vec4 color = vec4(0.0);
+
+ // Add the contributions of the possible 4 lines that can cross this pixel:
+ vec4 C = texture2D(colorMap, gl_TexCoord[0].xy);
+ vec4 Cleft = texture2D(colorMap, offset[0].xy);
+ vec4 Ctop = texture2D(colorMap, offset[0].zw);
+ vec4 Cright = texture2D(colorMap, offset[1].xy);
+ vec4 Cbottom = texture2D(colorMap, offset[1].zw);
+ color = mix(C, Ctop, a.r) * w.r + color;
+ color = mix(C, Cbottom, a.g) * w.g + color;
+ color = mix(C, Cleft, a.b) * w.b + color;
+ color = mix(C, Cright, a.a) * w.a + color;
+
+ // Normalize the resulting color and we are finished!
+ gl_FragColor = color / sum;
+}
diff --git a/data/shaders/mlaa_offset.vert b/data/shaders/mlaa_offset.vert
new file mode 100644
index 000000000..a0b03702e
--- /dev/null
+++ b/data/shaders/mlaa_offset.vert
@@ -0,0 +1,12 @@
+varying vec4 offset[2];
+uniform vec2 PIXEL_SIZE;
+
+void main() {
+ gl_Position = ftransform();
+ vec4 invy = gl_MultiTexCoord0;
+// invy.y = 1.0 - invy.y;
+ gl_TexCoord[0] = invy;
+
+ offset[0] = invy.xyxy + PIXEL_SIZE.xyxy * vec4(-1.0, 0.0, 0.0, 1.0);
+ offset[1] = invy.xyxy + PIXEL_SIZE.xyxy * vec4( 1.0, 0.0, 0.0, -1.0);
+}
diff --git a/data/shaders/motion_blur.frag b/data/shaders/motion_blur.frag
index c57abbf59..aef0843fb 100644
--- a/data/shaders/motion_blur.frag
+++ b/data/shaders/motion_blur.frag
@@ -41,7 +41,7 @@ uniform float mask_radius;
uniform float max_tex_height;
// Number of samples used for blurring
-#define NB_SAMPLES 12
+#define NB_SAMPLES 8
void main()
{
@@ -50,14 +50,6 @@ void main()
// Sample the color buffer
vec3 color = texture2D(color_buffer, texcoords).rgb;
- // If no motion blur is needed, don't do any of the blur computation,
- // just return the color from the texture.
- if(boost_amount==0.0)
- {
- gl_FragColor = vec4(color, 1.0);
- return;
- }
-
// Compute the blur direction.
// IMPORTANT: we don't normalize it so that it avoids a glitch around 'center',
// plus it naturally scales the motion blur in a cool way :)
diff --git a/data/shaders/multiply.frag b/data/shaders/multiply.frag
new file mode 100644
index 000000000..9394e9595
--- /dev/null
+++ b/data/shaders/multiply.frag
@@ -0,0 +1,10 @@
+uniform sampler2D tex1;
+uniform sampler2D tex2;
+
+void main()
+{
+ vec4 col1 = texture2D(tex1, gl_TexCoord[0].xy);
+ vec4 col2 = vec4(vec3(texture2D(tex2, gl_TexCoord[0].xy).x), 1.0);
+
+ gl_FragColor = col1 * col2;
+}
diff --git a/data/shaders/normalmap.frag b/data/shaders/normalmap.frag
index dfc10424b..1040e1662 100644
--- a/data/shaders/normalmap.frag
+++ b/data/shaders/normalmap.frag
@@ -4,7 +4,7 @@
uniform sampler2D BumpTex; //The bump-map
uniform sampler2D DecalTex; //The texture
uniform sampler2D LightMapTex;
- int HasLightMap;
+uniform int HasLightMap;
// New bumpmapping
varying vec3 lightVec;
@@ -19,18 +19,18 @@ void main()
normal = normalize (normal);
// compute diffuse lighting
- float lamberFactor = max (dot (lightVec, normal), 0.0) ;
+ float lamberFactor = max (dot (lightVec, normal), 0.0);
vec4 diffuseMaterial;
- diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st);
+ diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st);
- if (HasLightMap < 1)
- {
- // 0.5 is the ambient light
- gl_FragColor = diffuseMaterial * (0.5 + lamberFactor*0.5);
- }
- else
- {
- gl_FragColor = diffuseMaterial * (0.5 + lamberFactor*0.5) * texture2D(LightMapTex, gl_TexCoord[0].st);
- }
+ if (HasLightMap < 1)
+ {
+ // 0.5 is the ambient light
+ gl_FragColor = diffuseMaterial * (0.5 + lamberFactor*0.5);
+ }
+ else
+ {
+ gl_FragColor = diffuseMaterial * (0.5 + lamberFactor*0.5) * texture2D(LightMapTex, gl_TexCoord[0].st);
+ }
}
diff --git a/data/shaders/objectpass.frag b/data/shaders/objectpass.frag
new file mode 100644
index 000000000..c557894d2
--- /dev/null
+++ b/data/shaders/objectpass.frag
@@ -0,0 +1,40 @@
+varying vec3 nor;
+
+uniform sampler2D tex;
+uniform sampler2D lighttex;
+uniform float far;
+uniform int hastex;
+uniform int haslightmap;
+uniform float objectid;
+
+const float near = 1.0;
+
+vec4 encdepth(float v) {
+ vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
+ enc = fract(enc);
+ enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
+ return enc;
+}
+
+void main() {
+
+ float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
+
+ // Tune for better inside range without losing outdoors
+ linear_z *= 2.0;
+
+ vec4 light = vec4(1.0);
+
+ if (haslightmap != 0) {
+ light = texture2D(lighttex, gl_TexCoord[1].xy);
+ }
+
+ if (hastex != 0)
+ gl_FragData[0] = texture2D(tex, gl_TexCoord[0].xy) * light;
+ else
+ gl_FragData[0] = gl_Color;
+
+ gl_FragData[1] = vec4(nor, linear_z);
+ gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
+}
+
diff --git a/data/shaders/objectpass.vert b/data/shaders/objectpass.vert
new file mode 100644
index 000000000..76e749908
--- /dev/null
+++ b/data/shaders/objectpass.vert
@@ -0,0 +1,14 @@
+varying vec3 nor;
+uniform mat4 invtworldm;
+
+void main() {
+
+ nor = (invtworldm * vec4(gl_Normal, 0.0)).xyz;
+ nor = normalize(nor);
+ nor = nor * 0.5 + 0.5;
+
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[1] = gl_MultiTexCoord1;
+ gl_Position = ftransform();
+ gl_FrontColor = gl_Color;
+}
diff --git a/data/shaders/objectpass_ref.frag b/data/shaders/objectpass_ref.frag
new file mode 100644
index 000000000..daa022752
--- /dev/null
+++ b/data/shaders/objectpass_ref.frag
@@ -0,0 +1,37 @@
+varying vec3 nor;
+uniform sampler2D tex;
+uniform float far;
+uniform int hastex;
+uniform float objectid;
+
+const float near = 1.0;
+
+vec4 encdepth(float v) {
+ vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
+ enc = fract(enc);
+ enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
+ return enc;
+}
+
+void main() {
+
+ float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
+
+ // Tune for better inside range without losing outdoors
+ linear_z *= 2.0;
+
+ if (hastex != 0) {
+ vec4 col = texture2D(tex, gl_TexCoord[0].xy);
+
+ if (col.a < 0.5)
+ discard;
+
+ gl_FragData[0] = col;
+ } else {
+ gl_FragData[0] = gl_Color;
+ }
+
+ gl_FragData[1] = vec4(nor, linear_z);
+ gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
+}
+
diff --git a/data/shaders/objectpass_rimlit.frag b/data/shaders/objectpass_rimlit.frag
new file mode 100644
index 000000000..5979f2214
--- /dev/null
+++ b/data/shaders/objectpass_rimlit.frag
@@ -0,0 +1,45 @@
+varying vec3 nor;
+uniform sampler2D tex;
+uniform float far;
+uniform int hastex;
+uniform float objectid;
+
+varying vec3 eyenor;
+varying vec3 viewpos;
+
+const float near = 1.0;
+
+vec4 encdepth(float v) {
+ vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
+ enc = fract(enc);
+ enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
+ return enc;
+}
+
+void main() {
+
+ float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
+
+ // Tune for better inside range without losing outdoors
+ linear_z *= 2.0;
+
+ float rim = 1.0 - dot(eyenor, viewpos);
+ rim = smoothstep(0.5, 1.5, rim) * 0.35;
+
+ if (hastex != 0) {
+ vec4 col = texture2D(tex, gl_TexCoord[0].xy);
+
+ if (col.a < 0.5)
+ discard;
+
+ col.xyz += rim;
+
+ gl_FragData[0] = col;
+ } else {
+ gl_FragData[0] = gl_Color + vec4(vec3(rim), 0.0);
+ }
+
+ gl_FragData[1] = vec4(nor, linear_z);
+ gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
+}
+
diff --git a/data/shaders/objectpass_rimlit.vert b/data/shaders/objectpass_rimlit.vert
new file mode 100644
index 000000000..b3d98e449
--- /dev/null
+++ b/data/shaders/objectpass_rimlit.vert
@@ -0,0 +1,19 @@
+varying vec3 nor;
+uniform mat4 invtworldm;
+
+varying vec3 eyenor;
+varying vec3 viewpos;
+
+void main() {
+
+ nor = (invtworldm * vec4(gl_Normal, 0.0)).xyz;
+ nor = normalize(nor);
+ nor = nor * 0.5 + 0.5;
+
+ eyenor = gl_NormalMatrix * gl_Normal;
+ viewpos = -normalize((gl_ModelViewMatrix * gl_Vertex).xyz);
+
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = ftransform();
+ gl_FrontColor = gl_Color;
+}
diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag
new file mode 100644
index 000000000..f8abac686
--- /dev/null
+++ b/data/shaders/objectpass_spheremap.frag
@@ -0,0 +1,42 @@
+varying vec3 nor;
+uniform sampler2D tex;
+uniform float far;
+uniform float objectid;
+
+varying vec3 eyenor;
+varying vec3 viewpos;
+
+const float near = 1.0;
+
+vec4 encdepth(float v) {
+ vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
+ enc = fract(enc);
+ enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
+ return enc;
+}
+
+void main() {
+
+ float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
+
+ // Tune for better inside range without losing outdoors
+ linear_z *= 2.0;
+
+ // Calculate the spherical UV
+ const vec3 forward = vec3(0.0, 0.0, 1.0);
+
+ // get the angle between the forward vector and the horizontal portion of the normal
+ vec3 normal_x = normalize(vec3(eyenor.x, 0.0, eyenor.z));
+ float sin_theta_x = length(cross( forward, normal_x )) * eyenor.x/abs(eyenor.x);
+
+ // get the angle between the forward vector and the vertical portion of the normal
+ vec3 normal_y = normalize(vec3(0.0, eyenor.y, eyenor.z));
+ float sin_theta_y = length(cross( forward, normal_y )) * eyenor.y/abs(eyenor.y);
+
+ vec4 detail0 = texture2D(tex, vec2(0.5 + sin_theta_x*0.5, 0.5 + sin_theta_y*0.5));
+
+ gl_FragData[0] = detail0 * gl_Color;
+
+ gl_FragData[1] = vec4(nor, linear_z);
+ gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
+}
diff --git a/data/shaders/pass.frag b/data/shaders/pass.frag
new file mode 100644
index 000000000..10f94ce0d
--- /dev/null
+++ b/data/shaders/pass.frag
@@ -0,0 +1,6 @@
+uniform sampler2D tex;
+
+void main()
+{
+ gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
+}
diff --git a/data/shaders/pass.vert b/data/shaders/pass.vert
new file mode 100644
index 000000000..2fd32c1ac
--- /dev/null
+++ b/data/shaders/pass.vert
@@ -0,0 +1,6 @@
+void main() {
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[1] = gl_MultiTexCoord1;
+ gl_Position = ftransform();
+ gl_FrontColor = gl_Color;
+}
diff --git a/data/shaders/penumbrah.frag b/data/shaders/penumbrah.frag
new file mode 100644
index 000000000..822c73e56
--- /dev/null
+++ b/data/shaders/penumbrah.frag
@@ -0,0 +1,52 @@
+uniform sampler2D tex;
+uniform vec2 pixel;
+
+// Separated penumbra, horizontal
+
+void main()
+{
+ float sum = 0.0;
+ vec4 tmp;
+ float X = gl_TexCoord[0].x;
+ float Y = gl_TexCoord[0].y;
+ float width = 0.0;
+ float zsum = 0.00001;
+
+ tmp = texture2D(tex, vec2(X - 5.13333 * pixel.x, Y));
+ sum += tmp.x * 0.00640869;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X - 3.26667 * pixel.x, Y));
+ sum += tmp.x * 0.083313;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X - 1.4 * pixel.x, Y));
+ sum += tmp.x * 0.305481;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X, Y));
+ sum += tmp.x * 0.209473;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X + 1.4 * pixel.x, Y));
+ sum += tmp.x * 0.305481;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X + 3.26667 * pixel.x, Y));
+ sum += tmp.x * 0.083313;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X + 5.13333 * pixel.x, Y));
+ sum += tmp.x * 0.00640869;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ float hasz = step(0.7, zsum);
+ gl_FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0);
+}
diff --git a/data/shaders/penumbrav.frag b/data/shaders/penumbrav.frag
new file mode 100644
index 000000000..6a6ef2ca0
--- /dev/null
+++ b/data/shaders/penumbrav.frag
@@ -0,0 +1,52 @@
+uniform sampler2D tex;
+uniform vec2 pixel;
+
+// Separated penumbra, vertical
+
+void main()
+{
+ float sum = 0.0;
+ vec4 tmp;
+ float X = gl_TexCoord[0].x;
+ float Y = gl_TexCoord[0].y;
+ float width = 0.0;
+ float zsum = 0.00001;
+
+ tmp = texture2D(tex, vec2(X, Y - 5.13333 * pixel.y));
+ sum += tmp.x * 0.00640869;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X, Y - 3.26667 * pixel.y));
+ sum += tmp.x * 0.083313;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X, Y - 1.4 * pixel.y));
+ sum += tmp.x * 0.305481;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X, Y));
+ sum += tmp.x * 0.209473;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X, Y + 1.4 * pixel.y));
+ sum += tmp.x * 0.305481;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X, Y + 3.26667 * pixel.y));
+ sum += tmp.x * 0.083313;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ tmp = texture2D(tex, vec2(X, Y + 5.13333 * pixel.y));
+ sum += tmp.x * 0.00640869;
+ zsum += tmp.z;
+ width += tmp.y;
+
+ float hasz = step(0.7, zsum);
+ gl_FragColor = vec4(sum, (width / zsum) * hasz, hasz, 1.0);
+}
diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag
new file mode 100644
index 000000000..facc40c0e
--- /dev/null
+++ b/data/shaders/pointlight.frag
@@ -0,0 +1,50 @@
+uniform sampler2D ntex;
+uniform sampler2D dtex;
+
+uniform vec3 center;
+uniform vec3 col;
+uniform vec3 campos;
+uniform float r;
+uniform float spec;
+uniform vec2 screen;
+uniform mat4 invprojview;
+
+float decdepth(vec4 rgba) {
+ return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
+}
+
+void main() {
+
+ vec2 texc = gl_FragCoord.xy / screen;
+ float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0));
+
+ if (z < 0.03) discard;
+
+ vec3 tmp = vec3(texc, z);
+ tmp = tmp * 2.0 - 1.0;
+
+ vec4 xpos = vec4(tmp, 1.0);
+ xpos = invprojview * xpos;
+ xpos.xyz /= xpos.w;
+
+ float d = distance(center, xpos.xyz);
+ if (d > r) discard;
+
+ float att = 1.0 - smoothstep(0.0, r, d);
+
+ vec3 norm = texture2D(ntex, texc).xyz;
+ norm = (norm - 0.5) * 2.0;
+
+ vec3 camdir = normalize(campos - xpos.xyz);
+
+ vec3 L = normalize(center - xpos.xyz);
+ vec3 H = normalize(L + camdir);
+
+ float NdotL = max(0.0, dot(norm, L)) * att;
+ if (NdotL < 0.01) discard;
+ float NdotH = max(0.0, dot(norm, H));
+ NdotH = pow(NdotH, spec);
+ NdotH += 0.05; // offset so that the alpha test doesn't kill us
+
+ gl_FragColor = NdotL * vec4(col, NdotH);
+}
diff --git a/data/shaders/ppdisplace.frag b/data/shaders/ppdisplace.frag
new file mode 100644
index 000000000..a06293649
--- /dev/null
+++ b/data/shaders/ppdisplace.frag
@@ -0,0 +1,26 @@
+uniform sampler2D tex;
+uniform sampler2D dtex;
+
+uniform int viz;
+
+void main()
+{
+ vec2 tc = gl_TexCoord[0].xy;
+
+ vec4 shiftval = texture2D(dtex, tc) / vec4(50.0);
+ vec2 shift;
+ shift.x = -shiftval.x + shiftval.y;
+ shift.y = -shiftval.z + shiftval.w;
+
+ tc += shift;
+
+ vec4 newcol = texture2D(tex, tc);
+
+ if (viz < 1)
+ {
+ gl_FragColor = newcol;
+ } else
+ {
+ gl_FragColor = shiftval * vec4(50.0);
+ }
+}
diff --git a/data/shaders/rain.frag b/data/shaders/rain.frag
new file mode 100644
index 000000000..10f94ce0d
--- /dev/null
+++ b/data/shaders/rain.frag
@@ -0,0 +1,6 @@
+uniform sampler2D tex;
+
+void main()
+{
+ gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
+}
diff --git a/data/shaders/rain.vert b/data/shaders/rain.vert
new file mode 100644
index 000000000..f2a764ede
--- /dev/null
+++ b/data/shaders/rain.vert
@@ -0,0 +1,33 @@
+uniform float screenw;
+uniform float time;
+uniform mat4 viewm;
+uniform vec3 campos;
+
+void main()
+{
+ const float size = 0.5;
+
+ // This simulation will run accurately for a bit under five days.
+ vec4 start = gl_Vertex;
+ start.y -= time;
+
+ // How many times has it fell?
+ float count = floor(start.y / 24.0);
+ start.x += sin(count);
+ start.z += cos(count);
+
+ vec2 signs = sign(start.xz);
+ start.xz = mod(start.xz, 17.5) * signs;
+
+ start.y = mod(start.y, 24.0) - 3.0;
+
+ start.xyz += campos;
+
+ vec4 eyepos = viewm * start;
+ vec4 projCorner = gl_ProjectionMatrix * vec4(vec2(size), eyepos.z, eyepos.w);
+
+ gl_PointSize = screenw * projCorner.x / projCorner.w;
+ gl_Position = gl_ProjectionMatrix * eyepos;
+
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+}
diff --git a/data/shaders/shadowgen.frag b/data/shaders/shadowgen.frag
new file mode 100644
index 000000000..6c2d8501a
--- /dev/null
+++ b/data/shaders/shadowgen.frag
@@ -0,0 +1,44 @@
+uniform sampler2D halft; // half is a reserved word
+uniform sampler2D quarter;
+uniform sampler2D eighth;
+
+void main()
+{
+ vec3 val[3];
+ val[0] = texture2D(halft, gl_TexCoord[0].xy).xyz;
+ val[1] = texture2D(quarter, gl_TexCoord[0].xy).xyz;
+ val[2] = texture2D(eighth, gl_TexCoord[0].xy).xyz;
+
+ // Find the first level with a penumbra value
+ int i;
+ float q = 0.0;
+ float outval = 1.0;
+
+ float hasshadow = dot(vec3(1.0), vec3(val[0].z, val[1].z, val[2].z));
+
+ if (hasshadow > 0.9)
+ {
+ for (i = 0; i < 3; i++)
+ {
+ if (val[i].z > 0.9)
+ {
+ q = val[i].y;
+ break;
+ }
+ }
+
+ q *= 8.0;
+ q = max(1.0, q);
+ q = log2(q);
+ q = min(1.9, q);
+
+ // q is now between 0 and 1.9.
+ int down = int(floor(q));
+ int up = down + 1;
+ float interp = q - float(down);
+
+ outval = 1.0 - mix(val[down].x, val[up].x, interp);
+ }
+
+ gl_FragColor = vec4(vec3(outval), 1.0);
+}
diff --git a/data/shaders/shadowimportance.frag b/data/shaders/shadowimportance.frag
new file mode 100644
index 000000000..190d40418
--- /dev/null
+++ b/data/shaders/shadowimportance.frag
@@ -0,0 +1,70 @@
+uniform sampler2D ntex;
+uniform sampler2D ctex;
+uniform vec3 campos;
+uniform int low;
+
+varying vec3 wpos;
+varying vec2 texc;
+
+float luminanceImp()
+{
+ // A full-res fetch kills on low-end
+ if (low > 0) return 1.0;
+
+ const vec3 weights = vec3(0.2126, 0.7152, 0.0722); // ITU-R BT. 709
+ vec3 col = texture2D(ctex, texc).xyz;
+
+ float luma = dot(weights, col);
+
+ // Dark surfaces need less resolution
+ float f = smoothstep(0.1, 0.4, luma);
+ f = max(0.05, f);
+
+ return f;
+}
+
+float normalImp(vec3 normal)
+{
+ vec3 camdir = normalize(campos - wpos);
+ vec3 N = normalize(normal);
+
+ // Boost surfaces facing the viewer directly
+ float f = 2.0 * max(0.0, dot(N, camdir));
+
+ return f;
+}
+
+float depthImp(float linearz)
+{
+/* const float skip = 0.7;
+
+ float f = min(linearz, skip);
+ f *= 1.0/skip;*/
+
+ float z = log(1.0 + linearz * 9.0) / log(10.0);
+
+ float f = 1.0 - (z * 0.9);
+
+ return f;
+}
+
+void main()
+{
+ vec4 ntmp = texture2D(ntex, texc);
+ vec3 normal = ntmp.xyz * 2.0 - 1.0;
+ float linearz = ntmp.a;
+
+ float importance = normalImp(normal) * depthImp(linearz) * luminanceImp();
+ importance = clamp(importance, 0.0, 1.0);
+
+ float low = step(0.001, importance);
+
+ // Quantize it
+ const float steps = 16.0;
+ importance *= steps;
+ importance = ceil(importance) * low;
+ importance /= steps;
+
+ gl_FragColor = vec4(importance);
+ gl_FragDepth = 1.0 - importance;
+}
diff --git a/data/shaders/shadowimportance.vert b/data/shaders/shadowimportance.vert
new file mode 100644
index 000000000..87ab5c783
--- /dev/null
+++ b/data/shaders/shadowimportance.vert
@@ -0,0 +1,30 @@
+uniform sampler2D dtex;
+uniform mat4 ipvmat;
+uniform mat4 shadowmat;
+
+varying vec3 wpos;
+varying vec2 texc;
+
+float decdepth(vec4 rgba) {
+ return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
+}
+
+void main()
+{
+ texc = gl_Vertex.xy / vec2(32767.0);
+ float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0));
+
+ vec3 tmp = vec3(texc, z);
+ tmp = tmp * 2.0 - 1.0;
+
+ vec4 xpos = vec4(tmp, 1.0);
+ xpos = ipvmat * xpos;
+ xpos.xyz /= xpos.w;
+
+ wpos = xpos.xyz;
+
+ // Now we have this pixel's world-space position. Convert to shadow space.
+ vec4 pos = shadowmat * vec4(xpos.xyz, 1.0);
+
+ gl_Position = pos;
+}
diff --git a/data/shaders/shadowpass.frag b/data/shaders/shadowpass.frag
new file mode 100644
index 000000000..974cce97f
--- /dev/null
+++ b/data/shaders/shadowpass.frag
@@ -0,0 +1,34 @@
+uniform sampler2D tex;
+uniform int hastex;
+uniform int viz;
+uniform int wireframe;
+uniform float objectid;
+
+vec4 encdepth(float v) {
+ vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
+ enc = fract(enc);
+ enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
+ return enc;
+}
+
+void main() {
+
+ if (hastex != 0) {
+ float alpha = texture2D(tex, gl_TexCoord[0].xy).a;
+
+ if (alpha < 0.5)
+ discard;
+ }
+
+ if (viz < 1)
+ {
+ gl_FragColor = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
+ }
+ else {
+ if (wireframe > 0)
+ gl_FragColor = vec4(1.0);
+ else
+ gl_FragColor = texture2D(tex, gl_TexCoord[0].xy);
+ }
+}
+
diff --git a/data/shaders/shadowpass.vert b/data/shaders/shadowpass.vert
new file mode 100644
index 000000000..631dbb5a6
--- /dev/null
+++ b/data/shaders/shadowpass.vert
@@ -0,0 +1,25 @@
+uniform sampler2D warpx;
+uniform sampler2D warpy;
+
+float decdepth(vec4 rgba) {
+ return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
+}
+
+void main()
+{
+ vec4 pos = ftransform();
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+
+ vec2 tc = pos.xy * vec2(0.5) + vec2(0.5);
+
+ float movex = decdepth(texture2D(warpx, tc));
+ float movey = decdepth(texture2D(warpy, tc));
+
+ float dx = movex * 2.0 - 1.0;
+ float dy = movey * 2.0 - 1.0;
+
+ dx *= 2.0;
+ dy *= 2.0;
+
+ gl_Position = pos + vec4(dx, dy, vec2(0.0));
+}
diff --git a/data/shaders/shadowwarph.frag b/data/shaders/shadowwarph.frag
new file mode 100644
index 000000000..e7e9d5632
--- /dev/null
+++ b/data/shaders/shadowwarph.frag
@@ -0,0 +1,54 @@
+uniform sampler2D tex;
+uniform int size;
+uniform vec2 pixel;
+
+vec4 encdepth(float v) {
+ vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
+ enc = fract(enc);
+ enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
+ return enc;
+}
+
+void main()
+{
+ vec2 origtc = gl_TexCoord[0].xy;
+
+ // Get total sum
+ float first = 1.0, last = 0.0;
+ float lower = 0.0;
+ float total = 0.0;
+ vec2 tc = 0.5 * pixel;
+
+ for (int i = 0; i < size; i++)
+ {
+ float col = texture2D(tex, tc).x;
+
+ lower += col * step(tc.x, origtc.x);
+ total += col;
+
+ if (col > 0.0001)
+ {
+ first = min(first, tc.x);
+ last = max(last, tc.x);
+ }
+
+ tc += pixel;
+ }
+
+ float res = (lower / total) - origtc.x;
+
+ // Outside the edges?
+ if (origtc.x <= first)
+ {
+ res = origtc.x * -2.1;
+ }
+ else if (origtc.x >= last)
+ {
+ res = (1.0 - origtc.x) * 2.1;
+ }
+
+ res = res * 0.5 + 0.5;
+ res = clamp(res, 0.01, 0.99);
+
+ gl_FragColor = encdepth(res);
+}
diff --git a/data/shaders/shadowwarpv.frag b/data/shaders/shadowwarpv.frag
new file mode 100644
index 000000000..6998c61e7
--- /dev/null
+++ b/data/shaders/shadowwarpv.frag
@@ -0,0 +1,54 @@
+uniform sampler2D tex;
+uniform int size;
+uniform vec2 pixel;
+
+vec4 encdepth(float v) {
+ vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
+ enc = fract(enc);
+ enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
+ return enc;
+}
+
+void main()
+{
+ vec2 origtc = gl_TexCoord[0].xy;
+
+ // Get total sum
+ float first = 1.0, last = 0.0;
+ float lower = 0.0;
+ float total = 0.0;
+ vec2 tc = pixel * 0.5;
+
+ for (int i = 0; i < size; i++)
+ {
+ float col = texture2D(tex, tc).x;
+
+ lower += col * step(tc.y, origtc.y);
+ total += col;
+
+ if (col > 0.0001)
+ {
+ first = min(first, tc.y);
+ last = max(last, tc.y);
+ }
+
+ tc += pixel;
+ }
+
+ float res = (lower / total) - origtc.y;
+
+ // Outside the edges?
+ if (origtc.y <= first)
+ {
+ res = origtc.y * -2.1;
+ }
+ else if (origtc.y >= last)
+ {
+ res = (1.0 - origtc.y) * 2.1;
+ }
+
+ res = res * 0.5 + 0.5;
+ res = clamp(res, 0.01, 0.99);
+
+ gl_FragColor = encdepth(res);
+}
diff --git a/data/shaders/snow.frag b/data/shaders/snow.frag
new file mode 100644
index 000000000..3fddd77ec
--- /dev/null
+++ b/data/shaders/snow.frag
@@ -0,0 +1,18 @@
+uniform sampler2D tex;
+uniform float time;
+
+void main()
+{
+ vec2 change;
+ change.x = abs(sin(time * gl_Color.r));
+ change.y = abs(cos(time * gl_Color.g));
+
+ change = smoothstep(0.0, 1.0, change) * 0.5;
+
+ vec2 tc = gl_TexCoord[0].xy;
+ tc = smoothstep(0.5 - change, 0.5 + change, tc);
+
+ vec4 tcol = texture2D(tex, tc);
+
+ gl_FragColor = tcol;
+}
diff --git a/data/shaders/snow.vert b/data/shaders/snow.vert
new file mode 100644
index 000000000..b0d8dfd55
--- /dev/null
+++ b/data/shaders/snow.vert
@@ -0,0 +1,7 @@
+void main()
+{
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_Position = ftransform();
+
+ gl_FrontColor = gl_Color;
+}
diff --git a/data/shaders/splatting.frag b/data/shaders/splatting.frag
index 2fc3de57d..ac5e9f7ac 100644
--- a/data/shaders/splatting.frag
+++ b/data/shaders/splatting.frag
@@ -1,44 +1,48 @@
-// SuperTuxKart - a fun racing game with go-kart
-// Copyright (C) 2013 the SuperTuxKart team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 3
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+varying vec3 nor;
+uniform float far;
+uniform float objectid;
uniform sampler2D tex_layout;
uniform sampler2D tex_detail0;
uniform sampler2D tex_detail1;
uniform sampler2D tex_detail2;
uniform sampler2D tex_detail3;
-uniform sampler2D tex_detail4;
-varying vec3 normal;
-varying vec3 lightdir2;
-varying vec4 vertex_color;
+//uniform sampler2D tex_detail4;
-void main()
-{
- vec4 splatting = texture2D(tex_layout, gl_TexCoord[1].st);
- vec4 detail0 = texture2D(tex_detail0, gl_TexCoord[0].st);
- vec4 detail1 = texture2D(tex_detail1, gl_TexCoord[0].st);
- vec4 detail2 = texture2D(tex_detail2, gl_TexCoord[0].st);
- vec4 detail3 = texture2D(tex_detail3, gl_TexCoord[0].st);
- vec4 detail4 = texture2D(tex_detail4, gl_TexCoord[0].st);
+const float near = 1.0;
- gl_FragColor = (splatting.r * detail0 +
- splatting.g * detail1 +
- splatting.b * detail2 +
- (1.0 - splatting.r - splatting.g - splatting.b) * detail3 +
- (1.0 - splatting.a) * detail4)
- * min(1.0, 0.2 + dot(lightdir2, normal)) * vertex_color; // 0.2 is the ambient light.
+vec4 encdepth(float v) {
+ vec4 enc = vec4(1.0, 255.0, 65025.0, 16581375.0) * v;
+ enc = fract(enc);
+ enc -= enc.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);
+ return enc;
+}
+
+void main() {
+
+ float linear_z = (2.0 * near) / (far + near - gl_FragCoord.z * (far - near));
+
+ // Tune for better inside range without losing outdoors
+ linear_z *= 2.0;
+
+ // Splatting part
+ vec4 splatting = texture2D(tex_layout, gl_TexCoord[1].st);
+ vec4 detail0 = texture2D(tex_detail0, gl_TexCoord[0].st);
+ vec4 detail1 = texture2D(tex_detail1, gl_TexCoord[0].st);
+ vec4 detail2 = texture2D(tex_detail2, gl_TexCoord[0].st);
+ vec4 detail3 = texture2D(tex_detail3, gl_TexCoord[0].st);
+// vec4 detail4 = texture2D(tex_detail4, gl_TexCoord[0].st);
+ vec4 detail4 = vec4(0.0);
+
+ vec4 splatted = (splatting.r * detail0 +
+ splatting.g * detail1 +
+ splatting.b * detail2 +
+ (1.0 - splatting.r - splatting.g - splatting.b) * detail3 +
+ (1.0 - splatting.a) * detail4)
+ * gl_Color;
+
+ gl_FragData[0] = splatted;
+
+ gl_FragData[1] = vec4(nor, linear_z);
+ gl_FragData[2] = vec4(encdepth(gl_FragCoord.z).xyz, objectid);
}
diff --git a/data/shaders/ssao.frag b/data/shaders/ssao.frag
new file mode 100644
index 000000000..833364bf9
--- /dev/null
+++ b/data/shaders/ssao.frag
@@ -0,0 +1,78 @@
+#version 120
+
+uniform sampler2D tex;
+uniform sampler2D oldtex;
+
+const float totStrength = 2.38;
+const float strength = 0.07;
+const float falloff = 0.000002;
+
+#define SAMPLES 16
+
+const float invSamples = 1.0 / SAMPLES;
+
+void main(void)
+{
+ // A set of Random(tm) vec2's. 8 1s, 6 0.7s, 2 0.4
+ // Again not using const because of broken Intel Windows drivers
+ vec2 vecs[16] = vec2[](vec2(0.43589, -0.9), vec2(-0.9, 0.43589),
+ vec2(-0.8, -0.6), vec2(0.6, 0.8),
+ vec2(0.866025, -0.5), vec2(-0.5, 0.866025),
+ vec2(-0.3, -0.953939), vec2(0.953939, 0.3),
+ vec2(0.3, -0.781025), vec2(-0.781025, 0.3),
+ vec2(-0.56, -0.621611), vec2(0.621611, 0.56),
+ vec2(0.734847, -0.4), vec2(-0.4, 0.734847),
+ vec2(-0.2, -0.6), vec2(0.6, 0.2));
+
+ vec2 uv = gl_TexCoord[0].xy;
+
+ vec4 cur = texture2D(tex, uv);
+ float curdepth = cur.a;
+
+ // Will we skip this pixel? (if it's the sky)
+ float len = dot(vec3(1.0), abs(cur.xyz));
+ if (len < 0.2 || curdepth > 0.8) discard;
+
+ float mytotstrength = 3.0 * totStrength * curdepth * (1.0 - curdepth);
+
+ // get the normal of current fragment
+ vec3 norm = normalize(cur.xyz * vec3(2.0) - vec3(1.0));
+
+ float bl = 0.0;
+
+ // adjust for the depth, 0.1 close, 0.01 far
+ float radD = 0.10 - 0.09 * smoothstep(0.0, 0.2, curdepth);
+
+ for(int i = 0; i < SAMPLES; ++i) {
+
+ vec2 ray = uv + radD * vecs[i];
+
+ // get the depth of the occluder fragment
+ vec4 occluderFragment = texture2D(tex, ray);
+ float normAcceptable = step(0.2, dot(vec3(1.0), abs(occluderFragment.xyz)));
+
+ // get the normal of the occluder fragment
+ vec3 occNorm = normalize(occluderFragment.xyz * vec3(2.0) - vec3(1.0));
+
+ // if depthDifference is negative = occluder is behind current fragment
+ float depthDifference = curdepth - occluderFragment.a;
+
+ // calculate the difference between the normals as a weight
+ float normDiff = 1.0 - max(dot(occNorm, norm), 0.0);
+ normDiff = smoothstep(0.1, 0.3, normDiff);
+
+ // the falloff equation, starts at falloff and is kind of 1/x^2 falling
+ bl += step(falloff, depthDifference) * normDiff * normAcceptable *
+ (1.0 - smoothstep(falloff, strength, depthDifference));
+ }
+
+ // output the result
+ float ao = 1.0 - mytotstrength * bl * invSamples;
+
+ // Mix with old result to avoid flicker
+ float oldao = texture2D(oldtex, uv).x;
+
+ ao = mix(ao, oldao, 0.3);
+
+ gl_FragColor = vec4(vec3(ao), curdepth);
+}
diff --git a/data/shaders/sunlight.frag b/data/shaders/sunlight.frag
new file mode 100644
index 000000000..1553bfc0c
--- /dev/null
+++ b/data/shaders/sunlight.frag
@@ -0,0 +1,58 @@
+uniform sampler2D ntex;
+uniform sampler2D dtex;
+uniform sampler2D cloudtex;
+
+uniform vec3 center;
+uniform vec3 col;
+uniform vec2 screen;
+uniform mat4 invprojview;
+uniform int hasclouds;
+uniform vec2 wind;
+
+float decdepth(vec4 rgba) {
+ return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
+}
+
+void main() {
+
+ vec2 texc = gl_FragCoord.xy / screen;
+ float z = decdepth(vec4(texture2D(dtex, texc).xyz, 0.0));
+
+ if (z < 0.03)
+ {
+ // Skyboxes are fully lit
+ gl_FragData[0] = vec4(1.0);
+ gl_FragData[1] = vec4(1.0);
+ return;
+ }
+
+ vec3 norm = texture2D(ntex, texc).xyz;
+ norm = (norm - 0.5) * 2.0;
+
+ // Normalized on the cpu
+ vec3 L = center;
+
+ float NdotL = max(0.0, dot(norm, L));
+ if (NdotL < 0.01) discard;
+
+ vec3 outcol = NdotL * col;
+
+ if (hasclouds == 1)
+ {
+ vec3 tmp = vec3(texc, z);
+ tmp = tmp * 2.0 - 1.0;
+
+ vec4 xpos = vec4(tmp, 1.0);
+ xpos = invprojview * xpos;
+ xpos.xyz /= xpos.w;
+
+ vec2 cloudcoord = (xpos.xz * 0.00833333) + wind;
+ float cloud = texture2D(cloudtex, cloudcoord).x;
+ //float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y);
+
+ outcol *= cloud;
+ }
+
+ gl_FragData[0] = vec4(outcol, 0.05);
+ gl_FragData[1] = vec4(1.0);
+}
diff --git a/data/shaders/sunlightshadow.frag b/data/shaders/sunlightshadow.frag
new file mode 100644
index 000000000..89bc576f9
--- /dev/null
+++ b/data/shaders/sunlightshadow.frag
@@ -0,0 +1,106 @@
+uniform sampler2D ntex;
+uniform sampler2D dtex;
+uniform sampler2D cloudtex;
+uniform sampler2D shadowtex;
+uniform sampler2D warpx;
+uniform sampler2D warpy;
+
+uniform vec3 center;
+uniform vec3 col;
+uniform vec2 screen;
+uniform mat4 invprojview;
+uniform mat4 shadowmat;
+uniform int hasclouds;
+uniform vec2 wind;
+uniform float shadowoffset;
+
+float decdepth(vec4 rgba) {
+ return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
+}
+
+void main() {
+
+ vec2 texc = gl_FragCoord.xy / screen;
+ vec4 depthread = texture2D(dtex, texc);
+ float z = decdepth(vec4(depthread.xyz, 0.0));
+
+ if (z < 0.03)
+ {
+ // Skyboxes are fully lit
+ gl_FragData[0] = vec4(1.0);
+ gl_FragData[1] = vec4(0.0);
+ return;
+ }
+
+ vec3 norm = texture2D(ntex, texc).xyz;
+ norm = (norm - 0.5) * 2.0;
+
+ // Normalized on the cpu
+ vec3 L = center;
+
+ float NdotL = max(0.0, dot(norm, L));
+ if (NdotL < 0.01) discard;
+
+ vec3 outcol = NdotL * col;
+
+ // World-space position
+ vec3 tmp = vec3(texc, z);
+ tmp = tmp * 2.0 - 1.0;
+
+ vec4 xpos = vec4(tmp, 1.0);
+ xpos = invprojview * xpos;
+ xpos.xyz /= xpos.w;
+
+ if (hasclouds == 1)
+ {
+ vec2 cloudcoord = (xpos.xz * 0.00833333) + wind;
+ float cloud = texture2D(cloudtex, cloudcoord).x;
+ //float cloud = step(0.5, cloudcoord.x) * step(0.5, cloudcoord.y);
+
+ outcol *= cloud;
+ }
+
+ // Shadows
+ vec3 shadowcoord = (shadowmat * vec4(xpos.xyz, 1.0)).xyz;
+ shadowcoord = (shadowcoord * 0.5) + vec3(0.5);
+
+ float movex = decdepth(texture2D(warpx, shadowcoord.xy));
+ float movey = decdepth(texture2D(warpy, shadowcoord.xy));
+ float dx = movex * 2.0 - 1.0;
+ float dy = movey * 2.0 - 1.0;
+ shadowcoord.xy += vec2(dx, dy);
+
+ vec4 shadowread = texture2D(shadowtex, shadowcoord.xy);
+ float shadowmapz = decdepth(vec4(shadowread.xyz, 0.0));
+
+ float moved = (abs(dx) + abs(dy)) * 0.5;
+
+ float bias = 0.002 * tan(acos(NdotL)); // According to the slope
+ bias += smoothstep(0.001, 0.1, moved) * 0.014; // According to the warping
+ bias = clamp(bias, 0.001, 0.014);
+
+ // This ID, and four IDs around this must match for a shadow pixel
+ float right = texture2D(shadowtex, shadowcoord.xy + vec2(shadowoffset, 0.0)).a;
+ float left = texture2D(shadowtex, shadowcoord.xy + vec2(-shadowoffset, 0.0)).a;
+ float up = texture2D(shadowtex, shadowcoord.xy + vec2(0.0, shadowoffset)).a;
+ float down = texture2D(shadowtex, shadowcoord.xy + vec2(0.0, -shadowoffset)).a;
+
+ float matching = ((right + left + up + down) * 0.25) - shadowread.a;
+ matching = abs(matching) * 400.0;
+
+ // If the ID is different, we're likely in shadow - cut the bias to cut peter panning
+ float off = 7.0 - step(abs(shadowread.a - depthread.a) - matching, 0.004) * 6.0;
+ bias /= off;
+
+ const float softness = 8.0; // How soft is the light?
+ float shadowed = step(shadowmapz + bias, shadowcoord.z);
+ float dist = (shadowcoord.z / shadowmapz) - 1.0;
+ float penumbra = dist * softness / gl_FragCoord.z;
+ penumbra *= shadowed;
+
+/* outcol.r = (shadowcoord.z - shadowmapz) * 50.0;
+ outcol.g = moved;*/
+
+ gl_FragData[0] = vec4(outcol, 0.05);
+ gl_FragData[1] = vec4(shadowed, penumbra, shadowed, shadowed);
+}
diff --git a/data/shaders/water.frag b/data/shaders/water.frag
index 70899ea2e..3f36b8b72 100644
--- a/data/shaders/water.frag
+++ b/data/shaders/water.frag
@@ -16,11 +16,11 @@ void main()
{
// lookup normal from normal map, move from [0,1] to [-1, 1] range, normalize
vec3 normal = 2.0 * texture2D (BumpTex1, gl_TexCoord[0].st + delta1).rgb - 1.0;
- vec3 normal2 = 2.0 * texture2D (BumpTex2, gl_TexCoord[0].st + delta2).rgb - 1.0;
+ vec3 normal2 = 2.0 * texture2D (BumpTex2, gl_TexCoord[0].st + delta2).rgb - 1.0;
- // scale normals
- normal.y = 4.0*normal.y;
- normal2.y = 4.0*normal2.y;
+ // scale normals
+ normal.y = 4.0*normal.y;
+ normal2.y = 4.0*normal2.y;
normal = (normalize(normal) + normalize(normal2))/2.0;
@@ -29,31 +29,28 @@ void main()
vec4 diffuseMaterial;
vec4 diffuseLight;
- diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st + vec2(delta1.x, 0.0));
- diffuseLight = vec4(1.0, 1.0, 1.0, 1.0);
+ diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st + vec2(delta1.x, 0.0));
+ diffuseLight = vec4(1.0, 1.0, 1.0, 1.0);
- //if (lamberFactor < 0.7)
- //{
- // lamberFactor = 0.0;
- //}
+ vec3 col = diffuseMaterial.xyz * (0.3 + lamberFactor*0.7);
- gl_FragColor = diffuseMaterial * (0.3 + lamberFactor*0.7);
+ // specular (phong)
+ vec3 R = normalize(reflect(lightVec, normal));
+ float specular = max(dot(R, eyeVec), 0.0);
- // specular (phong)
- vec3 R = normalize(reflect(lightVec, normal));
- float specular = max(dot(R,eyeVec),0.0);
+ // weak specular
+ specular = specular*specular;
+ specular = specular*specular;
+ float specular_weak = specular*0.05;
+ col += vec3(specular_weak, specular_weak, specular_weak);
- if (specular > 0.0)
- {
- // weak specular
- specular = specular*specular;
- specular = specular*specular;
- float specular_weak = specular*0.05;
- gl_FragColor += vec4(specular_weak, specular_weak, specular_weak, 0.0);
+ // strong specular
+ specular = specular*specular;
+ float specular_strong = specular*0.3;
+ col += vec3(specular_strong, specular_strong, specular_strong);
- // strong specular
- specular = specular*specular;
- float specular_strong = specular*0.3;
- gl_FragColor += vec4(specular_strong, specular_strong, specular_strong, 0.0);
- }
+ float summed = dot(vec3(1.0), col) / 3.0;
+ float alpha = 0.9 + 0.1 * smoothstep(0.0, 1.0, summed);
+
+ gl_FragColor = vec4(col, alpha);
}
diff --git a/data/shaders/water.vert b/data/shaders/water.vert
index 9b88f362d..5a58fda94 100644
--- a/data/shaders/water.vert
+++ b/data/shaders/water.vert
@@ -1,25 +1,30 @@
// Shader based on work by Fabien Sanglard
// Released under the terms of CC-BY 3.0
+uniform float speed;
+uniform float height;
+uniform float length;
+
+uniform vec3 lightdir;
+
varying vec3 lightVec;
varying vec3 halfVec;
varying vec3 eyeVec;
-uniform vec3 lightdir;
-
void main()
{
+ vec4 pos = gl_Vertex;
- gl_TexCoord[0] = gl_MultiTexCoord0;
+ pos.y += (sin(pos.x/length + speed) + cos(pos.z/length + speed)) * height;
+
+ vec3 vertexPosition = vec3(gl_ModelViewMatrix * pos);
// Building the matrix Eye Space -> Tangent Space
vec3 n = normalize (gl_NormalMatrix * gl_Normal);
- // gl_MultiTexCoord1.xyz
+ // gl_MultiTexCoord1.xyz
vec3 t = normalize (gl_NormalMatrix * vec3(1.0, 0.0, 0.0)); // tangent
vec3 b = cross (n, t);
- vec3 vertexPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
-
// transform light and half angle vectors by tangent basis
vec3 v;
v.x = dot (lightdir, t);
@@ -29,7 +34,7 @@ void main()
vertexPosition = normalize(vertexPosition);
- eyeVec = normalize(-vertexPosition); // we are in Eye Coordinates, so EyePos is (0,0,0)
+ eyeVec = normalize(-vertexPosition); // we are in Eye Coordinates, so EyePos is (0,0,0)
// Normalize the halfVector to pass it to the fragment shader
@@ -44,5 +49,7 @@ void main()
//normalize (v);
halfVec = v ;
- gl_Position = ftransform();
-}
\ No newline at end of file
+ gl_Position = gl_ModelViewProjectionMatrix * pos;
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[1] = gl_MultiTexCoord1;
+}
diff --git a/data/shaders/water_fog.frag b/data/shaders/water_fog.frag
deleted file mode 100644
index 63a8f5a70..000000000
--- a/data/shaders/water_fog.frag
+++ /dev/null
@@ -1,75 +0,0 @@
-// Shader based on work by Fabien Sanglard
-// Released under the terms of CC-BY 3.0
-
-uniform sampler2D BumpTex1; // Normal map 1
-uniform sampler2D BumpTex2; // Normal map 2
-uniform sampler2D DecalTex; //The texture
-
-uniform vec2 delta1;
-uniform vec2 delta2;
-
-varying vec3 lightVec;
-varying vec3 halfVec;
-varying vec3 eyeVec;
-varying vec4 coord;
-
-uniform vec4 fogColor;
-uniform float fogFrom;
-uniform float fogTo;
-
-void main()
-{
- // lookup normal from normal map, move from [0,1] to [-1, 1] range, normalize
- vec3 normal = 2.0 * texture2D (BumpTex1, gl_TexCoord[0].st + delta1).rgb - 1.0;
- vec3 normal2 = 2.0 * texture2D (BumpTex2, gl_TexCoord[0].st + delta2).rgb - 1.0;
-
- // scale normals
- normal.y = 4.0*normal.y;
- normal2.y = 4.0*normal2.y;
-
- normal = (normalize(normal) + normalize(normal2))/2.0;
-
- // compute diffuse lighting
- float lamberFactor = max (dot (lightVec, normal), 0.0);
- vec4 diffuseMaterial;
- vec4 diffuseLight;
-
- diffuseMaterial = texture2D (DecalTex, gl_TexCoord[0].st + vec2(delta1.x, 0.0));
- diffuseLight = vec4(1.0, 1.0, 1.0, 1.0);
-
- //if (lamberFactor < 0.7)
- //{
- // lamberFactor = 0.0;
- //}
-
- gl_FragColor = diffuseMaterial * (0.3 + lamberFactor*0.7);
-
- // specular (phong)
- vec3 R = normalize(reflect(lightVec, normal));
- float specular = max(dot(R,eyeVec),0.0);
-
- if (specular > 0.0)
- {
- // weak specular
- specular = specular*specular;
- specular = specular*specular;
- float specular_weak = specular*0.05;
- gl_FragColor += vec4(specular_weak, specular_weak, specular_weak, 0.0);
-
- // strong specular
- specular = specular*specular;
- float specular_strong = specular*0.3;
- gl_FragColor += vec4(specular_strong, specular_strong, specular_strong, 0.0);
- }
-
- if (coord.z > fogTo)
- {
- gl_FragColor = fogColor;
- }
- else if (coord.z > fogFrom)
- {
- float fogIntensity = (coord.z - fogFrom) / (fogTo - fogFrom);
- gl_FragColor = fogIntensity*fogColor + (1.0 - fogIntensity)*gl_FragColor;
- }
-}
-
diff --git a/data/shaders/water_fog.vert b/data/shaders/water_fog.vert
deleted file mode 100644
index 4419ca428..000000000
--- a/data/shaders/water_fog.vert
+++ /dev/null
@@ -1,49 +0,0 @@
-// Shader based on work by Fabien Sanglard
-// Released under the terms of CC-BY 3.0
-
-varying vec3 lightVec;
-varying vec3 halfVec;
-varying vec3 eyeVec;
-varying vec4 coord;
-uniform vec3 lightdir;
-
-void main()
-{
-
- gl_TexCoord[0] = gl_MultiTexCoord0;
-
- // Building the matrix Eye Space -> Tangent Space
- vec3 n = normalize (gl_NormalMatrix * gl_Normal);
- // gl_MultiTexCoord1.xyz
- vec3 t = normalize (gl_NormalMatrix * vec3(1.0, 0.0, 0.0)); // tangent
- vec3 b = cross (n, t);
-
- vec3 vertexPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
-
- // transform light and half angle vectors by tangent basis
- vec3 v;
- v.x = dot (lightdir, t);
- v.y = dot (lightdir, b);
- v.z = dot (lightdir, n);
- lightVec = normalize (v);
-
- vertexPosition = normalize(vertexPosition);
-
- eyeVec = normalize(-vertexPosition); // we are in Eye Coordinates, so EyePos is (0,0,0)
-
- // Normalize the halfVector to pass it to the fragment shader
-
- // No need to divide by two, the result is normalized anyway.
- // vec3 halfVector = normalize((vertexPosition + lightDir) / 2.0);
- vec3 halfVector = normalize(vertexPosition + lightdir);
- v.x = dot (halfVector, t);
- v.y = dot (halfVector, b);
- v.z = dot (halfVector, n);
-
- // No need to normalize, t,b,n and halfVector are normal vectors.
- //normalize (v);
- halfVec = v ;
-
- gl_Position = ftransform();
- coord = gl_Position;
-}
diff --git a/data/shaders/white.frag b/data/shaders/white.frag
new file mode 100644
index 000000000..1cc07d303
--- /dev/null
+++ b/data/shaders/white.frag
@@ -0,0 +1,4 @@
+void main()
+{
+ gl_FragColor = vec4(1.0);
+}
diff --git a/data/stk_config.xml b/data/stk_config.xml
index 18d1cb51c..5bed7c8eb 100644
--- a/data/stk_config.xml
+++ b/data/stk_config.xml
@@ -135,6 +135,9 @@
+
+
+
diff --git a/doc/graphics_views.txt b/doc/graphics_views.txt
new file mode 100644
index 000000000..d96268a6e
--- /dev/null
+++ b/doc/graphics_views.txt
@@ -0,0 +1,21 @@
+Graphics debug views
+====================
+
+There are some graphics debug views, to be used both by artists when developing,
+and by users when reporting bugs.
+
+These should be available in normal (non-artist) mode
+to enable easier bug reports (go there, press this key, screenshot)
+without requiring editing the UTF-32 config files (which is inconvenient, most editors
+do not support that weird encoding).
+
+They don't give gameplay advantages like the item keys, so there should be little harm
+leaving them available. Accidental keypresses ought to be minimized by their location.
+
+Home - wireframe view
+End - mipmap visualization (is a texture too high or low resolution, red = too high)
+Del - normal view
+PgDown - SSAO view
+PgUp - light view
+Ins - shadow view
+ScrlLock - displacement view
diff --git a/doc/graphics_xml.txt b/doc/graphics_xml.txt
new file mode 100644
index 000000000..ba9062611
--- /dev/null
+++ b/doc/graphics_xml.txt
@@ -0,0 +1,157 @@
+Graphics GSOC XML additions
+===========================
+
+This document will list in depth all new XML values added during the graphics GSOC, for use
+by the blender exporter scripts.
+
+Glow colors
+-----------
+
+The glow colors for nitro bottles and boxes are settable in stk_config.xml.
+They are three-value RGB colors.
+
+Example:
+
+
+Particle wind
+-------------
+
+Particles may be affected by wind. This is used with the snow particles.
+
+Flips is a boolean controlling whether each particle will spin about its own two axis.
+It is only applicable to symmetric textures, such as snow flakes.
+
+Speed is a float in no real units.
+
+Example:
+
+
+Forced bloom objects
+--------------------
+
+Any object may be marked as forced bloom. This will include the object in the bloom pass
+regardless of its brightness.
+
+Example: forcedbloom="Y" inside the