summaryrefslogtreecommitdiff
path: root/src/renderergl2/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderergl2/glsl')
-rw-r--r--src/renderergl2/glsl/bokeh_fp.glsl70
-rw-r--r--src/renderergl2/glsl/bokeh_vp.glsl13
-rw-r--r--src/renderergl2/glsl/calclevels4x_fp.glsl60
-rw-r--r--src/renderergl2/glsl/calclevels4x_vp.glsl13
-rw-r--r--src/renderergl2/glsl/depthblur_fp.glsl82
-rw-r--r--src/renderergl2/glsl/depthblur_vp.glsl16
-rw-r--r--src/renderergl2/glsl/dlight_fp.glsl32
-rw-r--r--src/renderergl2/glsl/dlight_vp.glsl92
-rw-r--r--src/renderergl2/glsl/down4x_fp.glsl34
-rw-r--r--src/renderergl2/glsl/down4x_vp.glsl13
-rw-r--r--src/renderergl2/glsl/fogpass_fp.glsl9
-rw-r--r--src/renderergl2/glsl/fogpass_vp.glsl117
-rw-r--r--src/renderergl2/glsl/generic_fp.glsl33
-rw-r--r--src/renderergl2/glsl/generic_vp.glsl239
-rw-r--r--src/renderergl2/glsl/lightall_fp.glsl429
-rw-r--r--src/renderergl2/glsl/lightall_vp.glsl246
-rw-r--r--src/renderergl2/glsl/pshadow_fp.glsl78
-rw-r--r--src/renderergl2/glsl/pshadow_vp.glsl15
-rw-r--r--src/renderergl2/glsl/shadowfill_fp.glsl41
-rw-r--r--src/renderergl2/glsl/shadowfill_vp.glsl89
-rw-r--r--src/renderergl2/glsl/shadowmask_fp.glsl143
-rw-r--r--src/renderergl2/glsl/shadowmask_vp.glsl18
-rw-r--r--src/renderergl2/glsl/ssao_fp.glsl86
-rw-r--r--src/renderergl2/glsl/ssao_vp.glsl12
-rw-r--r--src/renderergl2/glsl/texturecolor_fp.glsl10
-rw-r--r--src/renderergl2/glsl/texturecolor_vp.glsl13
-rw-r--r--src/renderergl2/glsl/tonemap_fp.glsl57
-rw-r--r--src/renderergl2/glsl/tonemap_vp.glsl27
28 files changed, 2087 insertions, 0 deletions
diff --git a/src/renderergl2/glsl/bokeh_fp.glsl b/src/renderergl2/glsl/bokeh_fp.glsl
new file mode 100644
index 0000000..d08816a
--- /dev/null
+++ b/src/renderergl2/glsl/bokeh_fp.glsl
@@ -0,0 +1,70 @@
+uniform sampler2D u_TextureMap;
+
+uniform vec4 u_Color;
+
+uniform vec2 u_InvTexRes;
+varying vec2 var_TexCoords;
+
+void main()
+{
+ vec4 color;
+ vec2 tc;
+
+#if 0
+ float c[7] = float[7](1.0, 0.9659258263, 0.8660254038, 0.7071067812, 0.5, 0.2588190451, 0.0);
+
+ tc = var_TexCoords + u_InvTexRes * vec2( c[0], c[6]); color = texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[1], c[5]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[2], c[4]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[3], c[3]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[4], c[2]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[5], c[1]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[6], c[0]); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2( c[1], -c[5]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[2], -c[4]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[3], -c[3]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[4], -c[2]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[5], -c[1]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[6], -c[0]); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[0], c[6]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[1], c[5]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[2], c[4]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[3], c[3]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[4], c[2]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[5], c[1]); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[1], -c[5]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[2], -c[4]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[3], -c[3]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[4], -c[2]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[5], -c[1]); color += texture2D(u_TextureMap, tc);
+
+ gl_FragColor = color * 0.04166667 * u_Color;
+#endif
+
+ float c[5] = float[5](1.0, 0.9238795325, 0.7071067812, 0.3826834324, 0.0);
+
+ tc = var_TexCoords + u_InvTexRes * vec2( c[0], c[4]); color = texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[1], c[3]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[2], c[2]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[3], c[1]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[4], c[0]); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2( c[1], -c[3]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[2], -c[2]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[3], -c[1]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( c[4], -c[0]); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[0], c[4]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[1], c[3]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[2], c[2]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[3], c[1]); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[1], -c[3]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[2], -c[2]); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( -c[3], -c[1]); color += texture2D(u_TextureMap, tc);
+
+ gl_FragColor = color * 0.0625 * u_Color;
+}
diff --git a/src/renderergl2/glsl/bokeh_vp.glsl b/src/renderergl2/glsl/bokeh_vp.glsl
new file mode 100644
index 0000000..bdaa74a
--- /dev/null
+++ b/src/renderergl2/glsl/bokeh_vp.glsl
@@ -0,0 +1,13 @@
+attribute vec3 attr_Position;
+attribute vec4 attr_TexCoord0;
+
+uniform mat4 u_ModelViewProjectionMatrix;
+
+varying vec2 var_TexCoords;
+
+
+void main()
+{
+ gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
+ var_TexCoords = attr_TexCoord0.st;
+}
diff --git a/src/renderergl2/glsl/calclevels4x_fp.glsl b/src/renderergl2/glsl/calclevels4x_fp.glsl
new file mode 100644
index 0000000..8246c4b
--- /dev/null
+++ b/src/renderergl2/glsl/calclevels4x_fp.glsl
@@ -0,0 +1,60 @@
+uniform sampler2D u_TextureMap;
+
+uniform vec4 u_Color;
+
+uniform vec2 u_InvTexRes;
+varying vec2 var_TexCoords;
+
+const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721); //vec3(0.299, 0.587, 0.114);
+
+vec3 GetValues(vec2 offset, vec3 current)
+{
+ vec2 tc = var_TexCoords + u_InvTexRes * offset;
+ vec3 minAvgMax = texture2D(u_TextureMap, tc).rgb;
+
+#ifdef FIRST_PASS
+
+ #if defined(USE_PBR)
+ minAvgMax *= minAvgMax;
+ #endif
+
+ float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001);
+ float loglumi = clamp(log2(lumi), -10.0, 10.0);
+ minAvgMax = vec3(loglumi * 0.05 + 0.5);
+#endif
+
+ return vec3(min(current.x, minAvgMax.x), current.y + minAvgMax.y, max(current.z, minAvgMax.z));
+}
+
+void main()
+{
+ vec3 current = vec3(1.0, 0.0, 0.0);
+
+#ifdef FIRST_PASS
+ current = GetValues(vec2( 0.0, 0.0), current);
+#else
+ current = GetValues(vec2(-1.5, -1.5), current);
+ current = GetValues(vec2(-0.5, -1.5), current);
+ current = GetValues(vec2( 0.5, -1.5), current);
+ current = GetValues(vec2( 1.5, -1.5), current);
+
+ current = GetValues(vec2(-1.5, -0.5), current);
+ current = GetValues(vec2(-0.5, -0.5), current);
+ current = GetValues(vec2( 0.5, -0.5), current);
+ current = GetValues(vec2( 1.5, -0.5), current);
+
+ current = GetValues(vec2(-1.5, 0.5), current);
+ current = GetValues(vec2(-0.5, 0.5), current);
+ current = GetValues(vec2( 0.5, 0.5), current);
+ current = GetValues(vec2( 1.5, 0.5), current);
+
+ current = GetValues(vec2(-1.5, 1.5), current);
+ current = GetValues(vec2(-0.5, 1.5), current);
+ current = GetValues(vec2( 0.5, 1.5), current);
+ current = GetValues(vec2( 1.5, 1.5), current);
+
+ current.y *= 0.0625;
+#endif
+
+ gl_FragColor = vec4(current, 1.0f);
+}
diff --git a/src/renderergl2/glsl/calclevels4x_vp.glsl b/src/renderergl2/glsl/calclevels4x_vp.glsl
new file mode 100644
index 0000000..bdaa74a
--- /dev/null
+++ b/src/renderergl2/glsl/calclevels4x_vp.glsl
@@ -0,0 +1,13 @@
+attribute vec3 attr_Position;
+attribute vec4 attr_TexCoord0;
+
+uniform mat4 u_ModelViewProjectionMatrix;
+
+varying vec2 var_TexCoords;
+
+
+void main()
+{
+ gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
+ var_TexCoords = attr_TexCoord0.st;
+}
diff --git a/src/renderergl2/glsl/depthblur_fp.glsl b/src/renderergl2/glsl/depthblur_fp.glsl
new file mode 100644
index 0000000..d71b348
--- /dev/null
+++ b/src/renderergl2/glsl/depthblur_fp.glsl
@@ -0,0 +1,82 @@
+uniform sampler2D u_ScreenImageMap;
+uniform sampler2D u_ScreenDepthMap;
+
+uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
+varying vec2 var_ScreenTex;
+
+//float gauss[8] = float[8](0.17, 0.17, 0.16, 0.14, 0.12, 0.1, 0.08, 0.06);
+//float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033);
+float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044);
+//float gauss[3] = float[3](0.60, 0.19, 0.0066);
+#define BLUR_SIZE 4
+
+#if !defined(USE_DEPTH)
+//#define USE_GAUSS
+#endif
+
+float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
+{
+ float sampleZDivW = texture2D(depthMap, tex).r;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+}
+
+vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale)
+{
+
+#if defined(USE_DEPTH)
+ float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear);
+ vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y));
+ scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0);
+#endif
+
+#if defined(USE_HORIZONTAL_BLUR)
+ vec2 direction = vec2(scale.x * 2.0, 0.0);
+ vec2 nudge = vec2(0.0, scale.y * 0.5);
+#else // if defined(USE_VERTICAL_BLUR)
+ vec2 direction = vec2(0.0, scale.y * 2.0);
+ vec2 nudge = vec2(-scale.x * 0.5, 0.0);
+#endif
+
+#if defined(USE_GAUSS)
+ vec4 result = texture2D(imageMap, tex) * gauss[0];
+ float total = gauss[0];
+#else
+ vec4 result = texture2D(imageMap, tex);
+ float total = 1.0;
+#endif
+
+ float zLimit = 5.0 / zFar;
+ int i, j;
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 1; j < BLUR_SIZE; j++)
+ {
+ vec2 offset = direction * (float(j) - 0.25) + nudge;
+#if defined(USE_DEPTH)
+ float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear);
+ float depthExpected = depthCenter + dot(slope, offset);
+ float useSample = float(abs(depthSample - depthExpected) < zLimit);
+#else
+ float useSample = 1.0;
+#endif
+#if defined(USE_GAUSS)
+ result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample);
+ total += gauss[j] * useSample;
+#else
+ result += texture2D(imageMap, tex + offset) * useSample;
+ total += useSample;
+#endif
+ nudge = -nudge;
+ }
+
+ direction = -direction;
+ nudge = -nudge;
+ }
+
+ return result / total;
+}
+
+void main()
+{
+ gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw);
+}
diff --git a/src/renderergl2/glsl/depthblur_vp.glsl b/src/renderergl2/glsl/depthblur_vp.glsl
new file mode 100644
index 0000000..9c47660
--- /dev/null
+++ b/src/renderergl2/glsl/depthblur_vp.glsl
@@ -0,0 +1,16 @@
+attribute vec4 attr_Position;
+attribute vec4 attr_TexCoord0;
+
+uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
+
+varying vec2 var_ScreenTex;
+
+void main()
+{
+ gl_Position = attr_Position;
+ vec2 wh = vec2(1.0) / u_ViewInfo.zw - vec2(1.0);
+ var_ScreenTex = (floor(attr_TexCoord0.xy * wh) + vec2(0.5)) * u_ViewInfo.zw;
+
+ //vec2 screenCoords = gl_Position.xy / gl_Position.w;
+ //var_ScreenTex = screenCoords * 0.5 + 0.5;
+}
diff --git a/src/renderergl2/glsl/dlight_fp.glsl b/src/renderergl2/glsl/dlight_fp.glsl
new file mode 100644
index 0000000..41be049
--- /dev/null
+++ b/src/renderergl2/glsl/dlight_fp.glsl
@@ -0,0 +1,32 @@
+uniform sampler2D u_DiffuseMap;
+
+uniform int u_AlphaTest;
+
+varying vec2 var_Tex1;
+varying vec4 var_Color;
+
+
+void main()
+{
+ vec4 color = texture2D(u_DiffuseMap, var_Tex1);
+
+ float alpha = color.a * var_Color.a;
+ if (u_AlphaTest == 1)
+ {
+ if (alpha == 0.0)
+ discard;
+ }
+ else if (u_AlphaTest == 2)
+ {
+ if (alpha >= 0.5)
+ discard;
+ }
+ else if (u_AlphaTest == 3)
+ {
+ if (alpha < 0.5)
+ discard;
+ }
+
+ gl_FragColor.rgb = color.rgb * var_Color.rgb;
+ gl_FragColor.a = alpha;
+}
diff --git a/src/renderergl2/glsl/dlight_vp.glsl b/src/renderergl2/glsl/dlight_vp.glsl
new file mode 100644
index 0000000..c326bd7
--- /dev/null
+++ b/src/renderergl2/glsl/dlight_vp.glsl
@@ -0,0 +1,92 @@
+attribute vec3 attr_Position;
+attribute vec4 attr_TexCoord0;
+attribute vec3 attr_Normal;
+
+uniform vec4 u_DlightInfo;
+
+#if defined(USE_DEFORM_VERTEXES)
+uniform int u_DeformGen;
+uniform float u_DeformParams[5];
+uniform float u_Time;
+#endif
+
+uniform vec4 u_Color;
+uniform mat4 u_ModelViewProjectionMatrix;
+
+varying vec2 var_Tex1;
+varying vec4 var_Color;
+
+#if defined(USE_DEFORM_VERTEXES)
+vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
+{
+ if (u_DeformGen == 0)
+ {
+ return pos;
+ }
+
+ float base = u_DeformParams[0];
+ float amplitude = u_DeformParams[1];
+ float phase = u_DeformParams[2];
+ float frequency = u_DeformParams[3];
+ float spread = u_DeformParams[4];
+
+ if (u_DeformGen == DGEN_BULGE)
+ {
+ phase *= st.x;
+ }
+ else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
+ {
+ phase += dot(pos.xyz, vec3(spread));
+ }
+
+ float value = phase + (u_Time * frequency);
+ float func;
+
+ if (u_DeformGen == DGEN_WAVE_SIN)
+ {
+ func = sin(value * 2.0 * M_PI);
+ }
+ else if (u_DeformGen == DGEN_WAVE_SQUARE)
+ {
+ func = sign(0.5 - fract(value));
+ }
+ else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
+ {
+ func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
+ }
+ else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
+ {
+ func = fract(value);
+ }
+ else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)
+ {
+ func = (1.0 - fract(value));
+ }
+ else // if (u_DeformGen == DGEN_BULGE)
+ {
+ func = sin(value);
+ }
+
+ return pos + normal * (base + func * amplitude);
+}
+#endif
+
+void main()
+{
+ vec3 position = attr_Position;
+ vec3 normal = attr_Normal;
+
+#if defined(USE_DEFORM_VERTEXES)
+ position = DeformPosition(position, normal, attr_TexCoord0.st);
+#endif
+
+ gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
+
+ vec3 dist = u_DlightInfo.xyz - position;
+
+ var_Tex1 = dist.xy * u_DlightInfo.a + vec2(0.5);
+ float dlightmod = step(0.0, dot(dist, normal));
+ dlightmod *= clamp(2.0 * (1.0 - abs(dist.z) * u_DlightInfo.a), 0.0, 1.0);
+
+ var_Color = u_Color * dlightmod;
+}
diff --git a/src/renderergl2/glsl/down4x_fp.glsl b/src/renderergl2/glsl/down4x_fp.glsl
new file mode 100644
index 0000000..0f88fb2
--- /dev/null
+++ b/src/renderergl2/glsl/down4x_fp.glsl
@@ -0,0 +1,34 @@
+uniform sampler2D u_TextureMap;
+
+uniform vec2 u_InvTexRes;
+varying vec2 var_TexCoords;
+
+void main()
+{
+ vec4 color;
+ vec2 tc;
+
+ tc = var_TexCoords + u_InvTexRes * vec2(-1.5, -1.5); color = texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2(-0.5, -1.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( 0.5, -1.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( 1.5, -1.5); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2(-1.5, -0.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2(-0.5, -0.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( 0.5, -0.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( 1.5, -0.5); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2(-1.5, 0.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2(-0.5, 0.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( 0.5, 0.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( 1.5, 0.5); color += texture2D(u_TextureMap, tc);
+
+ tc = var_TexCoords + u_InvTexRes * vec2(-1.5, 1.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2(-0.5, 1.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( 0.5, 1.5); color += texture2D(u_TextureMap, tc);
+ tc = var_TexCoords + u_InvTexRes * vec2( 1.5, 1.5); color += texture2D(u_TextureMap, tc);
+
+ color *= 0.0625;
+
+ gl_FragColor = color;
+}
diff --git a/src/renderergl2/glsl/down4x_vp.glsl b/src/renderergl2/glsl/down4x_vp.glsl
new file mode 100644
index 0000000..bdaa74a
--- /dev/null
+++ b/src/renderergl2/glsl/down4x_vp.glsl
@@ -0,0 +1,13 @@
+attribute vec3 attr_Position;
+attribute vec4 attr_TexCoord0;
+
+uniform mat4 u_ModelViewProjectionMatrix;
+
+varying vec2 var_TexCoords;
+
+
+void main()
+{
+ gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
+ var_TexCoords = attr_TexCoord0.st;
+}
diff --git a/src/renderergl2/glsl/fogpass_fp.glsl b/src/renderergl2/glsl/fogpass_fp.glsl
new file mode 100644
index 0000000..e2ad465
--- /dev/null
+++ b/src/renderergl2/glsl/fogpass_fp.glsl
@@ -0,0 +1,9 @@
+uniform vec4 u_Color;
+
+varying float var_Scale;
+
+void main()
+{
+ gl_FragColor = u_Color;
+ gl_FragColor.a = sqrt(clamp(var_Scale, 0.0, 1.0));
+}
diff --git a/src/renderergl2/glsl/fogpass_vp.glsl b/src/renderergl2/glsl/fogpass_vp.glsl
new file mode 100644
index 0000000..c8ec9a9
--- /dev/null
+++ b/src/renderergl2/glsl/fogpass_vp.glsl
@@ -0,0 +1,117 @@
+attribute vec3 attr_Position;
+attribute vec3 attr_Normal;
+
+attribute vec4 attr_TexCoord0;
+
+#if defined(USE_VERTEX_ANIMATION)
+attribute vec3 attr_Position2;
+attribute vec3 attr_Normal2;
+#endif
+
+uniform vec4 u_FogDistance;
+uniform vec4 u_FogDepth;
+uniform float u_FogEyeT;
+
+#if defined(USE_DEFORM_VERTEXES)
+uniform int u_DeformGen;
+uniform float u_DeformParams[5];
+#endif
+
+uniform float u_Time;
+uniform mat4 u_ModelViewProjectionMatrix;
+
+#if defined(USE_VERTEX_ANIMATION)
+uniform float u_VertexLerp;
+#endif
+
+uniform vec4 u_Color;
+
+varying float var_Scale;
+
+#if defined(USE_DEFORM_VERTEXES)
+vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
+{
+ if (u_DeformGen == 0)
+ {
+ return pos;
+ }
+
+ float base = u_DeformParams[0];
+ float amplitude = u_DeformParams[1];
+ float phase = u_DeformParams[2];
+ float frequency = u_DeformParams[3];
+ float spread = u_DeformParams[4];
+
+ if (u_DeformGen == DGEN_BULGE)
+ {
+ phase *= st.x;
+ }
+ else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
+ {
+ phase += dot(pos.xyz, vec3(spread));
+ }
+
+ float value = phase + (u_Time * frequency);
+ float func;
+
+ if (u_DeformGen == DGEN_WAVE_SIN)
+ {
+ func = sin(value * 2.0 * M_PI);
+ }
+ else if (u_DeformGen == DGEN_WAVE_SQUARE)
+ {
+ func = sign(0.5 - fract(value));
+ }
+ else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
+ {
+ func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
+ }
+ else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
+ {
+ func = fract(value);
+ }
+ else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)
+ {
+ func = (1.0 - fract(value));
+ }
+ else // if (u_DeformGen == DGEN_BULGE)
+ {
+ func = sin(value);
+ }
+
+ return pos + normal * (base + func * amplitude);
+}
+#endif
+
+float CalcFog(vec3 position)
+{
+ float s = dot(vec4(position, 1.0), u_FogDistance) * 8.0;
+ float t = dot(vec4(position, 1.0), u_FogDepth);
+
+ float eyeOutside = float(u_FogEyeT < 0.0);
+ float fogged = float(t >= eyeOutside);
+
+ t += 1e-6;
+ t *= fogged / (t - u_FogEyeT * eyeOutside);
+
+ return s * t;
+}
+
+void main()
+{
+#if defined(USE_VERTEX_ANIMATION)
+ vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
+ vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
+#else
+ vec3 position = attr_Position;
+ vec3 normal = attr_Normal;
+#endif
+
+#if defined(USE_DEFORM_VERTEXES)
+ position.xyz = DeformPosition(position.xyz, normal, attr_TexCoord0.st);
+#endif
+
+ gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
+
+ var_Scale = CalcFog(position) * u_Color.a * u_Color.a;
+}
diff --git a/src/renderergl2/glsl/generic_fp.glsl b/src/renderergl2/glsl/generic_fp.glsl
new file mode 100644
index 0000000..c0a4940
--- /dev/null
+++ b/src/renderergl2/glsl/generic_fp.glsl
@@ -0,0 +1,33 @@
+uniform sampler2D u_DiffuseMap;
+
+uniform int u_AlphaTest;
+
+varying vec2 var_DiffuseTex;
+
+varying vec4 var_Color;
+
+
+void main()
+{
+ vec4 color = texture2D(u_DiffuseMap, var_DiffuseTex);
+
+ float alpha = color.a * var_Color.a;
+ if (u_AlphaTest == 1)
+ {
+ if (alpha == 0.0)
+ discard;
+ }
+ else if (u_AlphaTest == 2)
+ {
+ if (alpha >= 0.5)
+ discard;
+ }
+ else if (u_AlphaTest == 3)
+ {
+ if (alpha < 0.5)
+ discard;
+ }
+
+ gl_FragColor.rgb = color.rgb * var_Color.rgb;
+ gl_FragColor.a = alpha;
+}
diff --git a/src/renderergl2/glsl/generic_vp.glsl b/src/renderergl2/glsl/generic_vp.glsl
new file mode 100644
index 0000000..bbe08e8
--- /dev/null
+++ b/src/renderergl2/glsl/generic_vp.glsl
@@ -0,0 +1,239 @@
+attribute vec3 attr_Position;
+attribute vec3 attr_Normal;
+
+#if defined(USE_VERTEX_ANIMATION)
+attribute vec3 attr_Position2;
+attribute vec3 attr_Normal2;
+#endif
+
+attribute vec4 attr_Color;
+attribute vec4 attr_TexCoord0;
+
+#if defined(USE_TCGEN)
+attribute vec4 attr_TexCoord1;
+#endif
+
+uniform vec4 u_DiffuseTexMatrix;
+uniform vec4 u_DiffuseTexOffTurb;
+
+#if defined(USE_TCGEN) || defined(USE_RGBAGEN)
+uniform vec3 u_LocalViewOrigin;
+#endif
+
+#if defined(USE_TCGEN)
+uniform int u_TCGen0;
+uniform vec3 u_TCGen0Vector0;
+uniform vec3 u_TCGen0Vector1;
+#endif
+
+#if defined(USE_FOG)
+uniform vec4 u_FogDistance;
+uniform vec4 u_FogDepth;
+uniform float u_FogEyeT;
+uniform vec4 u_FogColorMask;
+#endif
+
+#if defined(USE_DEFORM_VERTEXES)
+uniform int u_DeformGen;
+uniform float u_DeformParams[5];
+uniform float u_Time;
+#endif
+
+uniform mat4 u_ModelViewProjectionMatrix;
+uniform vec4 u_BaseColor;
+uniform vec4 u_VertColor;
+
+#if defined(USE_RGBAGEN)
+uniform int u_ColorGen;
+uniform int u_AlphaGen;
+uniform vec3 u_AmbientLight;
+uniform vec3 u_DirectedLight;
+uniform vec3 u_ModelLightDir;
+uniform float u_PortalRange;
+#endif
+
+#if defined(USE_VERTEX_ANIMATION)
+uniform float u_VertexLerp;
+#endif
+
+varying vec2 var_DiffuseTex;
+varying vec4 var_Color;
+
+#if defined(USE_DEFORM_VERTEXES)
+vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
+{
+ float base = u_DeformParams[0];
+ float amplitude = u_DeformParams[1];
+ float phase = u_DeformParams[2];
+ float frequency = u_DeformParams[3];
+ float spread = u_DeformParams[4];
+
+ if (u_DeformGen == DGEN_BULGE)
+ {
+ phase *= st.x;
+ }
+ else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
+ {
+ phase += dot(pos.xyz, vec3(spread));
+ }
+
+ float value = phase + (u_Time * frequency);
+ float func;
+
+ if (u_DeformGen == DGEN_WAVE_SIN)
+ {
+ func = sin(value * 2.0 * M_PI);
+ }
+ else if (u_DeformGen == DGEN_WAVE_SQUARE)
+ {
+ func = sign(fract(0.5 - value));
+ }
+ else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
+ {
+ func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
+ }
+ else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
+ {
+ func = fract(value);
+ }
+ else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)
+ {
+ func = (1.0 - fract(value));
+ }
+ else // if (u_DeformGen == DGEN_BULGE)
+ {
+ func = sin(value);
+ }
+
+ return pos + normal * (base + func * amplitude);
+}
+#endif
+
+#if defined(USE_TCGEN)
+vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3 TCGenVector1)
+{
+ vec2 tex = attr_TexCoord0.st;
+
+ if (TCGen == TCGEN_LIGHTMAP)
+ {
+ tex = attr_TexCoord1.st;
+ }
+ else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
+ {
+ vec3 viewer = normalize(u_LocalViewOrigin - position);
+ vec2 ref = reflect(viewer, normal).yz;
+ tex.s = ref.x * -0.5 + 0.5;
+ tex.t = ref.y * 0.5 + 0.5;
+ }
+ else if (TCGen == TCGEN_VECTOR)
+ {
+ tex = vec2(dot(position, TCGenVector0), dot(position, TCGenVector1));
+ }
+
+ return tex;
+}
+#endif
+
+#if defined(USE_TCMOD)
+vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
+{
+ float amplitude = offTurb.z;
+ float phase = offTurb.w * 2.0 * M_PI;
+ vec2 st2;
+ st2.x = st.x * texMatrix.x + (st.y * texMatrix.z + offTurb.x);
+ st2.y = st.x * texMatrix.y + (st.y * texMatrix.w + offTurb.y);
+
+ vec2 offsetPos = vec2(position.x + position.z, position.y);
+
+ vec2 texOffset = sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(phase));
+
+ return st2 + texOffset * amplitude;
+}
+#endif
+
+#if defined(USE_RGBAGEN)
+vec4 CalcColor(vec3 position, vec3 normal)
+{
+ vec4 color = u_VertColor * attr_Color + u_BaseColor;
+
+ if (u_ColorGen == CGEN_LIGHTING_DIFFUSE)
+ {
+ float incoming = clamp(dot(normal, u_ModelLightDir), 0.0, 1.0);
+
+ color.rgb = clamp(u_DirectedLight * incoming + u_AmbientLight, 0.0, 1.0);
+ }
+
+ vec3 viewer = u_LocalViewOrigin - position;
+
+ if (u_AlphaGen == AGEN_LIGHTING_SPECULAR)
+ {
+ vec3 lightDir = normalize(vec3(-960.0, 1980.0, 96.0) - position);
+ vec3 reflected = -reflect(lightDir, normal);
+
+ color.a = clamp(dot(reflected, normalize(viewer)), 0.0, 1.0);
+ color.a *= color.a;
+ color.a *= color.a;
+ }
+ else if (u_AlphaGen == AGEN_PORTAL)
+ {
+ color.a = clamp(length(viewer) / u_PortalRange, 0.0, 1.0);
+ }
+
+ return color;
+}
+#endif
+
+#if defined(USE_FOG)
+float CalcFog(vec3 position)
+{
+ float s = dot(vec4(position, 1.0), u_FogDistance) * 8.0;
+ float t = dot(vec4(position, 1.0), u_FogDepth);
+
+ float eyeOutside = float(u_FogEyeT < 0.0);
+ float fogged = float(t >= eyeOutside);
+
+ t += 1e-6;
+ t *= fogged / (t - u_FogEyeT * eyeOutside);
+
+ return s * t;
+}
+#endif
+
+void main()
+{
+#if defined(USE_VERTEX_ANIMATION)
+ vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
+ vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
+#else
+ vec3 position = attr_Position;
+ vec3 normal = attr_Normal;
+#endif
+
+#if defined(USE_DEFORM_VERTEXES)
+ position = DeformPosition(position, normal, attr_TexCoord0.st);
+#endif
+
+ gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
+
+#if defined(USE_TCGEN)
+ vec2 tex = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1);
+#else
+ vec2 tex = attr_TexCoord0.st;
+#endif
+
+#if defined(USE_TCMOD)
+ var_DiffuseTex = ModTexCoords(tex, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
+#else
+ var_DiffuseTex = tex;
+#endif
+
+#if defined(USE_RGBAGEN)
+ var_Color = CalcColor(position, normal);
+#else
+ var_Color = u_VertColor * attr_Color + u_BaseColor;
+#endif
+
+#if defined(USE_FOG)
+ var_Color *= vec4(1.0) - u_FogColorMask * sqrt(clamp(CalcFog(position), 0.0, 1.0));
+#endif
+}
diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl
new file mode 100644
index 0000000..8e7c9b4
--- /dev/null
+++ b/src/renderergl2/glsl/lightall_fp.glsl
@@ -0,0 +1,429 @@
+uniform sampler2D u_DiffuseMap;
+
+#if defined(USE_LIGHTMAP)
+uniform sampler2D u_LightMap;
+#endif
+
+#if defined(USE_NORMALMAP)
+uniform sampler2D u_NormalMap;
+#endif
+
+#if defined(USE_DELUXEMAP)
+uniform sampler2D u_DeluxeMap;
+#endif
+
+#if defined(USE_SPECULARMAP)
+uniform sampler2D u_SpecularMap;
+#endif
+
+#if defined(USE_SHADOWMAP)
+uniform sampler2D u_ShadowMap;
+#endif
+
+#if defined(USE_CUBEMAP)
+uniform samplerCube u_CubeMap;
+#endif
+
+#if defined(USE_NORMALMAP) || defined(USE_DELUXEMAP) || defined(USE_SPECULARMAP) || defined(USE_CUBEMAP)
+// y = deluxe, w = cube
+uniform vec4 u_EnableTextures;
+#endif
+
+#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
+uniform vec3 u_PrimaryLightColor;
+uniform vec3 u_PrimaryLightAmbient;
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+uniform vec4 u_NormalScale;
+uniform vec4 u_SpecularScale;
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+#if defined(USE_CUBEMAP)
+uniform vec4 u_CubeMapInfo;
+#endif
+#endif
+
+uniform int u_AlphaTest;
+
+varying vec4 var_TexCoords;
+
+varying vec4 var_Color;
+#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
+varying vec4 var_ColorAmbient;
+#endif
+
+#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
+varying vec4 var_Normal;
+varying vec4 var_Tangent;
+varying vec4 var_Bitangent;
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+varying vec4 var_LightDir;
+#endif
+
+#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
+varying vec4 var_PrimaryLightDir;
+#endif
+
+
+#define EPSILON 0.00000001
+
+#if defined(USE_PARALLAXMAP)
+float SampleDepth(sampler2D normalMap, vec2 t)
+{
+ #if defined(SWIZZLE_NORMALMAP)
+ return 1.0 - texture2D(normalMap, t).r;
+ #else
+ return 1.0 - texture2D(normalMap, t).a;
+ #endif
+}
+
+float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)
+{
+ const int linearSearchSteps = 16;
+ const int binarySearchSteps = 6;
+
+ // current size of search window
+ float size = 1.0 / float(linearSearchSteps);
+
+ // current depth position
+ float depth = 0.0;
+
+ // best match found (starts with last position 1.0)
+ float bestDepth = 1.0;
+
+ // texture depth at best depth
+ float texDepth = 0.0;
+
+ float prevT = SampleDepth(normalMap, dp);
+ float prevTexDepth = prevT;
+
+ // search front to back for first point inside object
+ for(int i = 0; i < linearSearchSteps - 1; ++i)
+ {
+ depth += size;
+
+ float t = SampleDepth(normalMap, dp + ds * depth);
+
+ if(bestDepth > 0.996) // if no depth found yet
+ if(depth >= t)
+ {
+ bestDepth = depth; // store best depth
+ texDepth = t;
+ prevTexDepth = prevT;
+ }
+ prevT = t;
+ }
+
+ depth = bestDepth;
+
+#if !defined (USE_RELIEFMAP)
+ float div = 1.0 / (1.0 + (prevTexDepth - texDepth) * float(linearSearchSteps));
+ bestDepth -= (depth - size - prevTexDepth) * div;
+#else
+ // recurse around first point (depth) for closest match
+ for(int i = 0; i < binarySearchSteps; ++i)
+ {
+ size *= 0.5;
+
+ float t = SampleDepth(normalMap, dp + ds * depth);
+
+ if(depth >= t)
+ {
+ bestDepth = depth;
+ depth -= 2.0 * size;
+ }
+
+ depth += size;
+ }
+#endif
+
+ return bestDepth;
+}
+#endif
+
+vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness)
+{
+#if defined(USE_BURLEY)
+ // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf
+ float fd90 = -0.5 + EH * EH * roughness;
+ float burley = 1.0 + fd90 * 0.04 / NH;
+ burley *= burley;
+ return diffuseAlbedo * burley;
+#else
+ return diffuseAlbedo;
+#endif
+}
+
+vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular)
+{
+ // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
+ float v = 1.0 - max(roughness, NE);
+ v *= v * v;
+ return vec3(v) + specular;
+}
+
+vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness)
+{
+ // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf
+ float rr = roughness*roughness;
+ float rrrr = rr*rr;
+ float d = (NH * NH) * (rrrr - 1.0) + 1.0;
+ float v = (EH * EH) * (roughness + 0.5);
+ return specular * (rrrr / (4.0 * d * d * v));
+}
+
+
+float CalcLightAttenuation(float point, float normDist)
+{
+ // zero light at 1.0, approximating q3 style
+ // also don't attenuate directional light
+ float attenuation = (0.5 * normDist - 1.5) * point + 1.0;
+
+ // clamp attenuation
+ #if defined(NO_LIGHT_CLAMP)
+ attenuation = max(attenuation, 0.0);
+ #else
+ attenuation = clamp(attenuation, 0.0, 1.0);
+ #endif
+
+ return attenuation;
+}
+
+
+void main()
+{
+ vec3 viewDir, lightColor, ambientColor, reflectance;
+ vec3 L, N, E, H;
+ float NL, NH, NE, EH, attenuation;
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz);
+ viewDir = vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w);
+ E = normalize(viewDir);
+#endif
+
+ lightColor = var_Color.rgb;
+
+#if defined(USE_LIGHTMAP)
+ vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw);
+ #if defined(RGBM_LIGHTMAP)
+ lightmapColor.rgb *= lightmapColor.a;
+ #endif
+ #if defined(USE_PBR) && !defined(USE_FAST_LIGHT)
+ lightmapColor.rgb *= lightmapColor.rgb;
+ #endif
+ lightColor *= lightmapColor.rgb;
+#endif
+
+ vec2 texCoords = var_TexCoords.xy;
+
+#if defined(USE_PARALLAXMAP)
+ vec3 offsetDir = viewDir * tangentToWorld;
+
+ offsetDir.xy *= -u_NormalScale.a / offsetDir.z;
+
+ texCoords += offsetDir.xy * RayIntersectDisplaceMap(texCoords, offsetDir.xy, u_NormalMap);
+#endif
+
+ vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
+
+ float alpha = diffuse.a * var_Color.a;
+ if (u_AlphaTest == 1)
+ {
+ if (alpha == 0.0)
+ discard;
+ }
+ else if (u_AlphaTest == 2)
+ {
+ if (alpha >= 0.5)
+ discard;
+ }
+ else if (u_AlphaTest == 3)
+ {
+ if (alpha < 0.5)
+ discard;
+ }
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ L = var_LightDir.xyz;
+ #if defined(USE_DELUXEMAP)
+ L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y;
+ #endif
+ float sqrLightDist = dot(L, L);
+ L /= sqrt(sqrLightDist);
+
+ #if defined(USE_LIGHT_VECTOR)
+ attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist);
+ #else
+ attenuation = 1.0;
+ #endif
+
+ #if defined(USE_NORMALMAP)
+ #if defined(SWIZZLE_NORMALMAP)
+ N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5);
+ #else
+ N.xy = texture2D(u_NormalMap, texCoords).rg - vec2(0.5);
+ #endif
+ N.xy *= u_NormalScale.xy;
+ N.z = sqrt(clamp((0.25 - N.x * N.x) - N.y * N.y, 0.0, 1.0));
+ N = tangentToWorld * N;
+ #else
+ N = var_Normal.xyz;
+ #endif
+
+ N = normalize(N);
+
+ #if defined(USE_SHADOWMAP)
+ vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
+ float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
+
+ // surfaces not facing the light are always shadowed
+ shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0);
+
+ #if defined(SHADOWMAP_MODULATE)
+ lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r;
+ #endif
+ #endif
+
+ #if !defined(USE_LIGHT_VECTOR)
+ ambientColor = lightColor;
+ float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
+
+ // reserve 25% ambient to avoid black areas on normalmaps
+ lightColor *= 0.75;
+
+ // Scale the incoming light to compensate for the baked-in light angle
+ // attenuation.
+ lightColor /= max(surfNL, 0.25);
+
+ // Recover any unused light as ambient, in case attenuation is over 4x or
+ // light is below the surface
+ ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0));
+ #else
+ ambientColor = var_ColorAmbient.rgb;
+ #endif
+
+ NL = clamp(dot(N, L), 0.0, 1.0);
+ NE = clamp(dot(N, E), 0.0, 1.0);
+
+ #if defined(USE_SPECULARMAP)
+ vec4 specular = texture2D(u_SpecularMap, texCoords);
+ #else
+ vec4 specular = vec4(1.0);
+ #endif
+ specular *= u_SpecularScale;
+
+ #if defined(USE_PBR)
+ diffuse.rgb *= diffuse.rgb;
+ #endif
+
+ #if defined(USE_PBR)
+ // diffuse rgb is base color
+ // specular red is gloss
+ // specular green is metallicness
+ float gloss = specular.r;
+ float metal = specular.g;
+ specular.rgb = metal * diffuse.rgb + vec3(0.04 - 0.04 * metal);
+ diffuse.rgb *= 1.0 - metal;
+ #else
+ // diffuse rgb is diffuse
+ // specular rgb is specular reflectance at normal incidence
+ // specular alpha is gloss
+ float gloss = specular.a;
+
+ // adjust diffuse by specular reflectance, to maintain energy conservation
+ diffuse.rgb *= vec3(1.0) - specular.rgb;
+ #endif
+
+ #if defined(GLOSS_IS_GLOSS)
+ float roughness = exp2(-3.0 * gloss);
+ #elif defined(GLOSS_IS_SMOOTHNESS)
+ float roughness = 1.0 - gloss;
+ #elif defined(GLOSS_IS_ROUGHNESS)
+ float roughness = gloss;
+ #elif defined(GLOSS_IS_SHININESS)
+ float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25);
+ #endif
+
+ reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness);
+
+ gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL);
+ gl_FragColor.rgb += ambientColor * diffuse.rgb;
+
+ #if defined(USE_CUBEMAP)
+ reflectance = EnvironmentBRDF(roughness, NE, specular.rgb);
+
+ vec3 R = reflect(E, N);
+
+ // parallax corrected cubemap (cheaper trick)
+ // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
+ vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
+
+ vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, ROUGHNESS_MIPS * roughness).rgb * u_EnableTextures.w;
+
+ // normalize cubemap based on last roughness mip (~diffuse)
+ // multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
+ //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, ROUGHNESS_MIPS).rgb, 0.5 / 255.0);
+ //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721));
+
+ #if defined(USE_PBR)
+ cubeLightColor *= cubeLightColor;
+ #endif
+
+ // multiply cubemap values by lighting
+ // not technically correct, but helps make reflections look less unnatural
+ //cubeLightColor *= lightColor * (attenuation * NL) + ambientColor;
+
+ gl_FragColor.rgb += cubeLightColor * reflectance;
+ #endif
+
+ #if defined(USE_PRIMARY_LIGHT) || defined(SHADOWMAP_MODULATE)
+ vec3 L2, H2;
+ float NL2, EH2, NH2;
+
+ L2 = var_PrimaryLightDir.xyz;
+
+ // enable when point lights are supported as primary lights
+ //sqrLightDist = dot(L2, L2);
+ //L2 /= sqrt(sqrLightDist);
+
+ NL2 = clamp(dot(N, L2), 0.0, 1.0);
+ H2 = normalize(L2 + E);
+ EH2 = clamp(dot(E, H2), 0.0, 1.0);
+ NH2 = clamp(dot(N, H2), 0.0, 1.0);
+
+ reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness);
+
+ // bit of a hack, with modulated shadowmaps, ignore diffuse
+ #if !defined(SHADOWMAP_MODULATE)
+ reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness);
+ #endif
+
+ lightColor = u_PrimaryLightColor;
+
+ #if defined(USE_SHADOWMAP)
+ lightColor *= shadowValue;
+ #endif
+
+ // enable when point lights are supported as primary lights
+ //lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist);
+
+ gl_FragColor.rgb += lightColor * reflectance * NL2;
+ #endif
+
+ #if defined(USE_PBR)
+ gl_FragColor.rgb = sqrt(gl_FragColor.rgb);
+ #endif
+
+#else
+
+ gl_FragColor.rgb = diffuse.rgb * lightColor;
+
+#endif
+
+ gl_FragColor.a = alpha;
+}
diff --git a/src/renderergl2/glsl/lightall_vp.glsl b/src/renderergl2/glsl/lightall_vp.glsl
new file mode 100644
index 0000000..e5b3c4f
--- /dev/null
+++ b/src/renderergl2/glsl/lightall_vp.glsl
@@ -0,0 +1,246 @@
+attribute vec4 attr_TexCoord0;
+#if defined(USE_LIGHTMAP) || defined(USE_TCGEN)
+attribute vec4 attr_TexCoord1;
+#endif
+attribute vec4 attr_Color;
+
+attribute vec3 attr_Position;
+attribute vec3 attr_Normal;
+attribute vec4 attr_Tangent;
+
+#if defined(USE_VERTEX_ANIMATION)
+attribute vec3 attr_Position2;
+attribute vec3 attr_Normal2;
+attribute vec4 attr_Tangent2;
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
+attribute vec3 attr_LightDirection;
+#endif
+
+#if defined(USE_DELUXEMAP)
+uniform vec4 u_EnableTextures; // x = normal, y = deluxe, z = specular, w = cube
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+uniform vec3 u_ViewOrigin;
+#endif
+
+#if defined(USE_TCGEN)
+uniform int u_TCGen0;
+uniform vec3 u_TCGen0Vector0;
+uniform vec3 u_TCGen0Vector1;
+uniform vec3 u_LocalViewOrigin;
+#endif
+
+#if defined(USE_TCMOD)
+uniform vec4 u_DiffuseTexMatrix;
+uniform vec4 u_DiffuseTexOffTurb;
+#endif
+
+uniform mat4 u_ModelViewProjectionMatrix;
+uniform vec4 u_BaseColor;
+uniform vec4 u_VertColor;
+
+#if defined(USE_MODELMATRIX)
+uniform mat4 u_ModelMatrix;
+#endif
+
+#if defined(USE_VERTEX_ANIMATION)
+uniform float u_VertexLerp;
+#endif
+
+#if defined(USE_LIGHT_VECTOR)
+uniform vec4 u_LightOrigin;
+uniform float u_LightRadius;
+uniform vec3 u_DirectedLight;
+uniform vec3 u_AmbientLight;
+#endif
+
+#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
+uniform vec4 u_PrimaryLightOrigin;
+uniform float u_PrimaryLightRadius;
+#endif
+
+varying vec4 var_TexCoords;
+
+varying vec4 var_Color;
+#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
+varying vec4 var_ColorAmbient;
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+varying vec4 var_Normal;
+varying vec4 var_Tangent;
+varying vec4 var_Bitangent;
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+varying vec4 var_LightDir;
+#endif
+
+#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
+varying vec4 var_PrimaryLightDir;
+#endif
+
+#if defined(USE_TCGEN)
+vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3 TCGenVector1)
+{
+ vec2 tex = attr_TexCoord0.st;
+
+ if (TCGen == TCGEN_LIGHTMAP)
+ {
+ tex = attr_TexCoord1.st;
+ }
+ else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
+ {
+ vec3 viewer = normalize(u_LocalViewOrigin - position);
+ vec2 ref = reflect(viewer, normal).yz;
+ tex.s = ref.x * -0.5 + 0.5;
+ tex.t = ref.y * 0.5 + 0.5;
+ }
+ else if (TCGen == TCGEN_VECTOR)
+ {
+ tex = vec2(dot(position, TCGenVector0), dot(position, TCGenVector1));
+ }
+
+ return tex;
+}
+#endif
+
+#if defined(USE_TCMOD)
+vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
+{
+ float amplitude = offTurb.z;
+ float phase = offTurb.w * 2.0 * M_PI;
+ vec2 st2;
+ st2.x = st.x * texMatrix.x + (st.y * texMatrix.z + offTurb.x);
+ st2.y = st.x * texMatrix.y + (st.y * texMatrix.w + offTurb.y);
+
+ vec2 offsetPos = vec2(position.x + position.z, position.y);
+
+ vec2 texOffset = sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(phase));
+
+ return st2 + texOffset * amplitude;
+}
+#endif
+
+
+float CalcLightAttenuation(float point, float normDist)
+{
+ // zero light at 1.0, approximating q3 style
+ // also don't attenuate directional light
+ float attenuation = (0.5 * normDist - 1.5) * point + 1.0;
+
+ // clamp attenuation
+ #if defined(NO_LIGHT_CLAMP)
+ attenuation = max(attenuation, 0.0);
+ #else
+ attenuation = clamp(attenuation, 0.0, 1.0);
+ #endif
+
+ return attenuation;
+}
+
+
+void main()
+{
+#if defined(USE_VERTEX_ANIMATION)
+ vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
+ vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
+ #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ vec3 tangent = mix(attr_Tangent.xyz, attr_Tangent2.xyz, u_VertexLerp);
+ #endif
+#else
+ vec3 position = attr_Position;
+ vec3 normal = attr_Normal;
+ #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ vec3 tangent = attr_Tangent.xyz;
+ #endif
+#endif
+
+#if defined(USE_TCGEN)
+ vec2 texCoords = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1);
+#else
+ vec2 texCoords = attr_TexCoord0.st;
+#endif
+
+#if defined(USE_TCMOD)
+ var_TexCoords.xy = ModTexCoords(texCoords, position, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
+#else
+ var_TexCoords.xy = texCoords;
+#endif
+
+ gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
+
+#if defined(USE_MODELMATRIX)
+ position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
+ normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz;
+ #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;
+ #endif
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ vec3 bitangent = cross(normal, tangent) * attr_Tangent.w;
+#endif
+
+#if defined(USE_LIGHT_VECTOR)
+ vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w);
+#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ vec3 L = attr_LightDirection;
+ #if defined(USE_MODELMATRIX)
+ L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
+ #endif
+#endif
+
+#if defined(USE_LIGHTMAP)
+ var_TexCoords.zw = attr_TexCoord1.st;
+#endif
+
+ var_Color = u_VertColor * attr_Color + u_BaseColor;
+
+#if defined(USE_LIGHT_VECTOR)
+ #if defined(USE_FAST_LIGHT)
+ float sqrLightDist = dot(L, L);
+ float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
+ float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist);
+
+ var_Color.rgb *= u_DirectedLight * (attenuation * NL) + u_AmbientLight;
+ #else
+ var_ColorAmbient.rgb = u_AmbientLight * var_Color.rgb;
+ var_Color.rgb *= u_DirectedLight;
+ #if defined(USE_PBR)
+ var_ColorAmbient.rgb *= var_ColorAmbient.rgb;
+ #endif
+ #endif
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) && defined(USE_PBR)
+ var_Color.rgb *= var_Color.rgb;
+#endif
+
+#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
+ var_PrimaryLightDir.xyz = u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w);
+ var_PrimaryLightDir.w = u_PrimaryLightRadius * u_PrimaryLightRadius;
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ #if defined(USE_LIGHT_VECTOR)
+ var_LightDir = vec4(L, u_LightRadius * u_LightRadius);
+ #else
+ var_LightDir = vec4(L, 0.0);
+ #endif
+ #if defined(USE_DELUXEMAP)
+ var_LightDir -= u_EnableTextures.y * var_LightDir;
+ #endif
+#endif
+
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+ vec3 viewDir = u_ViewOrigin - position;
+ // store view direction in tangent space to save on varyings
+ var_Normal = vec4(normal, viewDir.x);
+ var_Tangent = vec4(tangent, viewDir.y);
+ var_Bitangent = vec4(bitangent, viewDir.z);
+#endif
+}
diff --git a/src/renderergl2/glsl/pshadow_fp.glsl b/src/renderergl2/glsl/pshadow_fp.glsl
new file mode 100644
index 0000000..c196f48
--- /dev/null
+++ b/src/renderergl2/glsl/pshadow_fp.glsl
@@ -0,0 +1,78 @@
+uniform sampler2D u_ShadowMap;
+
+uniform vec3 u_LightForward;
+uniform vec3 u_LightUp;
+uniform vec3 u_LightRight;
+uniform vec4 u_LightOrigin;
+uniform float u_LightRadius;
+varying vec3 var_Position;
+varying vec3 var_Normal;
+
+void main()
+{
+ vec3 lightToPos = var_Position - u_LightOrigin.xyz;
+ vec2 st = vec2(-dot(u_LightRight, lightToPos), dot(u_LightUp, lightToPos));
+
+ float fade = length(st);
+
+#if defined(USE_DISCARD)
+ if (fade >= 1.0)
+ {
+ discard;
+ }
+#endif
+
+ fade = clamp(8.0 - fade * 8.0, 0.0, 1.0);
+
+ st = st * 0.5 + vec2(0.5);
+
+#if defined(USE_SOLID_PSHADOWS)
+ float intensity = max(sign(u_LightRadius - length(lightToPos)), 0.0);
+#else
+ float intensity = clamp((1.0 - dot(lightToPos, lightToPos) / (u_LightRadius * u_LightRadius)) * 2.0, 0.0, 1.0);
+#endif
+
+ float lightDist = length(lightToPos);
+ float dist;
+
+#if defined(USE_DISCARD)
+ if (dot(u_LightForward, lightToPos) <= 0.0)
+ {
+ discard;
+ }
+
+ if (dot(var_Normal, lightToPos) > 0.0)
+ {
+ discard;
+ }
+#else
+ intensity *= max(sign(dot(u_LightForward, lightToPos)), 0.0);
+ intensity *= max(sign(-dot(var_Normal, lightToPos)), 0.0);
+#endif
+
+ intensity *= fade;
+
+ float part;
+#if defined(USE_PCF)
+ part = float(texture2D(u_ShadowMap, st + vec2(-1.0/512.0, -1.0/512.0)).r != 1.0);
+ part += float(texture2D(u_ShadowMap, st + vec2( 1.0/512.0, -1.0/512.0)).r != 1.0);
+ part += float(texture2D(u_ShadowMap, st + vec2(-1.0/512.0, 1.0/512.0)).r != 1.0);
+ part += float(texture2D(u_ShadowMap, st + vec2( 1.0/512.0, 1.0/512.0)).r != 1.0);
+#else
+ part = float(texture2D(u_ShadowMap, st).r != 1.0);
+#endif
+
+ if (part <= 0.0)
+ {
+ discard;
+ }
+
+#if defined(USE_PCF)
+ intensity *= part * 0.25;
+#else
+ intensity *= part;
+#endif
+
+ gl_FragColor.rgb = vec3(0);
+ gl_FragColor.a = clamp(intensity, 0.0, 0.75);
+}
diff --git a/src/renderergl2/glsl/pshadow_vp.glsl b/src/renderergl2/glsl/pshadow_vp.glsl
new file mode 100644
index 0000000..07a4985
--- /dev/null
+++ b/src/renderergl2/glsl/pshadow_vp.glsl
@@ -0,0 +1,15 @@
+attribute vec3 attr_Position;
+attribute vec3 attr_Normal;
+
+uniform mat4 u_ModelViewProjectionMatrix;
+varying vec3 var_Position;
+varying vec3 var_Normal;
+
+
+void main()
+{
+ gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
+
+ var_Position = attr_Position;
+ var_Normal = attr_Normal;
+}
diff --git a/src/renderergl2/glsl/shadowfill_fp.glsl b/src/renderergl2/glsl/shadowfill_fp.glsl
new file mode 100644
index 0000000..150f3d1
--- /dev/null
+++ b/src/renderergl2/glsl/shadowfill_fp.glsl
@@ -0,0 +1,41 @@
+uniform vec4 u_LightOrigin;
+uniform float u_LightRadius;
+
+varying vec3 var_Position;
+
+void main()
+{
+#if defined(USE_DEPTH)
+ float depth = length(u_LightOrigin.xyz - var_Position) / u_LightRadius;
+ #if 0
+ // 32 bit precision
+ const vec4 bitSh = vec4( 256 * 256 * 256, 256 * 256, 256, 1);
+ const vec4 bitMsk = vec4( 0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
+
+ vec4 comp;
+ comp = depth * bitSh;
+ comp.xyz = fract(comp.xyz);
+ comp -= comp.xxyz * bitMsk;
+ gl_FragColor = comp;
+ #endif
+
+ #if 1
+ // 24 bit precision
+ const vec3 bitSh = vec3( 256 * 256, 256, 1);
+ const vec3 bitMsk = vec3( 0, 1.0 / 256.0, 1.0 / 256.0);
+
+ vec3 comp;
+ comp = depth * bitSh;
+ comp.xy = fract(comp.xy);
+ comp -= comp.xxy * bitMsk;
+ gl_FragColor = vec4(comp, 1.0);
+ #endif
+
+ #if 0
+ // 8 bit precision
+ gl_FragColor = vec4(depth, depth, depth, 1);
+ #endif
+#else
+ gl_FragColor = vec4(0, 0, 0, 1);
+#endif
+}
diff --git a/src/renderergl2/glsl/shadowfill_vp.glsl b/src/renderergl2/glsl/shadowfill_vp.glsl
new file mode 100644
index 0000000..7de901b
--- /dev/null
+++ b/src/renderergl2/glsl/shadowfill_vp.glsl
@@ -0,0 +1,89 @@
+attribute vec3 attr_Position;
+attribute vec3 attr_Normal;
+attribute vec4 attr_TexCoord0;
+
+//#if defined(USE_VERTEX_ANIMATION)
+attribute vec3 attr_Position2;
+attribute vec3 attr_Normal2;
+//#endif
+
+//#if defined(USE_DEFORM_VERTEXES)
+uniform int u_DeformGen;
+uniform float u_DeformParams[5];
+//#endif
+
+uniform float u_Time;
+uniform mat4 u_ModelViewProjectionMatrix;
+
+uniform mat4 u_ModelMatrix;
+
+//#if defined(USE_VERTEX_ANIMATION)
+uniform float u_VertexLerp;
+//#endif
+
+varying vec3 var_Position;
+
+vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)
+{
+ if (u_DeformGen == 0)
+ {
+ return pos;
+ }
+
+ float base = u_DeformParams[0];
+ float amplitude = u_DeformParams[1];
+ float phase = u_DeformParams[2];
+ float frequency = u_DeformParams[3];
+ float spread = u_DeformParams[4];
+
+ if (u_DeformGen == DGEN_BULGE)
+ {
+ phase *= st.x;
+ }
+ else // if (u_DeformGen <= DGEN_WAVE_INVERSE_SAWTOOTH)
+ {
+ phase += dot(pos.xyz, vec3(spread));
+ }
+
+ float value = phase + (u_Time * frequency);
+ float func;
+
+ if (u_DeformGen == DGEN_WAVE_SIN)
+ {
+ func = sin(value * 2.0 * M_PI);
+ }
+ else if (u_DeformGen == DGEN_WAVE_SQUARE)
+ {
+ func = sign(0.5 - fract(value));
+ }
+ else if (u_DeformGen == DGEN_WAVE_TRIANGLE)
+ {
+ func = abs(fract(value + 0.75) - 0.5) * 4.0 - 1.0;
+ }
+ else if (u_DeformGen == DGEN_WAVE_SAWTOOTH)
+ {
+ func = fract(value);
+ }
+ else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)
+ {
+ func = (1.0 - fract(value));
+ }
+ else // if (u_DeformGen == DGEN_BULGE)
+ {
+ func = sin(value);
+ }
+
+ return pos + normal * (base + func * amplitude);
+}
+
+void main()
+{
+ vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
+ vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
+
+ position = DeformPosition(position, normal, attr_TexCoord0.st);
+
+ gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
+
+ var_Position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
+}
diff --git a/src/renderergl2/glsl/shadowmask_fp.glsl b/src/renderergl2/glsl/shadowmask_fp.glsl
new file mode 100644
index 0000000..2b57e3b
--- /dev/null
+++ b/src/renderergl2/glsl/shadowmask_fp.glsl
@@ -0,0 +1,143 @@
+uniform sampler2D u_ScreenDepthMap;
+
+uniform sampler2DShadow u_ShadowMap;
+#if defined(USE_SHADOW_CASCADE)
+uniform sampler2DShadow u_ShadowMap2;
+uniform sampler2DShadow u_ShadowMap3;
+uniform sampler2DShadow u_ShadowMap4;
+#endif
+
+uniform mat4 u_ShadowMvp;
+#if defined(USE_SHADOW_CASCADE)
+uniform mat4 u_ShadowMvp2;
+uniform mat4 u_ShadowMvp3;
+uniform mat4 u_ShadowMvp4;
+#endif
+
+uniform vec3 u_ViewOrigin;
+uniform vec4 u_ViewInfo; // zfar / znear, zfar
+
+varying vec2 var_DepthTex;
+varying vec3 var_ViewDir;
+
+// depth is GL_DEPTH_COMPONENT24
+// so the maximum error is 1.0 / 2^24
+#define DEPTH_MAX_ERROR 0.000000059604644775390625
+
+// Input: It uses texture coords as the random number seed.
+// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
+// Author: Michael Pohoreski
+// Copyright: Copyleft 2012 :-)
+// Source: http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader
+
+float random( const vec2 p )
+{
+ // We need irrationals for pseudo randomness.
+ // Most (all?) known transcendental numbers will (generally) work.
+ const vec2 r = vec2(
+ 23.1406926327792690, // e^pi (Gelfond's constant)
+ 2.6651441426902251); // 2^sqrt(2) (Gelfond-Schneider constant)
+ //return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) );
+ return mod( 123456789., 1e-7 + 256. * dot(p,r) );
+}
+
+float PCF(const sampler2DShadow shadowmap, const vec2 st, const float dist)
+{
+ float mult;
+ float scale = 2.0 / r_shadowMapSize;
+
+#if 0
+ // from http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html
+ vec2 offset = vec2(greaterThan(fract(var_DepthTex.xy * r_FBufScale * 0.5), vec2(0.25)));
+ offset.y += offset.x;
+ if (offset.y > 1.1) offset.y = 0.0;
+
+ mult = shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, 0.5)) * scale, dist))
+ + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, 0.5)) * scale, dist))
+ + shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, -1.5)) * scale, dist))
+ + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, -1.5)) * scale, dist));
+
+ mult *= 0.25;
+#endif
+
+#if defined(USE_SHADOW_FILTER)
+ float r = random(var_DepthTex.xy);
+ float sinr = sin(r) * scale;
+ float cosr = cos(r) * scale;
+ mat2 rmat = mat2(cosr, sinr, -sinr, cosr);
+
+ mult = shadow2D(shadowmap, vec3(st + rmat * vec2(-0.7055767, 0.196515), dist));
+ mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.3524343, -0.7791386), dist));
+ mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.2391056, 0.9189604), dist));
+ #if defined(USE_SHADOW_FILTER2)
+ mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.07580382, -0.09224417), dist));
+ mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.5784913, -0.002528916), dist));
+ mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.192888, 0.4064181), dist));
+ mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.6335801, -0.5247476), dist));
+ mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.5579782, 0.7491854), dist));
+ mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.7320465, 0.6317794), dist));
+
+ mult *= 0.11111;
+ #else
+ mult *= 0.33333;
+ #endif
+#else
+ mult = shadow2D(shadowmap, vec3(st, dist));
+#endif
+
+ return mult;
+}
+
+float getLinearDepth(sampler2D depthMap, vec2 tex, float zFarDivZNear)
+{
+ float sampleZDivW = texture2D(depthMap, tex).r - DEPTH_MAX_ERROR;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+}
+
+void main()
+{
+ float result;
+
+ float depth = getLinearDepth(u_ScreenDepthMap, var_DepthTex, u_ViewInfo.x);
+ vec4 biasPos = vec4(u_ViewOrigin + var_ViewDir * (depth - 0.5 / u_ViewInfo.x), 1.0);
+
+ vec4 shadowpos = u_ShadowMvp * biasPos;
+
+#if defined(USE_SHADOW_CASCADE)
+ if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w)))))
+ {
+#endif
+ shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5);
+ result = PCF(u_ShadowMap, shadowpos.xy, shadowpos.z);
+#if defined(USE_SHADOW_CASCADE)
+ }
+ else
+ {
+ shadowpos = u_ShadowMvp2 * biasPos;
+
+ if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w)))))
+ {
+ shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5);
+ result = PCF(u_ShadowMap2, shadowpos.xy, shadowpos.z);
+ }
+ else
+ {
+ shadowpos = u_ShadowMvp3 * biasPos;
+
+ if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w)))))
+ {
+ shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5);
+ result = PCF(u_ShadowMap3, shadowpos.xy, shadowpos.z);
+ }
+ else
+ {
+ shadowpos = u_ShadowMvp4 * biasPos;
+ shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5);
+ result = PCF(u_ShadowMap4, shadowpos.xy, shadowpos.z);
+ }
+ }
+ }
+#endif
+
+ gl_FragColor = vec4(vec3(result), 1.0);
+}
diff --git a/src/renderergl2/glsl/shadowmask_vp.glsl b/src/renderergl2/glsl/shadowmask_vp.glsl
new file mode 100644
index 0000000..13166a2
--- /dev/null
+++ b/src/renderergl2/glsl/shadowmask_vp.glsl
@@ -0,0 +1,18 @@
+attribute vec4 attr_Position;
+attribute vec4 attr_TexCoord0;
+
+uniform vec3 u_ViewForward;
+uniform vec3 u_ViewLeft;
+uniform vec3 u_ViewUp;
+uniform vec4 u_ViewInfo; // zfar / znear
+
+varying vec2 var_DepthTex;
+varying vec3 var_ViewDir;
+
+void main()
+{
+ gl_Position = attr_Position;
+ vec2 screenCoords = gl_Position.xy / gl_Position.w;
+ var_DepthTex = attr_TexCoord0.xy;
+ var_ViewDir = u_ViewForward + u_ViewLeft * -screenCoords.x + u_ViewUp * screenCoords.y;
+}
diff --git a/src/renderergl2/glsl/ssao_fp.glsl b/src/renderergl2/glsl/ssao_fp.glsl
new file mode 100644
index 0000000..93f6185
--- /dev/null
+++ b/src/renderergl2/glsl/ssao_fp.glsl
@@ -0,0 +1,86 @@
+uniform sampler2D u_ScreenDepthMap;
+
+uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height
+
+varying vec2 var_ScreenTex;
+
+vec2 poissonDisc[9] = vec2[9](
+vec2(-0.7055767, 0.196515), vec2(0.3524343, -0.7791386),
+vec2(0.2391056, 0.9189604), vec2(-0.07580382, -0.09224417),
+vec2(0.5784913, -0.002528916), vec2(0.192888, 0.4064181),
+vec2(-0.6335801, -0.5247476), vec2(-0.5579782, 0.7491854),
+vec2(0.7320465, 0.6317794)
+);
+#define NUM_SAMPLES 3
+
+// Input: It uses texture coords as the random number seed.
+// Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive.
+// Author: Michael Pohoreski
+// Copyright: Copyleft 2012 :-)
+// Source: http://stackoverflow.com/questions/5149544/can-i-generate-a-random-number-inside-a-pixel-shader
+
+float random( const vec2 p )
+{
+ // We need irrationals for pseudo randomness.
+ // Most (all?) known transcendental numbers will (generally) work.
+ const vec2 r = vec2(
+ 23.1406926327792690, // e^pi (Gelfond's constant)
+ 2.6651441426902251); // 2^sqrt(2) (Gelfond-Schneider constant)
+ //return fract( cos( mod( 123456789., 1e-7 + 256. * dot(p,r) ) ) );
+ return mod( 123456789., 1e-7 + 256. * dot(p,r) );
+}
+
+mat2 randomRotation( const vec2 p )
+{
+ float r = random(p);
+ float sinr = sin(r);
+ float cosr = cos(r);
+ return mat2(cosr, sinr, -sinr, cosr);
+}
+
+float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear)
+{
+ float sampleZDivW = texture2D(depthMap, tex).r;
+ return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW);
+}
+
+float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar, const vec2 scale)
+{
+ float result = 0;
+
+ float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear);
+ float scaleZ = zFarDivZNear * sampleZ;
+
+ vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y));
+
+ if (length(slope) * zFar > 5000.0)
+ return 1.0;
+
+ vec2 offsetScale = vec2(scale * 1024.0 / scaleZ);
+
+ mat2 rmat = randomRotation(tex);
+
+ float invZFar = 1.0 / zFar;
+ float zLimit = 20.0 * invZFar;
+ int i;
+ for (i = 0; i < NUM_SAMPLES; i++)
+ {
+ vec2 offset = rmat * poissonDisc[i] * offsetScale;
+ float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ;
+
+ bool s1 = abs(sampleDiff) > zLimit;
+ bool s2 = sampleDiff + invZFar > dot(slope, offset);
+ result += float(s1 || s2);
+ }
+
+ result *= 1.0 / float(NUM_SAMPLES);
+
+ return result;
+}
+
+void main()
+{
+ float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz);
+
+ gl_FragColor = vec4(vec3(result), 1.0);
+}
diff --git a/src/renderergl2/glsl/ssao_vp.glsl b/src/renderergl2/glsl/ssao_vp.glsl
new file mode 100644
index 0000000..9c46a79
--- /dev/null
+++ b/src/renderergl2/glsl/ssao_vp.glsl
@@ -0,0 +1,12 @@
+attribute vec4 attr_Position;
+attribute vec4 attr_TexCoord0;
+
+varying vec2 var_ScreenTex;
+
+void main()
+{
+ gl_Position = attr_Position;
+ var_ScreenTex = attr_TexCoord0.xy;
+ //vec2 screenCoords = gl_Position.xy / gl_Position.w;
+ //var_ScreenTex = screenCoords * 0.5 + 0.5;
+}
diff --git a/src/renderergl2/glsl/texturecolor_fp.glsl b/src/renderergl2/glsl/texturecolor_fp.glsl
new file mode 100644
index 0000000..7c9046e
--- /dev/null
+++ b/src/renderergl2/glsl/texturecolor_fp.glsl
@@ -0,0 +1,10 @@
+uniform sampler2D u_DiffuseMap;
+uniform vec4 u_Color;
+
+varying vec2 var_Tex1;
+
+
+void main()
+{
+ gl_FragColor = texture2D(u_DiffuseMap, var_Tex1) * u_Color;
+}
diff --git a/src/renderergl2/glsl/texturecolor_vp.glsl b/src/renderergl2/glsl/texturecolor_vp.glsl
new file mode 100644
index 0000000..552cd93
--- /dev/null
+++ b/src/renderergl2/glsl/texturecolor_vp.glsl
@@ -0,0 +1,13 @@
+attribute vec3 attr_Position;
+attribute vec4 attr_TexCoord0;
+
+uniform mat4 u_ModelViewProjectionMatrix;
+
+varying vec2 var_Tex1;
+
+
+void main()
+{
+ gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
+ var_Tex1 = attr_TexCoord0.st;
+}
diff --git a/src/renderergl2/glsl/tonemap_fp.glsl b/src/renderergl2/glsl/tonemap_fp.glsl
new file mode 100644
index 0000000..9e24e24
--- /dev/null
+++ b/src/renderergl2/glsl/tonemap_fp.glsl
@@ -0,0 +1,57 @@
+uniform sampler2D u_TextureMap;
+uniform sampler2D u_LevelsMap;
+
+uniform vec4 u_Color;
+
+
+uniform vec2 u_AutoExposureMinMax;
+uniform vec3 u_ToneMinAvgMaxLinear;
+
+varying vec2 var_TexCoords;
+varying float var_InvWhite;
+
+const vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721); //vec3(0.299, 0.587, 0.114);
+
+float FilmicTonemap(float x)
+{
+ const float SS = 0.22; // Shoulder Strength
+ const float LS = 0.30; // Linear Strength
+ const float LA = 0.10; // Linear Angle
+ const float TS = 0.20; // Toe Strength
+ const float TAN = 0.01; // Toe Angle Numerator
+ const float TAD = 0.30; // Toe Angle Denominator
+
+ return ((x*(SS*x+LA*LS)+TS*TAN)/(x*(SS*x+LS)+TS*TAD)) - TAN/TAD;
+}
+
+void main()
+{
+ vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color;
+
+#if defined(USE_PBR)
+ color.rgb *= color.rgb;
+#endif
+
+ vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb;
+ vec3 logMinAvgMaxLum = clamp(minAvgMax * 20.0 - 10.0, -u_AutoExposureMinMax.y, -u_AutoExposureMinMax.x);
+
+ float invAvgLum = u_ToneMinAvgMaxLinear.y * exp2(-logMinAvgMaxLum.y);
+
+ color.rgb = color.rgb * invAvgLum - u_ToneMinAvgMaxLinear.xxx;
+ color.rgb = max(vec3(0.0), color.rgb);
+
+ color.r = FilmicTonemap(color.r);
+ color.g = FilmicTonemap(color.g);
+ color.b = FilmicTonemap(color.b);
+
+ color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0);
+
+#if defined(USE_PBR)
+ color.rgb = sqrt(color.rgb);
+#endif
+
+ // add a bit of dither to reduce banding
+ color.rgb += vec3(1.0/510.0 * mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) - 1.0/1020.0);
+
+ gl_FragColor = color;
+}
diff --git a/src/renderergl2/glsl/tonemap_vp.glsl b/src/renderergl2/glsl/tonemap_vp.glsl
new file mode 100644
index 0000000..577c0a1
--- /dev/null
+++ b/src/renderergl2/glsl/tonemap_vp.glsl
@@ -0,0 +1,27 @@
+attribute vec3 attr_Position;
+attribute vec4 attr_TexCoord0;
+
+uniform mat4 u_ModelViewProjectionMatrix;
+uniform vec3 u_ToneMinAvgMaxLinear;
+
+varying vec2 var_TexCoords;
+varying float var_InvWhite;
+
+float FilmicTonemap(float x)
+{
+ const float SS = 0.22; // Shoulder Strength
+ const float LS = 0.30; // Linear Strength
+ const float LA = 0.10; // Linear Angle
+ const float TS = 0.20; // Toe Strength
+ const float TAN = 0.01; // Toe Angle Numerator
+ const float TAD = 0.30; // Toe Angle Denominator
+
+ return ((x*(SS*x+LA*LS)+TS*TAN)/(x*(SS*x+LS)+TS*TAD)) - TAN/TAD;
+}
+
+void main()
+{
+ gl_Position = u_ModelViewProjectionMatrix * vec4(attr_Position, 1.0);
+ var_TexCoords = attr_TexCoord0.st;
+ var_InvWhite = 1.0 / FilmicTonemap(u_ToneMinAvgMaxLinear.z - u_ToneMinAvgMaxLinear.x);
+}