diff options
Diffstat (limited to 'src/renderergl2/glsl')
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); +} |