{@}aastep.glsl{@}float aastep(float threshold, float value) { float afwidth = length(vec2(dFdx(value), dFdy(value))) * 0.70710678118654757; return smoothstep(threshold-afwidth, threshold+afwidth, value); } float aastep(float threshold, float value, float padding) { return smoothstep(threshold - padding, threshold + padding, value); } vec2 aastep(vec2 threshold, vec2 value) { return vec2( aastep(threshold.x, value.x), aastep(threshold.y, value.y) ); }{@}aspectuv.glsl{@}vec2 getAspectCoverScale(vec2 textureResolution, vec2 containerDimensions) { vec2 ratioX = vec2(1., textureResolution.x/textureResolution.y * containerDimensions.y/containerDimensions.x); vec2 ratioY = vec2(textureResolution.y/textureResolution.x * containerDimensions.x/containerDimensions.y, 1.); float which = step(ratioX.y , 1.); return mix(ratioY, ratioX, which); } vec2 aspectUV(vec2 uv, vec2 textureResolution, vec2 containerDimensions, vec2 align) { return (uv - align) * getAspectCoverScale(textureResolution, containerDimensions) + align; } vec2 aspectUV(vec2 uv, vec2 textureResolution, vec2 containerDimensions) { return aspectUV(uv, textureResolution, containerDimensions, vec2(0.5)); } {@}blendmodes.glsl{@}float blendColorDodge(float base, float blend) { return (blend == 1.0)?blend:min(base/(1.0-blend), 1.0); } vec3 blendColorDodge(vec3 base, vec3 blend) { return vec3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b)); } vec3 blendColorDodge(vec3 base, vec3 blend, float opacity) { return (blendColorDodge(base, blend) * opacity + base * (1.0 - opacity)); } float blendColorBurn(float base, float blend) { return (blend == 0.0)?blend:max((1.0-((1.0-base)/blend)), 0.0); } vec3 blendColorBurn(vec3 base, vec3 blend) { return vec3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b)); } vec3 blendColorBurn(vec3 base, vec3 blend, float opacity) { return (blendColorBurn(base, blend) * opacity + base * (1.0 - opacity)); } float blendVividLight(float base, float blend) { return (blend<0.5)?blendColorBurn(base, (2.0*blend)):blendColorDodge(base, (2.0*(blend-0.5))); } vec3 blendVividLight(vec3 base, vec3 blend) { return vec3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b)); } vec3 blendVividLight(vec3 base, vec3 blend, float opacity) { return (blendVividLight(base, blend) * opacity + base * (1.0 - opacity)); } float blendHardMix(float base, float blend) { return (blendVividLight(base, blend)<0.5)?0.0:1.0; } vec3 blendHardMix(vec3 base, vec3 blend) { return vec3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b)); } vec3 blendHardMix(vec3 base, vec3 blend, float opacity) { return (blendHardMix(base, blend) * opacity + base * (1.0 - opacity)); } float blendLinearDodge(float base, float blend) { return min(base+blend, 1.0); } vec3 blendLinearDodge(vec3 base, vec3 blend) { return min(base+blend, vec3(1.0)); } vec3 blendLinearDodge(vec3 base, vec3 blend, float opacity) { return (blendLinearDodge(base, blend) * opacity + base * (1.0 - opacity)); } float blendLinearBurn(float base, float blend) { return max(base+blend-1.0, 0.0); } vec3 blendLinearBurn(vec3 base, vec3 blend) { return max(base+blend-vec3(1.0), vec3(0.0)); } vec3 blendLinearBurn(vec3 base, vec3 blend, float opacity) { return (blendLinearBurn(base, blend) * opacity + base * (1.0 - opacity)); } float blendLinearLight(float base, float blend) { return blend<0.5?blendLinearBurn(base, (2.0*blend)):blendLinearDodge(base, (2.0*(blend-0.5))); } vec3 blendLinearLight(vec3 base, vec3 blend) { return vec3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b)); } vec3 blendLinearLight(vec3 base, vec3 blend, float opacity) { return (blendLinearLight(base, blend) * opacity + base * (1.0 - opacity)); } float blendLighten(float base, float blend) { return max(blend, base); } vec3 blendLighten(vec3 base, vec3 blend) { return vec3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b)); } vec3 blendLighten(vec3 base, vec3 blend, float opacity) { return (blendLighten(base, blend) * opacity + base * (1.0 - opacity)); } float blendDarken(float base, float blend) { return min(blend, base); } vec3 blendDarken(vec3 base, vec3 blend) { return vec3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b)); } vec3 blendDarken(vec3 base, vec3 blend, float opacity) { return (blendDarken(base, blend) * opacity + base * (1.0 - opacity)); } float blendPinLight(float base, float blend) { return (blend<0.5)?blendDarken(base, (2.0*blend)):blendLighten(base, (2.0*(blend-0.5))); } vec3 blendPinLight(vec3 base, vec3 blend) { return vec3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b)); } vec3 blendPinLight(vec3 base, vec3 blend, float opacity) { return (blendPinLight(base, blend) * opacity + base * (1.0 - opacity)); } float blendReflect(float base, float blend) { return (blend == 1.0)?blend:min(base*base/(1.0-blend), 1.0); } vec3 blendReflect(vec3 base, vec3 blend) { return vec3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b)); } vec3 blendReflect(vec3 base, vec3 blend, float opacity) { return (blendReflect(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendGlow(vec3 base, vec3 blend) { return blendReflect(blend, base); } vec3 blendGlow(vec3 base, vec3 blend, float opacity) { return (blendGlow(base, blend) * opacity + base * (1.0 - opacity)); } float blendOverlay(float base, float blend) { return base<0.5?(2.0*base*blend):(1.0-2.0*(1.0-base)*(1.0-blend)); } vec3 blendOverlay(vec3 base, vec3 blend) { return vec3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b)); } vec3 blendOverlay(vec3 base, vec3 blend, float opacity) { return (blendOverlay(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendHardLight(vec3 base, vec3 blend) { return blendOverlay(blend, base); } vec3 blendHardLight(vec3 base, vec3 blend, float opacity) { return (blendHardLight(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendPhoenix(vec3 base, vec3 blend) { return min(base, blend)-max(base, blend)+vec3(1.0); } vec3 blendPhoenix(vec3 base, vec3 blend, float opacity) { return (blendPhoenix(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendNormal(vec3 base, vec3 blend) { return blend; } vec3 blendNormal(vec3 base, vec3 blend, float opacity) { return (blendNormal(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendNegation(vec3 base, vec3 blend) { return vec3(1.0)-abs(vec3(1.0)-base-blend); } vec3 blendNegation(vec3 base, vec3 blend, float opacity) { return (blendNegation(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendMultiply(vec3 base, vec3 blend) { return base*blend; } vec3 blendMultiply(vec3 base, vec3 blend, float opacity) { return (blendMultiply(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendAverage(vec3 base, vec3 blend) { return (base+blend)/2.0; } vec3 blendAverage(vec3 base, vec3 blend, float opacity) { return (blendAverage(base, blend) * opacity + base * (1.0 - opacity)); } float blendScreen(float base, float blend) { return 1.0-((1.0-base)*(1.0-blend)); } vec3 blendScreen(vec3 base, vec3 blend) { return vec3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b)); } vec3 blendScreen(vec3 base, vec3 blend, float opacity) { return (blendScreen(base, blend) * opacity + base * (1.0 - opacity)); } float blendSoftLight(float base, float blend) { return (blend<0.5)?(2.0*base*blend+base*base*(1.0-2.0*blend)):(sqrt(base)*(2.0*blend-1.0)+2.0*base*(1.0-blend)); } vec3 blendSoftLight(vec3 base, vec3 blend) { return vec3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b)); } vec3 blendSoftLight(vec3 base, vec3 blend, float opacity) { return (blendSoftLight(base, blend) * opacity + base * (1.0 - opacity)); } float blendSubtract(float base, float blend) { return max(base+blend-1.0, 0.0); } vec3 blendSubtract(vec3 base, vec3 blend) { return max(base+blend-vec3(1.0), vec3(0.0)); } vec3 blendSubtract(vec3 base, vec3 blend, float opacity) { return (blendSubtract(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendExclusion(vec3 base, vec3 blend) { return base+blend-2.0*base*blend; } vec3 blendExclusion(vec3 base, vec3 blend, float opacity) { return (blendExclusion(base, blend) * opacity + base * (1.0 - opacity)); } vec3 blendDifference(vec3 base, vec3 blend) { return abs(base-blend); } vec3 blendDifference(vec3 base, vec3 blend, float opacity) { return (blendDifference(base, blend) * opacity + base * (1.0 - opacity)); } float blendAdd(float base, float blend) { return min(base+blend, 1.0); } vec3 blendAdd(vec3 base, vec3 blend) { return min(base+blend, vec3(1.0)); } vec3 blendAdd(vec3 base, vec3 blend, float opacity) { return (blendAdd(base, blend) * opacity + base * (1.0 - opacity)); }{@}conditionals.glsl{@}vec4 when_eq(vec4 x, vec4 y) { return 1.0 - abs(sign(x - y)); } vec4 when_neq(vec4 x, vec4 y) { return abs(sign(x - y)); } vec4 when_gt(vec4 x, vec4 y) { return max(sign(x - y), 0.0); } vec4 when_lt(vec4 x, vec4 y) { return max(sign(y - x), 0.0); } vec4 when_ge(vec4 x, vec4 y) { return 1.0 - when_lt(x, y); } vec4 when_le(vec4 x, vec4 y) { return 1.0 - when_gt(x, y); } vec3 when_eq(vec3 x, vec3 y) { return 1.0 - abs(sign(x - y)); } vec3 when_neq(vec3 x, vec3 y) { return abs(sign(x - y)); } vec3 when_gt(vec3 x, vec3 y) { return max(sign(x - y), 0.0); } vec3 when_lt(vec3 x, vec3 y) { return max(sign(y - x), 0.0); } vec3 when_ge(vec3 x, vec3 y) { return 1.0 - when_lt(x, y); } vec3 when_le(vec3 x, vec3 y) { return 1.0 - when_gt(x, y); } vec2 when_eq(vec2 x, vec2 y) { return 1.0 - abs(sign(x - y)); } vec2 when_neq(vec2 x, vec2 y) { return abs(sign(x - y)); } vec2 when_gt(vec2 x, vec2 y) { return max(sign(x - y), 0.0); } vec2 when_lt(vec2 x, vec2 y) { return max(sign(y - x), 0.0); } vec2 when_ge(vec2 x, vec2 y) { return 1.0 - when_lt(x, y); } vec2 when_le(vec2 x, vec2 y) { return 1.0 - when_gt(x, y); } float when_eq(float x, float y) { return 1.0 - abs(sign(x - y)); } float when_neq(float x, float y) { return abs(sign(x - y)); } float when_gt(float x, float y) { return max(sign(x - y), 0.0); } float when_lt(float x, float y) { return max(sign(y - x), 0.0); } float when_ge(float x, float y) { return 1.0 - when_lt(x, y); } float when_le(float x, float y) { return 1.0 - when_gt(x, y); } vec4 and(vec4 a, vec4 b) { return a * b; } vec4 or(vec4 a, vec4 b) { return min(a + b, 1.0); } vec4 Not(vec4 a) { return 1.0 - a; } vec3 and(vec3 a, vec3 b) { return a * b; } vec3 or(vec3 a, vec3 b) { return min(a + b, 1.0); } vec3 Not(vec3 a) { return 1.0 - a; } vec2 and(vec2 a, vec2 b) { return a * b; } vec2 or(vec2 a, vec2 b) { return min(a + b, 1.0); } vec2 Not(vec2 a) { return 1.0 - a; } float and(float a, float b) { return a * b; } float or(float a, float b) { return min(a + b, 1.0); } float Not(float a) { return 1.0 - a; }{@}depthvalue.fs{@}float getDepthValue(sampler2D tDepth, vec2 uv, float n, float f) { vec4 depth = texture2D(tDepth, uv); return (2.0 * n) / (f + n - depth.x * (f - n)); } float getDepthValue(float z, float n, float f) { return (2.0 * n) / (f + n - z * (f - n)); } float getEyeZ(float depth, float n, float f) { float z = depth * 2.0 - 1.0; return (2.0 * n * f) / (f + n - z * (f - n)); } vec3 eyePosFromDepth(sampler2D tDepth, vec2 c, float n, float f) { float eyeZ = getEyeZ(texelFetch(tDepth, ivec2(gl_FragCoord.xy), 0).x, n, f); float x = ((1.0 - projectionMatrix[2][0]) / projectionMatrix[0][0]) - (2.0 * (c.x + 0.5) / (resolution.x * projectionMatrix[0][0])); float y = ((1.0 + projectionMatrix[2][1]) / projectionMatrix[1][1]) - (2.0 * (c.y + 0.5) / (resolution.y * projectionMatrix[1][1])); return vec3(vec2(x,y) * -eyeZ, -eyeZ); } vec3 eyePosFromDepth(float depth, float n, float f, vec2 c, bool linearDepth) { float eyeZ = linearDepth ? depth : getEyeZ(depth, n, f); float x = ((1.0 - projectionMatrix[2][0]) / projectionMatrix[0][0]) - (2.0 * (c.x + 0.5) / (resolution.x * projectionMatrix[0][0])); float y = ((1.0 + projectionMatrix[2][1]) / projectionMatrix[1][1]) - (2.0 * (c.y + 0.5) / (resolution.y * projectionMatrix[1][1])); return vec3(vec2(x,y) * -eyeZ, -eyeZ); } vec3 worldPosFromDepth(sampler2D tDepth) { float depth = texture2D(tDepth, vUv).r; float z = depth * 2.0 - 1.0; vec4 clipSpacePosition = vec4(vUv * 2.0 - 1.0, z, 1.0); vec4 viewSpacePosition = inverse(projectionMatrix) * clipSpacePosition; // Perspective division viewSpacePosition /= viewSpacePosition.w; vec4 worldSpacePosition = inverse(viewMatrix) * viewSpacePosition; return worldSpacePosition.xyz; }{@}eases.glsl{@}#ifndef PI #define PI 3.141592653589793 #endif #ifndef HALF_PI #define HALF_PI 1.5707963267948966 #endif float backInOut(float t) { float f = t < 0.5 ? 2.0 * t : 1.0 - (2.0 * t - 1.0); float g = pow(f, 3.0) - f * sin(f * PI); return t < 0.5 ? 0.5 * g : 0.5 * (1.0 - g) + 0.5; } float backIn(float t) { return pow(t, 3.0) - t * sin(t * PI); } float backOut(float t) { float f = 1.0 - t; return 1.0 - (pow(f, 3.0) - f * sin(f * PI)); } float bounceOut(float t) { const float a = 4.0 / 11.0; const float b = 8.0 / 11.0; const float c = 9.0 / 10.0; const float ca = 4356.0 / 361.0; const float cb = 35442.0 / 1805.0; const float cc = 16061.0 / 1805.0; float t2 = t * t; return t < a ? 7.5625 * t2 : t < b ? 9.075 * t2 - 9.9 * t + 3.4 : t < c ? ca * t2 - cb * t + cc : 10.8 * t * t - 20.52 * t + 10.72; } float bounceIn(float t) { return 1.0 - bounceOut(1.0 - t); } float bounceInOut(float t) { return t < 0.5 ? 0.5 * (1.0 - bounceOut(1.0 - t * 2.0)) : 0.5 * bounceOut(t * 2.0 - 1.0) + 0.5; } float circularInOut(float t) { return t < 0.5 ? 0.5 * (1.0 - sqrt(1.0 - 4.0 * t * t)) : 0.5 * (sqrt((3.0 - 2.0 * t) * (2.0 * t - 1.0)) + 1.0); } float circularIn(float t) { return 1.0 - sqrt(1.0 - t * t); } float circularOut(float t) { return sqrt((2.0 - t) * t); } float cubicInOut(float t) { return t < 0.5 ? 4.0 * t * t * t : 0.5 * -pow(2.0 - 2.0 * t, 3.0) + 1.0; } float cubicIn(float t) { return t * t * t; } float cubicOut(float t) { float f = t - 1.0; return f * f * f + 1.0; } float elasticInOut(float t) { return t < 0.5 ? 0.5 * sin(+13.0 * HALF_PI * 2.0 * t) * pow(2.0, 10.0 * (2.0 * t - 1.0)) : 0.5 * sin(-13.0 * HALF_PI * ((2.0 * t - 1.0) + 1.0)) * pow(2.0, -10.0 * (2.0 * t - 1.0)) + 1.0; } float elasticIn(float t) { return sin(13.0 * t * HALF_PI) * pow(2.0, 10.0 * (t - 1.0)); } float elasticOut(float t) { return sin(-13.0 * (t + 1.0) * HALF_PI) * pow(2.0, -10.0 * t) + 1.0; } float expoInOut(float t) { return t == 0.0 || t == 1.0 ? t : t < 0.5 ? +0.5 * pow(2.0, (20.0 * t) - 10.0) : -0.5 * pow(2.0, 10.0 - (t * 20.0)) + 1.0; } float expoIn(float t) { return t == 0.0 ? t : pow(2.0, 10.0 * (t - 1.0)); } float expoOut(float t) { return t == 1.0 ? t : 1.0 - pow(2.0, -10.0 * t); } float linear(float t) { return t; } float quadraticInOut(float t) { float p = 2.0 * t * t; return t < 0.5 ? p : -p + (4.0 * t) - 1.0; } float quadraticIn(float t) { return t * t; } float quadraticOut(float t) { return -t * (t - 2.0); } float quarticInOut(float t) { return t < 0.5 ? +8.0 * pow(t, 4.0) : -8.0 * pow(1.0 - t, 4.0) + 1.0; } float quarticIn(float t) { return pow(t, 4.0); } float quarticOut(float t) { return pow(1.0 - t, 3.0) * (t - 1.0) + 1.0; } float qinticInOut(float t) { return t < 0.5 ? +16.0 * pow(t, 5.0) : -0.5 * pow(2.0 * t - 2.0, 5.0) + 1.0; } float qinticIn(float t) { return pow(t, 5.0); } float qinticOut(float t) { return 1.0 - (pow(1.0 - t, 5.0)); } float sineInOut(float t) { return -0.5 * (cos(PI * t) - 1.0); } float sineIn(float t) { return sin((t - 1.0) * HALF_PI) + 1.0; } float sineOut(float t) { return sin(t * HALF_PI); } {@}ColorMaterial.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform vec3 color; uniform float alpha; #!VARYINGS #!SHADER: ColorMaterial.vs void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: ColorMaterial.fs void main() { gl_FragColor = vec4(color, alpha); }{@}DebugCamera.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform vec3 uColor; #!VARYINGS varying vec3 vColor; #!SHADER: DebugCamera.vs void main() { vColor = mix(uColor, vec3(1.0, 0.0, 0.0), step(position.z, -0.1)); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: DebugCamera.fs void main() { gl_FragColor = vec4(vColor, 1.0); }{@}OcclusionMaterial.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform vec3 bbMin; uniform vec3 bbMax; #!VARYINGS #!SHADER: Vertex.vs void main() { vec3 pos = position; pos *= bbMax - bbMin; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: Fragment.fs void main() { gl_FragColor = vec4(1.0); }{@}ScreenQuad.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; #!VARYINGS #!SHADER: ScreenQuad.vs void main() { gl_Position = vec4(position, 1.0); } #!SHADER: ScreenQuad.fs void main() { gl_FragColor = texture2D(tMap, gl_FragCoord.xy / resolution); gl_FragColor.a = 1.0; }{@}ScreenQuadVR.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform float uEye; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex vec2 scaleUV(vec2 uv, vec2 scale, vec2 origin) { vec2 st = uv - origin; st /= scale; return st + origin; } void main() { vUv = scaleUV(uv, vec2(2.0, 1.0), vec2(0.0)) - vec2(uEye, 0.0); gl_Position = vec4(position, 1.0); } #!SHADER: Fragment void main() { gl_FragColor = texture2D(tMap, vUv); }{@}TestMaterial.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform float alpha; #!VARYINGS varying vec3 vNormal; #!SHADER: TestMaterial.vs void main() { vec3 pos = position; vNormal = normalMatrix * normal; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: TestMaterial.fs void main() { gl_FragColor = vec4(vNormal, 1.0); }{@}TextureMaterial.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; #!VARYINGS varying vec2 vUv; #!SHADER: TextureMaterial.vs void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: TextureMaterial.fs void main() { gl_FragColor = texture2D(tMap, vUv); gl_FragColor.rgb /= gl_FragColor.a; }{@}BlitPass.fs{@}void main() { gl_FragColor = texture2D(tDiffuse, vUv); gl_FragColor.a = 1.0; }{@}NukePass.vs{@}varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0); }{@}ShadowDepth.glsl{@}#!ATTRIBUTES #!UNIFORMS #!VARYINGS #!SHADER: ShadowDepth.vs void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: ShadowDepth.fs void main() { gl_FragColor = vec4(vec3(gl_FragCoord.x), 1.0); }{@}instance.vs{@}vec3 transformNormal(vec3 n, vec4 orientation) { vec3 nn = n + 2.0 * cross(orientation.xyz, cross(orientation.xyz, n) + orientation.w * n); return nn; } vec3 transformPosition(vec3 position, vec3 offset, vec3 scale, vec4 orientation) { vec3 _pos = position; _pos *= scale; _pos = _pos + 2.0 * cross(orientation.xyz, cross(orientation.xyz, _pos) + orientation.w * _pos); _pos += offset; return _pos; } vec3 transformPosition(vec3 position, vec3 offset, vec4 orientation) { vec3 _pos = position; _pos = _pos + 2.0 * cross(orientation.xyz, cross(orientation.xyz, _pos) + orientation.w * _pos); _pos += offset; return _pos; } vec3 transformPosition(vec3 position, vec3 offset, float scale, vec4 orientation) { return transformPosition(position, offset, vec3(scale), orientation); } vec3 transformPosition(vec3 position, vec3 offset) { return position + offset; } vec3 transformPosition(vec3 position, vec3 offset, float scale) { vec3 pos = position * scale; return pos + offset; } vec3 transformPosition(vec3 position, vec3 offset, vec3 scale) { vec3 pos = position * scale; return pos + offset; }{@}lights.fs{@}vec3 worldLight(vec3 pos, vec3 vpos) { vec4 mvPos = modelViewMatrix * vec4(vpos, 1.0); vec4 worldPosition = viewMatrix * vec4(pos, 1.0); return worldPosition.xyz - mvPos.xyz; }{@}lights.vs{@}vec3 worldLight(vec3 pos) { vec4 mvPos = modelViewMatrix * vec4(position, 1.0); vec4 worldPosition = viewMatrix * vec4(pos, 1.0); return worldPosition.xyz - mvPos.xyz; } vec3 worldLight(vec3 lightPos, vec3 localPos) { vec4 mvPos = modelViewMatrix * vec4(localPos, 1.0); vec4 worldPosition = viewMatrix * vec4(lightPos, 1.0); return worldPosition.xyz - mvPos.xyz; }{@}shadows.fs{@}#define PI2 6.2831853072 #define PI 3.141592653589793 #define MAX_PCSS_SAMPLES 17 vec2 poissonDisk[MAX_PCSS_SAMPLES]; struct PCSShadowConfig { int sampleCount; int ringCount; float lightWorldSize; float lightFrustumWidth; float nearPlane; }; PCSShadowConfig defaultPCSSShadowConfig() { PCSShadowConfig config; config.sampleCount = 10; config.ringCount = 11; config.lightWorldSize = 0.3; config.lightFrustumWidth = 6.75; config.nearPlane = 6.5; return config; } bool frustumTest(vec3 coords) { return coords.x >= 0.0 && coords.x <= 1.0 && coords.y >= 0.0 && coords.y <= 1.0 && coords.z <= 1.0; } float rand(float n){return fract(sin(n) * 43758.5453123);} highp float rand( const in vec2 uv ) { const highp float a = 12.9898, b = 78.233, c = 43758.5453; highp float dt = dot( uv.xy, vec2( a, b ) ), sn = mod( dt, PI ); return fract( sin( sn ) * c ); } void initPoissonSamples(const in vec2 randomSeed, PCSShadowConfig config) { float angleStep = PI2 * float(config.ringCount) / float(config.sampleCount); float invSampleCount = 1.0 / float(config.sampleCount); float angle = rand(randomSeed) * PI2; float radius = invSampleCount; float radiusStep = radius; for(int i = 0; i < MAX_PCSS_SAMPLES; i ++ ) { if( i > config.sampleCount ) { break; } poissonDisk[i] = vec2(cos(angle), sin(angle)) * pow(radius, 0.75); radius += radiusStep; angle += angleStep; } } float penumbraSize(const in float zReceiver, const in float zBlocker) { return (zReceiver - zBlocker) / zBlocker; } float findBlocker(sampler2D shadowMap, const in vec2 uv, const in float zReceiver, PCSShadowConfig config) { // This uses similar triangles to compute what // area of the shadow map we should search float lightSizeUV = config.lightWorldSize / config.lightFrustumWidth; float searchRadius = lightSizeUV * (zReceiver - config.nearPlane) / zReceiver; float blockerDepthSum = 0.0; int numBlockers = 0; for(int i = 0; i < MAX_PCSS_SAMPLES; i ++ ) { if( i > config.sampleCount ) { break; } float shadowMapDepth = texture2D(shadowMap, uv + poissonDisk[i] * searchRadius).r; if (shadowMapDepth < zReceiver) { blockerDepthSum += shadowMapDepth; numBlockers ++ ; } } if (numBlockers == 0)return -1.0; return blockerDepthSum / float(numBlockers); } float pcfFilter(sampler2D shadowMap, vec2 uv, float zReceiver, float filterRadius, PCSShadowConfig config) { float sum = 0.0; float depth; int numSamples = config.sampleCount; for(int i = 0; i < MAX_PCSS_SAMPLES; i ++ ) { if( i > numSamples ) { break; } depth = texture2D(shadowMap, uv + poissonDisk[i] * filterRadius).r; if (zReceiver <= depth) sum += 1.0; } for(int i = 0; i < MAX_PCSS_SAMPLES; i ++ ) { if( i > numSamples ) { break; } depth = texture2D(shadowMap, uv + -poissonDisk[i].yx * filterRadius).r; if (zReceiver <= depth) sum += 1.0; } return sum / (2.0 * float(numSamples)); } float PCSS(sampler2D shadowMap, vec3 coords, PCSShadowConfig config) { vec2 uv = coords.xy; float zReceiver = coords.z; // Assumed to be eye-space z in this code initPoissonSamples(uv, config); float avgBlockerDepth = findBlocker(shadowMap, uv, zReceiver, config); if (avgBlockerDepth == -1.0)return 1.0; float penumbraRatio = penumbraSize(zReceiver, avgBlockerDepth); float lightSizeUV = config.lightWorldSize / config.lightFrustumWidth; float filterRadius = penumbraRatio * lightSizeUV * config.nearPlane / zReceiver; return pcfFilter(shadowMap, uv, zReceiver, filterRadius, config); } float shadowLookupPCSS(sampler2D map, vec3 coords, float size, float compare, vec3 wpos, PCSShadowConfig config) { float shadow = 1.0; bool frustumTest = frustumTest(coords); if (frustumTest) { shadow = PCSS(map, coords, config); } return clamp(shadow, 0.0, 1.0); } float shadowCompare(sampler2D map, vec2 coords, float compare) { return step(compare, texture2D(map, coords).r); } float shadowLerp(sampler2D map, vec2 coords, float compare, float size) { const vec2 offset = vec2(0.0, 1.0); vec2 texelSize = vec2(1.0) / size; vec2 centroidUV = floor(coords * size + 0.5) / size; float lb = shadowCompare(map, centroidUV + texelSize * offset.xx, compare); float lt = shadowCompare(map, centroidUV + texelSize * offset.xy, compare); float rb = shadowCompare(map, centroidUV + texelSize * offset.yx, compare); float rt = shadowCompare(map, centroidUV + texelSize * offset.yy, compare); vec2 f = fract( coords * size + 0.5 ); float a = mix( lb, lt, f.y ); float b = mix( rb, rt, f.y ); float c = mix( a, b, f.x ); return c; } float srange(float oldValue, float oldMin, float oldMax, float newMin, float newMax) { float oldRange = oldMax - oldMin; float newRange = newMax - newMin; return (((oldValue - oldMin) * newRange) / oldRange) + newMin; } float shadowrandom(vec3 vin) { vec3 v = vin * 0.1; float t = v.z * 0.3; v.y *= 0.8; float noise = 0.0; float s = 0.5; noise += srange(sin(v.x * 0.9 / s + t * 10.0) + sin(v.x * 2.4 / s + t * 15.0) + sin(v.x * -3.5 / s + t * 4.0) + sin(v.x * -2.5 / s + t * 7.1), -1.0, 1.0, -0.3, 0.3); noise += srange(sin(v.y * -0.3 / s + t * 18.0) + sin(v.y * 1.6 / s + t * 18.0) + sin(v.y * 2.6 / s + t * 8.0) + sin(v.y * -2.6 / s + t * 4.5), -1.0, 1.0, -0.3, 0.3); return noise; } float shadowLookup(sampler2D map, vec3 coords, float size, float compare, vec3 wpos) { float shadow = 1.0; #if defined(SHADOW_MAPS) bool frustumTest = coords.x >= 0.0 && coords.x <= 1.0 && coords.y >= 0.0 && coords.y <= 1.0 && coords.z <= 1.0; if (frustumTest) { vec2 texelSize = vec2(1.0) / size; float dx0 = -texelSize.x; float dy0 = -texelSize.y; float dx1 = +texelSize.x; float dy1 = +texelSize.y; float rnoise = shadowrandom(wpos) * 0.00015; dx0 += rnoise; dy0 -= rnoise; dx1 += rnoise; dy1 -= rnoise; #if defined(SHADOWS_MED) shadow += shadowCompare(map, coords.xy + vec2(0.0, dy0), compare); // shadow += shadowCompare(map, coords.xy + vec2(dx1, dy0), compare); shadow += shadowCompare(map, coords.xy + vec2(dx0, 0.0), compare); shadow += shadowCompare(map, coords.xy, compare); shadow += shadowCompare(map, coords.xy + vec2(dx1, 0.0), compare); // shadow += shadowCompare(map, coords.xy + vec2(dx0, dy1), compare); shadow += shadowCompare(map, coords.xy + vec2(0.0, dy1), compare); shadow /= 5.0; #elif defined(SHADOWS_HIGH) shadow = shadowLerp(map, coords.xy + vec2(dx0, dy0), compare, size); shadow += shadowLerp(map, coords.xy + vec2(0.0, dy0), compare, size); shadow += shadowLerp(map, coords.xy + vec2(dx1, dy0), compare, size); shadow += shadowLerp(map, coords.xy + vec2(dx0, 0.0), compare, size); shadow += shadowLerp(map, coords.xy, compare, size); shadow += shadowLerp(map, coords.xy + vec2(dx1, 0.0), compare, size); shadow += shadowLerp(map, coords.xy + vec2(dx0, dy1), compare, size); shadow += shadowLerp(map, coords.xy + vec2(0.0, dy1), compare, size); shadow += shadowLerp(map, coords.xy + vec2(dx1, dy1), compare, size); shadow /= 9.0; #else shadow = shadowCompare(map, coords.xy, compare); #endif } #endif return clamp(shadow, 0.0, 1.0); } #test !!window.Metal vec3 transformShadowLight(vec3 pos, vec3 vpos, mat4 mvMatrix, mat4 viewMatrix) { vec4 mvPos = mvMatrix * vec4(vpos, 1.0); vec4 worldPosition = viewMatrix * vec4(pos, 1.0); return normalize(worldPosition.xyz - mvPos.xyz); } float getShadow(vec3 pos, vec3 normal, float bias, Uniforms uniforms, GlobalUniforms globalUniforms, sampler2D shadowMap) { float shadow = 1.0; #if defined(SHADOW_MAPS) vec4 shadowMapCoords; vec3 coords; float lookup; for (int i = 0; i < SHADOW_COUNT; i++) { shadowMapCoords = uniforms.shadowMatrix[i] * vec4(pos, 1.0); coords = (shadowMapCoords.xyz / shadowMapCoords.w) * vec3(0.5) + vec3(0.5); lookup = shadowLookup(shadowMap, coords, uniforms.shadowSize[i], coords.z - bias, pos); lookup += mix(1.0 - step(0.002, dot(transformShadowLight(uniforms.shadowLightPos[i], pos, uniforms.modelViewMatrix, globalUniforms.viewMatrix), normal)), 0.0, step(999.0, normal.x)); shadow *= clamp(lookup, 0.0, 1.0); } #endif return shadow; } float getShadow(vec3 pos, vec3 normal, Uniforms uniforms, GlobalUniforms globalUniforms, sampler2D shadowMap) { return getShadow(pos, normal, 0.0, uniforms, globalUniforms, shadowMap); } float getShadow(vec3 pos, float bias, Uniforms uniforms, GlobalUniforms globalUniforms, sampler2D shadowMap) { return getShadow(pos, vec3(99999.0), bias, uniforms, globalUniforms, shadowMap); } float getShadow(vec3 pos, Uniforms uniforms, GlobalUniforms globalUniforms, sampler2D shadowMap) { return getShadow(pos, vec3(99999.0), 0.0, uniforms, globalUniforms, shadowMap); } float getShadow(vec3 pos, vec3 normal) { return 1.0; } float getShadow(vec3 pos, float bias) { return 1.0; } float getShadow(vec3 pos) { return 1.0; } float getShadowPCSS(vec3 pos, vec3 normal, Uniforms uniforms, GlobalUniforms globalUniforms, sampler2D shadowMap, PCSShadowConfig config) { float shadow = 1.0; #if defined(SHADOW_MAPS) vec4 shadowMapCoords; vec3 coords; float lookup; for (int i = 0; i < SHADOW_COUNT; i++) { shadowMapCoords = uniforms.shadowMatrix[i] * vec4(pos, 1.0); coords = (shadowMapCoords.xyz / shadowMapCoords.w) * vec3(0.5) + vec3(0.5); lookup = shadowLookupPCSS(shadowMap, coords, uniforms.shadowSize[i], coords.z - bias, pos); lookup += mix(1.0 - step(0.002, dot(transformShadowLight(uniforms.shadowLightPos[i], pos, uniforms.modelViewMatrix, globalUniforms.viewMatrix), normal)), 0.0, step(999.0, normal.x)); shadow *= clamp(lookup, 0.0, 1.0); } #endif return shadow; } float getShadowPCSS(vec3 pos, vec3 normal, Uniforms uniforms, GlobalUniforms globalUniforms, sampler2D shadowMap) { PCSShadowConfig config = defaultPCSSShadowConfig(); return getShadowPCSS(pos, normal, bias, config); } #endtest #test !window.Metal vec3 transformShadowLight(vec3 pos, vec3 vpos) { vec4 mvPos = modelViewMatrix * vec4(vpos, 1.0); vec4 worldPosition = viewMatrix * vec4(pos, 1.0); return normalize(worldPosition.xyz - mvPos.xyz); } float getShadow(vec3 pos, vec3 normal, float bias) { float shadow = 1.0; #if defined(SHADOW_MAPS) vec4 shadowMapCoords; vec3 coords; float lookup; #pragma unroll_loop for (int i = 0; i < SHADOW_COUNT; i++) { shadowMapCoords = shadowMatrix[i] * vec4(pos, 1.0); coords = (shadowMapCoords.xyz / shadowMapCoords.w) * vec3(0.5) + vec3(0.5); lookup = shadowLookup(shadowMap[i], coords, shadowSize[i], coords.z - bias, pos); lookup += mix(1.0 - step(0.002, dot(transformShadowLight(shadowLightPos[i], pos), normal)), 0.0, step(999.0, normal.x)); shadow *= clamp(lookup, 0.0, 1.0); } #endif return shadow; } float getShadow(vec3 pos, vec3 normal) { return getShadow(pos, normal, 0.0); } float getShadow(vec3 pos, float bias) { return getShadow(pos, vec3(99999.0), bias); } float getShadow(vec3 pos) { return getShadow(pos, vec3(99999.0), 0.0); } float getShadowPCSS(vec3 pos, vec3 normal, float bias, PCSShadowConfig config) { float shadow = 1.0; #if defined(SHADOW_MAPS) vec4 shadowMapCoords; vec3 coords; float lookup; #pragma unroll_loop for (int i = 0; i < SHADOW_COUNT; i++) { shadowMapCoords = shadowMatrix[i] * vec4(pos, 1.0); coords = (shadowMapCoords.xyz / shadowMapCoords.w) * vec3(0.5) + vec3(0.5); lookup = shadowLookupPCSS(shadowMap[i], coords, shadowSize[i], coords.z - bias, pos, config); lookup += mix(1.0 - step(0.002, dot(transformShadowLight(shadowLightPos[i], pos), normal)), 0.0, step(999.0, normal.x)); shadow *= clamp(lookup, 0.0, 1.0); } #endif return shadow; } float getShadowPCSS(vec3 pos, vec3 normal, float bias) { PCSShadowConfig config = defaultPCSSShadowConfig(); return getShadowPCSS(pos, normal, bias, config); } #endtest{@}FXAA.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMask; #!VARYINGS varying vec2 v_rgbNW; varying vec2 v_rgbNE; varying vec2 v_rgbSW; varying vec2 v_rgbSE; varying vec2 v_rgbM; #!SHADER: FXAA.vs varying vec2 vUv; void main() { vUv = uv; vec2 fragCoord = uv * resolution; vec2 inverseVP = 1.0 / resolution.xy; v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; v_rgbM = vec2(fragCoord * inverseVP); gl_Position = vec4(position, 1.0); } #!SHADER: FXAA.fs #require(conditionals.glsl) #ifndef FXAA_REDUCE_MIN #define FXAA_REDUCE_MIN (1.0/ 128.0) #endif #ifndef FXAA_REDUCE_MUL #define FXAA_REDUCE_MUL (1.0 / 8.0) #endif #ifndef FXAA_SPAN_MAX #define FXAA_SPAN_MAX 8.0 #endif vec4 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution, vec2 v_rgbNW, vec2 v_rgbNE, vec2 v_rgbSW, vec2 v_rgbSE, vec2 v_rgbM) { vec4 color; mediump vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y); vec3 rgbNW = texture2D(tex, v_rgbNW).xyz; vec3 rgbNE = texture2D(tex, v_rgbNE).xyz; vec3 rgbSW = texture2D(tex, v_rgbSW).xyz; vec3 rgbSE = texture2D(tex, v_rgbSE).xyz; vec4 texColor = texture2D(tex, v_rgbM); vec3 rgbM = texColor.xyz; vec3 luma = vec3(0.299, 0.587, 0.114); float lumaNW = dot(rgbNW, luma); float lumaNE = dot(rgbNE, luma); float lumaSW = dot(rgbSW, luma); float lumaSE = dot(rgbSE, luma); float lumaM = dot(rgbM, luma); float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); mediump vec2 dir; dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * inverseVP; vec3 rgbA = 0.5 * ( texture2D(tex, fragCoord * inverseVP + dir * (1.0 / 3.0 - 0.5)).xyz + texture2D(tex, fragCoord * inverseVP + dir * (2.0 / 3.0 - 0.5)).xyz); vec3 rgbB = rgbA * 0.5 + 0.25 * ( texture2D(tex, fragCoord * inverseVP + dir * -0.5).xyz + texture2D(tex, fragCoord * inverseVP + dir * 0.5).xyz); float lumaB = dot(rgbB, luma); color = vec4(rgbB, texColor.a); color = mix(color, vec4(rgbA, texColor.a), when_lt(lumaB, lumaMin)); color = mix(color, vec4(rgbA, texColor.a), when_gt(lumaB, lumaMax)); return color; } void main() { vec2 fragCoord = vUv * resolution; float mask = texture2D(tMask, vUv).r; if (mask < 0.5) { gl_FragColor = fxaa(tDiffuse, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); } else { gl_FragColor = texture2D(tDiffuse, vUv); } gl_FragColor.a = 1.0; } {@}DefaultText.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform vec3 uColor; uniform float uAlpha; #!VARYINGS varying vec2 vUv; #!SHADER: DefaultText.vs void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: DefaultText.fs #require(msdf.glsl) void main() { float alpha = msdf(tMap, vUv); gl_FragColor.rgb = uColor; gl_FragColor.a = alpha * uAlpha; } {@}msdf.glsl{@}float msdf(vec3 tex, vec2 uv, bool discards) { // TODO: fallback for fwidth for webgl1 (need to enable ext) float signedDist = max(min(tex.r, tex.g), min(max(tex.r, tex.g), tex.b)) - 0.5; float d = fwidth(signedDist); float alpha = smoothstep(-d, d, signedDist); if (alpha < 0.01 && discards) discard; return alpha; } float msdf(sampler2D tMap, vec2 uv, bool discards) { vec3 tex = texture2D(tMap, uv).rgb; return msdf( tex, uv, discards ); } float msdf(vec3 tex, vec2 uv) { return msdf( tex, uv, true ); } float msdf(sampler2D tMap, vec2 uv) { vec3 tex = texture2D(tMap, uv).rgb; return msdf( tex, uv ); } float strokemsdf(sampler2D tMap, vec2 uv, float stroke, float padding) { vec3 tex = texture2D(tMap, uv).rgb; float signedDist = max(min(tex.r, tex.g), min(max(tex.r, tex.g), tex.b)) - 0.5; float t = stroke; float alpha = smoothstep(-t, -t + padding, signedDist) * smoothstep(t, t - padding, signedDist); return alpha; } {@}GLUIBatch.glsl{@}#!ATTRIBUTES attribute vec3 offset; attribute vec2 scale; attribute float rotation; //attributes #!UNIFORMS uniform sampler2D tMap; uniform vec3 uColor; uniform float uAlpha; #!VARYINGS varying vec2 vUv; //varyings #!SHADER: Vertex mat4 rotationMatrix(vec3 axis, float angle) { axis = normalize(axis); float s = sin(angle); float c = cos(angle); float oc = 1.0 - c; return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0); } void main() { vUv = uv; //vdefines vec3 pos = vec3(rotationMatrix(vec3(0.0, 0.0, 1.0), rotation) * vec4(position, 1.0)); pos.xy *= scale; pos.xyz += offset; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: Fragment void main() { gl_FragColor = vec4(1.0); }{@}GLUIBatchText.glsl{@}#!ATTRIBUTES attribute vec3 offset; attribute vec2 scale; attribute float rotation; //attributes #!UNIFORMS uniform sampler2D tMap; uniform vec3 uColor; uniform float uAlpha; #!VARYINGS varying vec2 vUv; //varyings #!SHADER: Vertex mat4 lrotationMatrix(vec3 axis, float angle) { axis = normalize(axis); float s = sin(angle); float c = cos(angle); float oc = 1.0 - c; return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0); } void main() { vUv = uv; //vdefines vec3 pos = vec3(lrotationMatrix(vec3(0.0, 0.0, 1.0), rotation) * vec4(position, 1.0)); //custommain pos.xy *= scale; pos += offset; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: Fragment #require(msdf.glsl) void main() { float alpha = msdf(tMap, vUv); gl_FragColor.rgb = v_uColor; gl_FragColor.a = alpha * v_uAlpha; } {@}GLUIColor.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform vec3 uColor; uniform float uAlpha; #!VARYINGS varying vec2 vUv; #!SHADER: GLUIColor.vs void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: GLUIColor.fs void main() { vec2 uv = vUv; vec3 uvColor = vec3(uv, 1.0); gl_FragColor = vec4(mix(uColor, uvColor, 0.0), uAlpha); }{@}GLUIObject.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform float uAlpha; #!VARYINGS varying vec2 vUv; #!SHADER: GLUIObject.vs void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: GLUIObject.fs void main() { gl_FragColor = texture2D(tMap, vUv); gl_FragColor.a *= uAlpha; }{@}gluimask.fs{@}uniform vec4 uMaskValues; #require(range.glsl) vec2 getMaskUV() { vec2 ores = gl_FragCoord.xy / resolution; vec2 uv; uv.x = range(ores.x, uMaskValues.x, uMaskValues.z, 0.0, 1.0); uv.y = 1.0 - range(1.0 - ores.y, uMaskValues.y, uMaskValues.w, 0.0, 1.0); return uv; }{@}luma.fs{@}float luma(vec3 color) { return dot(color, vec3(0.299, 0.587, 0.114)); } float luma(vec4 color) { return dot(color.rgb, vec3(0.299, 0.587, 0.114)); }{@}PBR.glsl{@}#!ATTRIBUTES #!UNIFORMS #!VARYINGS #!SHADER: Vertex #require(pbr.vs) void main() { vec3 pos = position; setupPBR(pos); gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: Fragment #require(pbr.fs) void main() { gl_FragColor = getPBR(); } {@}pbr.fs{@}uniform sampler2D tBaseColor; uniform sampler2D tMRO; uniform sampler2D tNormal; uniform sampler2D tLUT; uniform sampler2D tEnvDiffuse; uniform sampler2D tEnvSpecular; uniform vec2 uEnvOffset; uniform sampler2D tLightmap; uniform float uUseLightmap; uniform float uLightmapIntensity; uniform float uUseLinearOutput; uniform vec3 uTint; uniform vec2 uTiling; uniform vec2 uOffset; uniform vec4 uMRON; uniform vec3 uEnv; uniform float uHDR; varying vec2 vUv; varying vec2 vUv2; varying vec3 vV; varying vec3 vWorldNormal; vec3 unpackNormalPBR( vec3 eye_pos, vec3 surf_norm, sampler2D normal_map, float intensity, float scale, vec2 uv ) { vec3 q0 = dFdx( eye_pos.xyz ); vec3 q1 = dFdy( eye_pos.xyz ); vec2 st0 = dFdx( uv.st ); vec2 st1 = dFdy( uv.st ); vec3 N = normalize(surf_norm); vec3 q1perp = cross( q1, N ); vec3 q0perp = cross( N, q0 ); vec3 T = q1perp * st0.x + q0perp * st1.x; vec3 B = q1perp * st0.y + q0perp * st1.y; float det = max( dot( T, T ), dot( B, B ) ); float scalefactor = ( det == 0.0 ) ? 0.0 : inversesqrt( det ); vec3 mapN = texture2D( normal_map, uv * scale ).xyz * 2.0 - 1.0; mapN.xy *= intensity; return normalize( T * ( mapN.x * scalefactor ) + B * ( mapN.y * scalefactor ) + N * mapN.z ); } const vec2 INV_ATAN = vec2(0.1591, 0.3183); const float LN2 = 0.6931472; const float ENV_LODS = 7.0; const float PI = 3.14159; struct PBRConfig { float reflection; float clearcoat; vec3 color; vec3 lightColor; vec3 envReflection; bool overrideMRO; bool overrideENV; vec3 mro; vec3 env; }; vec3 fresnelSphericalGaussianRoughness(float cosTheta, vec3 F0, float roughness) { return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(2.0, (-5.55473 * cosTheta - 6.98316) * cosTheta); } vec2 sampleSphericalMap(vec3 v) { vec3 normalizedV = normalize(v); vec2 uv = vec2(0.5 + atan(normalizedV.z, normalizedV.x) / (2.0 * PI), 0.5 + asin(normalizedV.y) / PI); return uv; } vec4 SRGBtoLinear(vec4 srgb) { vec3 linOut = pow(srgb.xyz, vec3(2.2)); return vec4(linOut, srgb.w); } vec3 linearToSRGB(vec3 color) { return pow(color, vec3(0.4545454545454545)); } vec4 linearToSRGB(vec4 color) { return vec4(pow(color.rgb, vec3(0.4545454545454545)), 1.0); } vec4 RGBMToLinear(vec4 value) { float maxRange = 6.0; return vec4(value.xyz * value.w * maxRange, 1.0); } vec4 autoToLinear(vec4 texel, float uHDR) { vec4 color = RGBMToLinear(texel); if (uHDR < 0.001) { color = SRGBtoLinear(texel); } return color; } vec3 uncharted2Tonemap(vec3 x) { float A = 0.15; float B = 0.50; float C = 0.10; float D = 0.20; float E = 0.02; float F = 0.30; return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F; } vec3 uncharted2(vec3 color) { const float W = 11.2; float exposureBias = 2.0; vec3 curr = uncharted2Tonemap(exposureBias * color); vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W)); return curr * whiteScale; } vec4 getIBLContribution(float NdV, vec4 baseColor, vec4 MRO, vec3 R, vec3 V, vec3 N, sampler2D tLUT, sampler2D tEnvDiffuse, sampler2D tEnvSpecular, PBRConfig config) { float metallic = clamp(MRO.x + uMRON.x - 1.0, 0.0, 1.0); float roughness = clamp(MRO.y + uMRON.y - 1.0, 0.0, 1.0); float ao = mix(1.0, MRO.z, uMRON.z); vec3 env = uEnv; if (config.overrideMRO) { metallic = config.mro.x; roughness = config.mro.y; ao = config.mro.z; } if (config.overrideENV) { env = config.env; } vec2 lutUV = vec2(NdV, roughness); vec2 diffuseUV = sampleSphericalMap(N); vec3 brdf = SRGBtoLinear(texture2D(tLUT, lutUV)).rgb; vec3 diffuse = autoToLinear( texture2D(tEnvDiffuse, diffuseUV + uEnvOffset ), uHDR).rgb; vec3 lightmap = vec3(1.0); if (uUseLightmap > 0.0) { lightmap = texture2D(tLightmap, vUv2).rgb; lightmap.rgb = pow(lightmap.rgb, vec3(2.2)) * uLightmapIntensity; diffuse.rgb *= lightmap.rgb; } diffuse *= baseColor.rgb; float level = floor(roughness * ENV_LODS); vec2 specUV = sampleSphericalMap(R); specUV.y /= 2.0; specUV /= pow(2.0, level); specUV.y += 1.0 - exp(-LN2 * level); vec3 specular = autoToLinear(texture2D(tEnvSpecular, specUV + uEnvOffset), uHDR).rgb; // fake stronger specular highlight specular += pow(specular, vec3(2.2)) * env.y; if (uUseLightmap > 0.0) { specular *= lightmap; } vec3 F0 = vec3(0.04); F0 = mix(F0, baseColor.rgb, metallic); vec3 F = fresnelSphericalGaussianRoughness(NdV, F0, roughness); vec3 diffuseContrib = 1.0 - F; specular = specular.rgb * (F * brdf.x + brdf.y); diffuseContrib *= 1.0 - metallic; float alpha = baseColor.a; return vec4((diffuseContrib * diffuse + specular + (config.envReflection*0.01)) * ao * env.x, alpha); } vec3 getNormal() { vec3 N = vWorldNormal; vec3 V = normalize(vV); return unpackNormalPBR(V, N, tNormal, uMRON.w, 1.0, vUv).xyz; } vec4 getPBR(vec3 baseColor, PBRConfig config) { vec3 N = vWorldNormal; vec3 V = normalize(vV); vec3 worldNormal = getNormal(); vec3 R = reflect(V, worldNormal); float NdV = abs(dot(worldNormal, V)); vec4 baseColor4 = SRGBtoLinear(vec4(baseColor, 1.0)); vec4 MRO = texture2D(tMRO, vUv); vec4 color = getIBLContribution(NdV, baseColor4, MRO, R, V, worldNormal, tLUT, tEnvDiffuse, tEnvSpecular, config); if (uUseLinearOutput < 0.5) { color.rgb = uncharted2(color.rgb); color = linearToSRGB(color); } return color; } vec4 getPBR(vec3 baseColor) { PBRConfig config; return getPBR(baseColor, config); } vec4 getPBR() { vec4 baseColor = texture2D(tBaseColor, vUv); vec4 color = getPBR(baseColor.rgb * uTint); color.a *= baseColor.a; return color; } {@}pbr.vs{@}attribute vec2 uv2; uniform sampler2D tBaseColor; uniform vec2 uTiling; uniform vec2 uOffset; varying vec2 vUv; varying vec2 vUv2; varying vec3 vNormal; varying vec3 vWorldNormal; varying vec3 vV; void setupPBR(vec3 p0) { //inlinemain vUv = uv * uTiling + uOffset; vUv2 = uv2; vec4 worldPos = modelMatrix * vec4(p0, 1.0); vV = worldPos.xyz - cameraPosition; vNormal = normalMatrix * normal; vWorldNormal = mat3(modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz) * normal; } void setupPBR(vec3 p0, vec3 n) { vUv = uv * uTiling + uOffset; vUv2 = uv2; vec4 worldPos = modelMatrix * vec4(p0, 1.0); vV = worldPos.xyz - cameraPosition; vNormal = normalMatrix * n; vWorldNormal = mat3(modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz) * n; } {@}range.glsl{@} float range(float oldValue, float oldMin, float oldMax, float newMin, float newMax) { vec3 sub = vec3(oldValue, newMax, oldMax) - vec3(oldMin, newMin, oldMin); return sub.x * sub.y / sub.z + newMin; } vec2 range(vec2 oldValue, vec2 oldMin, vec2 oldMax, vec2 newMin, vec2 newMax) { vec2 oldRange = oldMax - oldMin; vec2 newRange = newMax - newMin; vec2 val = oldValue - oldMin; return val * newRange / oldRange + newMin; } vec3 range(vec3 oldValue, vec3 oldMin, vec3 oldMax, vec3 newMin, vec3 newMax) { vec3 oldRange = oldMax - oldMin; vec3 newRange = newMax - newMin; vec3 val = oldValue - oldMin; return val * newRange / oldRange + newMin; } float crange(float oldValue, float oldMin, float oldMax, float newMin, float newMax) { return clamp(range(oldValue, oldMin, oldMax, newMin, newMax), min(newMin, newMax), max(newMin, newMax)); } vec2 crange(vec2 oldValue, vec2 oldMin, vec2 oldMax, vec2 newMin, vec2 newMax) { return clamp(range(oldValue, oldMin, oldMax, newMin, newMax), min(newMin, newMax), max(newMin, newMax)); } vec3 crange(vec3 oldValue, vec3 oldMin, vec3 oldMax, vec3 newMin, vec3 newMax) { return clamp(range(oldValue, oldMin, oldMax, newMin, newMax), min(newMin, newMax), max(newMin, newMax)); } float rangeTransition(float t, float x, float padding) { float transition = crange(t, 0.0, 1.0, -padding, 1.0 + padding); return crange(x, transition - padding, transition + padding, 1.0, 0.0); } {@}rgb2hsv.fs{@}vec3 rgb2hsv(vec3 c) { vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } vec3 hsv2rgb(vec3 c) { vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); }{@}rgbshift.fs{@}vec4 getRGB(sampler2D tDiffuse, vec2 uv, float angle, float amount) { vec2 offset = vec2(cos(angle), sin(angle)) * amount; vec4 r = texture2D(tDiffuse, uv + offset); vec4 g = texture2D(tDiffuse, uv); vec4 b = texture2D(tDiffuse, uv - offset); return vec4(r.r, g.g, b.b, g.a); }{@}rotation.glsl{@}mat4 rotationMatrix(vec3 axis, float angle) { axis = normalize(axis); float s = sin(angle); float c = cos(angle); float oc = 1.0 - c; return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 0.0, 0.0, 0.0, 1.0); } mat2 rotationMatrix(float angle) { float s = sin(angle); float c = cos(angle); return mat2(c, -s, s, c); }{@}roundedBorder.glsl{@}float roundedBorder(float thickness, float radius, vec2 uv, vec2 resolution, out float inside) { // Get square-pixel coordinates in range -1.0 .. 1.0 float multiplier = max(resolution.x, resolution.y); vec2 ratio = resolution / multiplier; vec2 squareUv = (2.0 * uv - 1.0) * ratio; // -1.0 .. 1.0 float squareThickness = (thickness / multiplier); float squareRadius = 2.0 * (radius / multiplier); vec2 size = ratio - vec2(squareRadius + squareThickness); vec2 q = abs(squareUv) - size; float d = min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - squareRadius; float dist = abs(d); float delta = fwidth(dist); float border = 1.0 - smoothstep(-delta, delta, dist - squareThickness); delta = fwidth(d); float limit = squareThickness * 0.5; inside = 1.0 - smoothstep(-delta, delta, d - limit); return border; } float roundedBorder(float thickness, float radius, vec2 uv, vec2 resolution) { float inside; return roundedBorder(thickness, radius, uv, resolution, inside); } {@}simplenoise.glsl{@}float getNoise(vec2 uv, float time) { float x = uv.x * uv.y * time * 1000.0; x = mod(x, 13.0) * mod(x, 123.0); float dx = mod(x, 0.01); float amount = clamp(0.1 + dx * 100.0, 0.0, 1.0); return amount; } #test Device.mobile float sinf(float x) { x*=0.159155; x-=floor(x); float xx=x*x; float y=-6.87897; y=y*xx+33.7755; y=y*xx-72.5257; y=y*xx+80.5874; y=y*xx-41.2408; y=y*xx+6.28077; return x*y; } #endtest #test !Device.mobile #define sinf sin #endtest highp float getRandom(vec2 co) { highp float a = 12.9898; highp float b = 78.233; highp float c = 43758.5453; highp float dt = dot(co.xy, vec2(a, b)); highp float sn = mod(dt, 3.14); return fract(sin(sn) * c); } float cnoise(vec3 v) { float t = v.z * 0.3; v.y *= 0.8; float noise = 0.0; float s = 0.5; noise += (sinf(v.x * 0.9 / s + t * 10.0) + sinf(v.x * 2.4 / s + t * 15.0) + sinf(v.x * -3.5 / s + t * 4.0) + sinf(v.x * -2.5 / s + t * 7.1)) * 0.3; noise += (sinf(v.y * -0.3 / s + t * 18.0) + sinf(v.y * 1.6 / s + t * 18.0) + sinf(v.y * 2.6 / s + t * 8.0) + sinf(v.y * -2.6 / s + t * 4.5)) * 0.3; return noise; } float cnoise(vec2 v) { float t = v.x * 0.3; v.y *= 0.8; float noise = 0.0; float s = 0.5; noise += (sinf(v.x * 0.9 / s + t * 10.0) + sinf(v.x * 2.4 / s + t * 15.0) + sinf(v.x * -3.5 / s + t * 4.0) + sinf(v.x * -2.5 / s + t * 7.1)) * 0.3; noise += (sinf(v.y * -0.3 / s + t * 18.0) + sinf(v.y * 1.6 / s + t * 18.0) + sinf(v.y * 2.6 / s + t * 8.0) + sinf(v.y * -2.6 / s + t * 4.5)) * 0.3; return noise; } float fbm(vec3 x, int octaves) { float v = 0.0; float a = 0.5; vec3 shift = vec3(100); for (int i = 0; i < 10; ++i) { if (i >= octaves){ break; } v += a * cnoise(x); x = x * 2.0 + shift; a *= 0.5; } return v; } float fbm(vec2 x, int octaves) { float v = 0.0; float a = 0.5; vec2 shift = vec2(100); mat2 rot = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.50)); for (int i = 0; i < 10; ++i) { if (i >= octaves){ break; } v += a * cnoise(x); x = rot * x * 2.0 + shift; a *= 0.5; } return v; } {@}transformUV.glsl{@}vec2 translateUV(vec2 uv, vec2 translate) { return uv - translate; } vec2 rotateUV(vec2 uv, float r, vec2 origin) { float c = cos(r); float s = sin(r); mat2 m = mat2(c, -s, s, c); vec2 st = uv - origin; st = m * st; return st + origin; } vec2 scaleUV(vec2 uv, vec2 scale, vec2 origin) { vec2 st = uv - origin; st /= scale; return st + origin; } vec2 rotateUV(vec2 uv, float r) { return rotateUV(uv, r, vec2(0.5)); } vec2 scaleUV(vec2 uv, vec2 scale) { return scaleUV(uv, scale, vec2(0.5)); } vec2 skewUV(vec2 st, vec2 skew) { return st + st.gr * skew; } vec2 transformUV(vec2 uv, float a[9]) { // Array consists of the following // 0 translate.x // 1 translate.y // 2 skew.x // 3 skew.y // 4 rotate // 5 scale.x // 6 scale.y // 7 origin.x // 8 origin.y vec2 st = uv; //Translate st -= vec2(a[0], a[1]); //Skew st = st + st.gr * vec2(a[2], a[3]); //Rotate st = rotateUV(st, a[4], vec2(a[7], a[8])); //Scale st = scaleUV(st, vec2(a[5], a[6]), vec2(a[7], a[8])); return st; }{@}tridither.glsl{@}//https://www.shadertoy.com/view/4djSRW float hash12(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * .1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); } vec3 hash32(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973)); p3 += dot(p3, p3.yxz+33.33); return fract((p3.xxy+p3.yzz)*p3.zyx); } vec4 hash42(vec2 p) { vec4 p4 = fract(vec4(p.xyxy) * vec4(.1031, .1030, .0973, .1099)); p4 += dot(p4, p4.wzxy+33.33); return fract((p4.xxyz+p4.yzzw)*p4.zywx); } float dither1(in float color, in vec2 coord, in float time) { float noiseA = hash12(coord + fract(time + 1781.0)); float noiseB = hash12(coord + fract(time + 1130.0)); return color + ((noiseA + (noiseB - 1.0)) / 255.0); } vec3 dither3(in vec3 color, in vec2 coord, in float time) { vec2 seed = coord; vec3 noiseA = hash32(seed + fract(time) * 1300.0); vec3 noiseB = hash32(seed.yx + fract(time) * 1854.0); return color + ((noiseA + (noiseB - 1.0)) / 255.0); } vec4 dither4(in vec4 color, in vec2 coord, in float time) { vec2 seed = coord; vec4 noiseA = hash42(seed + fract(time + 1015.0)); vec4 noiseB = hash42(seed + fract(time + 1543.0)); return color + ((noiseA + (noiseB - 1.0)) / 255.0); } {@}module.json{@}{ "gl": ["transformUV"] }{@}uvgrid.glsl{@}#require(transformUV.glsl) vec2 getUVForGrid(vec2 uv, float xr, float yr, float x, float y) { return translateUV(scaleUV(uv, vec2(xr, yr), vec2(0.0)), -vec2(x / xr, y / yr)); } {@}TransitionShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tFrom; uniform sampler2D tTo; uniform sampler2D tTransition; uniform float uTransition; uniform float uTileSize; #!VARYINGS #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); } #!SHADER: Fragment #require(spritesheetUV.glsl) void main() { vec2 uv = gl_FragCoord.xy / resolution; vec3 from = texture2D(tFrom, uv).rgb; vec3 to = texture2D(tTo, uv).rgb; float vertical = step(uTransition, uv.y); float alpha = 1. - smoothstep(texture2D(tTransition, spritesheetUV(uv, uTransition, uTileSize, uTileSize, 0.)).r, 0.2, 1.); vec3 color = mix(to, from, alpha); gl_FragColor = vec4(color, 1.0); } {@}BGShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform vec3 uColor; #!VARYINGS #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); } #!SHADER: Fragment void main() { gl_FragColor = vec4(uColor, 1.0); }{@}ButtonUI.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform float uAlpha; uniform vec2 uResolution; uniform vec3 uColor; uniform vec3 uBorderColor; #!VARYINGS varying vec2 vUv; #!SHADER: ButtonUI.vs void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: ButtonUI.fs #require(roundedBorder.glsl) #require(range.glsl) void main() { vec2 uv = vUv; float inside = 0.0; float border = roundedBorder(2., 15., uv, uResolution, inside); vec3 color = uColor; gl_FragColor.rgb = uColor; gl_FragColor.rgb = mix(uColor, uBorderColor, border); gl_FragColor.a = uAlpha * inside; }{@}BackCircle.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform vec3 uColor; uniform float uAlpha; uniform float uHover; uniform bool uRounded; uniform float uFilled; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment #require(aastep.glsl) #require(roundedBorder.glsl) void main() { float alpha = 0.0; if(uRounded) { float inside = 0.0; inside += roundedBorder(30., 5.0, vUv, vec2(60.0, 40.)); alpha = inside; } else { float v = mix(0.46, 0.43, uHover); float outerCircle = aastep(v, length(vUv - vec2(0.5))); float innerCircle = aastep(0.48, length(vUv - vec2(0.5))); float hoverCircle = 1.0 - aastep(mix(0.46, 0.0, 1.0 - uFilled), length(vUv - vec2(0.5))); float circle = (1. - outerCircle ) + hoverCircle; alpha = circle; } gl_FragColor = vec4(uColor, alpha * uAlpha); }{@}VectorShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tIcon; uniform sampler2D uColort; uniform vec3 uColor; uniform vec3 uColorB; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment float msdf(sampler2D tMap, vec2 uv) { vec3 tex = texture2D(tMap, uv).rgb; // If you have small artifacts, try to tweak the 0.5 value. float signedDist = max(min(tex.r, tex.g), min(max(tex.r, tex.g), tex.b)) - 0.5; float d = fwidth(signedDist); float alpha = smoothstep(-d, d, signedDist); return alpha; } void main() { vec2 screenuv = gl_FragCoord.xy / resolution.xy; float colort = texture2D(uColort, screenuv).r; float value = msdf(tIcon, vUv); vec3 color = mix(uColor, uColorB, colort); gl_FragColor = vec4(color, value); }{@}BtnShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform vec3 uColor; uniform vec3 uColorHover; uniform float uHover; uniform float uAlpha; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment #require(aastep.glsl) void main() { vec4 ocolor = texture2D(tMap, vUv); vec4 color = ocolor; vec3 border = uColorHover; vec3 fill = uColor; border = mix(border, uColor, uHover); fill = mix(fill, uColorHover, uHover); color.rgb = mix(color.rgb, border, ocolor.r); color.rgb = mix(color.rgb, fill, ocolor.g); float alpha = ocolor.a; float cut = 0.001; alpha *= aastep(cut, vUv.x); alpha *= 1.0 - aastep(1.0 - cut, vUv.x); alpha *= aastep(cut, vUv.y); alpha *= 1.0 - aastep(1.0 - cut, vUv.y); gl_FragColor = vec4(color.rgb, alpha * uAlpha); }{@}HomeMapShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform vec3 uColor; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment #require(blendmodes.glsl) #require(simplenoise.glsl) #require(mousefluid.fs) void main() { vec3 color = uColor; vec2 uv = vUv; uv *= 1.5; vec4 map = texture2D(tMap, uv); vec3 fluid = getFluidVelocityMask(); float n = cnoise(vec3(uv * 2.0, time * 0.7)); map -= n * 0.1; // map.a -= fluid.x * 0.1; map.rgb /= map.a; color *= 1.0 + cnoise(uv * 0.5 + time * 0.1) * 0.1; color = blendOverlay(color, map.rgb, smoothstep(1.0, 0.0, length(uv-0.5)) + fluid.x * 0.0001); color += min(1.0, abs(fluid.y) * 0.01) * map.r * 0.05; color -= min(1.0, abs(fluid.x) * 0.01) * map.r * 0.05; //color = blendAdd(color, map.rgb, (fluid.x * 1.0) * 0.001); // edges float edge = 0.0; edge = smoothstep(0.0, 0.2, vUv.x); edge *= smoothstep(0.0, 0.2, 1.0 - vUv.x); edge *= smoothstep(0.0, 0.2, vUv.y); edge *= smoothstep(0.0, 0.2, 1.0 - vUv.y); color = mix(uColor, color, edge); gl_FragColor = vec4(color, 1.0); }{@}HomepageComposite.fs{@}uniform sampler2D tDiffuse; uniform float uIntro; uniform vec3 uIntroColor; varying vec2 vUv; #require(UnrealBloom.fs) #require(rgbshift.fs) #require(transformUV.glsl) #require(rgb2hsv.fs) #require(blendmodes.glsl) #require(simplenoise.glsl) void main() { vec2 uv = vUv; uv = scaleUV(uv, vec2(1.0 + (1.0-uIntro) * 0.2)); vec2 squareUV = scaleUV(vUv, vec2(1.0, resolution.x/resolution.y)); vec3 texel = getRGB(tDiffuse, uv, radians(45.0), 0.00025).rgb; texel += pow(getUnrealBloom(vUv), vec3(1.0)); texel += cnoise(vUv*0.5+time*0.02) * 0.1; texel *= mix(0.5, 1.0, smoothstep(1.0, 0.2, length(squareUV-0.5))); texel = blendOverlay(texel, vec3(getNoise(vUv,time)), 0.1); texel = mix(texel*2.0, texel, smoothstep(0.0, 0.4, uIntro)); squareUV += cnoise(vUv*2.0+time*0.2) * 0.1 * smoothstep(0.0, 0.1, length(squareUV-0.5)); texel = mix(texel, uIntroColor, step(uIntro*0.6, length(squareUV-0.5)) * smoothstep(1.0, 0.9, uIntro)); gl_FragColor = vec4(texel, 1.0); }{@}LogoShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; #!VARYINGS #!SHADER: Vertex void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: Fragment void main() { gl_FragColor = vec4(1.0); }{@}StartShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform vec3 uColor; uniform vec3 uColorAlternate; uniform float uHover; uniform float uAlpha; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment void main() { vec4 color = texture2D(tMap, vUv); color.rgb *= mix(uColor, uColorAlternate, uHover); gl_FragColor = color; gl_FragColor.rgb /= gl_FragColor.a * uAlpha; gl_FragColor.a = gl_FragColor.a * uAlpha; }{@}BgVibes.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform vec3 uColor; uniform float uAlpha; #!VARYINGS varying vec2 vUv; #!SHADER: BgVibes.vs void main() { vec3 pos = position; vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: BgVibes.fs void main() { gl_FragColor.rgb = uColor; gl_FragColor.a = uAlpha; } {@}CloudShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform float uAlpha; #!VARYINGS varying vec2 vUv; varying vec3 vPos; #!SHADER: CloudShader.vs void main() { vec3 pos = position; vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); vPos = gl_Position.xyz; } #!SHADER: CloudShader.fs #require(range.glsl) void main() { vec3 map = texture2D(tMap, vUv).rgb; float image = mix(map.r, mix(map.g, map.b, crange(vPos.z, 1.5, .7, 0., 1.)), crange(vPos.z, 2., 1., 0., 1.)); gl_FragColor.rgb = vec3(image); gl_FragColor.rgb /= image; gl_FragColor.a = image * uAlpha; } {@}CardLayerImage.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform sampler2D tDisplace; uniform vec2 uMouse; uniform float uAmplitude; #!VARYINGS varying vec2 vUv; #!SHADER: CardLayerImage.vs void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: CardLayerImage.fs void main() { vec2 st = gl_FragCoord.xy / resolution; float displace = texture2D(tDisplace, vUv).r; vec2 amplitude = uMouse * .1 * uAmplitude; vec2 displaceUV = vec2(vUv.x + (displace) * amplitude.x, vUv.y + (displace) * amplitude.y); gl_FragColor = texture2D(tMap, displaceUV); gl_FragColor = mix(gl_FragColor, gl_FragColor - 0.3, min(1. - min(vUv.y * 3., 1.), 1.) * 0.9); }{@}CardPBRShader.glsl{@} #!ATTRIBUTES #!UNIFORMS uniform vec3 uLightColor; uniform sampler2D tFront; uniform sampler2D tBack; uniform vec3 uCardColor; uniform vec3 uTextColor; uniform float uCenter; uniform float uDirection; uniform float uWiggle; uniform float uElastic; uniform float uOver; uniform vec2 uMouse; uniform float uMobile; #!VARYINGS varying vec3 vPos; varying vec3 vNormal; varying vec3 vNormal2; varying vec2 vOuv; varying vec2 vOuvBack; varying float isBack; varying float isFront; #!SHADER: Vertex #require(pbr.vs) #require(transformUV.glsl) #define PI 3.141592653589793 void main() { vOuv = uv; vOuv = vec2(vOuv.x, 1.0 - vOuv.y); vOuvBack = vOuv; if (uMobile > 0.5) { vOuvBack = rotateUV(vOuv, PI * 0.5); } // check if normal are facing back isBack = dot(normal, vec3(0.0, 0.0, -1.0)); isFront = dot(normal, vec3(0.0, 0.0, 1.0)); vec3 pos = position; pos.z += (pow(sin(pos.x + 1.57), -.18) - 1.0) * uDirection; pos.z += (pow(sin(pos.x + 1.57), -1.) - 1.0) * 0.2 * abs(uWiggle) * uCenter; pos.z += (pow(sin(pos.x + 1.57), -1.) - 1.) * uOver * -0.25 * uCenter; vPos = pos; setupPBR(pos); gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); vNormal2 = normal; } #!SHADER: Fragment #require(pbr.fs) #require(blendmodes.glsl) #require(transformUV.glsl) #require(roundedBorder.glsl) void main() { // PBR Config // this is the default config that can be tweaked PBRConfig baseConfig; baseConfig.clearcoat = 0.0; baseConfig.reflection = 1.0; baseConfig.color = vec3(1.0); baseConfig.lightColor = uLightColor; vec3 cardColor = uCardColor; vec3 frontColor = texture2D(tFront, vUv).rgb; float backTexture = texture2D(tBack, vOuvBack).r; vec3 backColor = blendMultiply(cardColor, vec3(1. - backTexture * 0.3), 0.7); vec3 baseColor = cardColor; float inside = 0.; if (uMobile > 0.5) { roundedBorder(0.1, 20., scaleUV(vOuv, vec2(0.95, 0.97)), resolution.xy, inside); } else { roundedBorder(0.1, 40., scaleUV(vOuv, vec2(0.95, 0.92)), resolution.xy, inside); } baseColor = mix(baseColor, backColor * 0.85, clamp(isBack, 0.0, 1.0)); baseColor = mix(baseColor, frontColor, clamp(isFront, 0.0, 1.0) * inside * mix(1.0, 0.5, 1. - uCenter)); vec3 pbr = baseColor; // directional light vec3 light = normalize(vec3(0.1, 0.4, 1.0)); float lightIntensity = clamp(dot(vNormal, light), 0.0, 1.0); if (isFront > 0.5 && inside > 0.5) { lightIntensity = 0.0; } pbr += vNormal2.z > 0. ? mix((lightIntensity * 0.3), 0., vNormal2.z) : (lightIntensity * 0.3); // pbr = vec3(vNormal); gl_FragColor = vec4(pbr, 1.0); }{@}FakeCardShadow.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform vec2 uResolution; uniform float uCenter; uniform float uDirection; uniform float uWiggle; uniform float uElastic; uniform float uOver; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex.vs void main() { vUv = uv; vec3 pos = position; pos.z += (pow(sin(pos.x + 1.57), -.18) - 1.0) * uDirection; pos.z += (pow(sin(pos.x + 1.57), -1.) - 1.0) * 0.2 * abs(uWiggle) * uCenter; pos.z += (pow(sin(pos.x + 1.57), -1.) - 1.) * uOver * -0.25 * uCenter; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: Fragment.fs float getDistance(vec2 p, vec2 center, vec2 size) { // calculate distance to the edge of the rectangle return length(max(abs(p - center) - size, vec2(0.0))); } void main() { vec2 st = gl_FragCoord.xy / resolution; vec2 halfSize = vec2(.5, .5); float radius = 0.2; float dist = smoothstep(radius, 0.0, getDistance(vUv, halfSize, halfSize - radius)); gl_FragColor.rgb = vec3(0.); gl_FragColor.a = dist * 0.5 * (1. - uCenter); } {@}FakeCardShadowCenter.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform float uCenter; uniform float uAlpha; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex.vs void main() { vUv = uv; vec3 pos = position; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); gl_Position.x += uCenter * 6.2; } #!SHADER: Fragment.fs float getDistance(vec2 p, vec2 center, vec2 size) { return length(max(abs(p - center) - size, vec2(0.0))); } void main() { vec2 st = gl_FragCoord.xy / resolution; vec2 halfSize = vec2(.5, .5); float radius = 0.25; float dist = smoothstep(radius, 0.0, getDistance(vUv, halfSize, halfSize - radius)); gl_FragColor.rgb = vec3(0.); gl_FragColor.a = uAlpha * dist * 0.20 * (1. - abs(uCenter)); } {@}VibesComposite.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tDiffuse; uniform sampler2D tLightStreak; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment void main() { vec3 scene = texture2D(tDiffuse, vUv).rgb; scene += pow(texture2D(tLightStreak, vUv).rgb, vec3(1.25)) * 0.8; gl_FragColor = vec4(scene, 1.0); } {@}SlidePinShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform float uAlpha; uniform vec2 uResolution; #!VARYINGS varying vec2 vUv; #!SHADER: SlidePinShader.vs void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: SlidePinShader.fs #require(roundedBorder.glsl) #require(aspectuv.glsl) void main() { vec2 uv = aspectUV(vUv, vec2(1., 1.), vec2(1.13, 1.)); float inside = 0.0; float border = roundedBorder(.13, .13, vUv, uResolution, inside); gl_FragColor = texture2D(tMap, uv) + (border); gl_FragColor.a = inside; }{@}ModalShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform float uAlpha; uniform vec2 uResolution; uniform vec3 uColor; uniform float uTransition; #!VARYINGS varying vec2 vUv; varying float vDark; varying float vAlpha; #!SHADER: ModalShader.vs #require(range.glsl) #require(transformUV.glsl) #require(eases.glsl) void main() { vUv = uv; vec3 pos = position; float p = uTransition; // float p = 1.0; float transition = crange(p, 0., 1., 0.5, 1.); float invTransition = 1. - p; // pos.x -= 0.5; // pos *= 0.4; // pos.x += 0.5; pos.y -= 0.5 * invTransition; float t = expoOut(invTransition); pos.x += (sin(pos.y * 15.0 + time) * 0.05) * t; pos.y -= (sin(pos.x * 2.0 + time) * 0.05) * t; vDark = (sin(pos.x * 20.0 + time) * 0.5 + 0.5) * t; vAlpha = crange(uTransition, 0.0, 0.2, 0.0, 1.0); gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: ModalShader.fs #require(roundedBorder.glsl) #require(range.glsl) #require(transformUV.glsl) #require(eases.glsl) void main() { float inside = 0.0; float border = roundedBorder(0., 20., vUv, uResolution, inside); vec3 color = mix(uColor, uColor * 0.75, vDark); gl_FragColor = vec4(color, inside * vAlpha); }{@}PinShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform vec3 uColor; uniform float uAlpha; uniform float uShape; uniform vec2 uResolution; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex.vs void main() { vUv = uv; vec3 pos = position; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: Fragment.fs #require(msdf.glsl) #require(roundedBorder.glsl) void main() { vec2 st = gl_FragCoord.xy / resolution; float alpha = 0.; float inside = 0.; if (uShape > 0.5) { roundedBorder(0.0, .17, vUv, uResolution.xy + vec2(0., 0.), inside); alpha = inside; } else { alpha = msdf(tMap, vUv); } gl_FragColor.rgb = uColor; gl_FragColor.a = alpha * uAlpha; } {@}advectionManualFilteringShader.fs{@}varying vec2 vUv; uniform sampler2D uVelocity; uniform sampler2D uSource; uniform vec2 texelSize; uniform vec2 dyeTexelSize; uniform float dt; uniform float dissipation; vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) { vec2 st = uv / tsize - 0.5; vec2 iuv = floor(st); vec2 fuv = fract(st); vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize); vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize); vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize); vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize); return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y); } void main () { vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize; gl_FragColor = dissipation * bilerp(uSource, coord, dyeTexelSize); gl_FragColor.a = 1.0; }{@}advectionShader.fs{@}varying vec2 vUv; uniform sampler2D uVelocity; uniform sampler2D uSource; uniform vec2 texelSize; uniform float dt; uniform float dissipation; void main () { vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize; gl_FragColor = dissipation * texture2D(uSource, coord); gl_FragColor.a = 1.0; }{@}backgroundShader.fs{@}varying vec2 vUv; uniform sampler2D uTexture; uniform float aspectRatio; #define SCALE 25.0 void main () { vec2 uv = floor(vUv * SCALE * vec2(aspectRatio, 1.0)); float v = mod(uv.x + uv.y, 2.0); v = v * 0.1 + 0.8; gl_FragColor = vec4(vec3(v), 1.0); }{@}clearShader.fs{@}varying vec2 vUv; uniform sampler2D uTexture; uniform float value; void main () { gl_FragColor = value * texture2D(uTexture, vUv); }{@}colorShader.fs{@}uniform vec4 color; void main () { gl_FragColor = color; }{@}curlShader.fs{@}varying highp vec2 vUv; varying highp vec2 vL; varying highp vec2 vR; varying highp vec2 vT; varying highp vec2 vB; uniform sampler2D uVelocity; void main () { float L = texture2D(uVelocity, vL).y; float R = texture2D(uVelocity, vR).y; float T = texture2D(uVelocity, vT).x; float B = texture2D(uVelocity, vB).x; float vorticity = R - L - T + B; gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0); }{@}displayShader.fs{@}varying vec2 vUv; uniform sampler2D uTexture; void main () { vec3 C = texture2D(uTexture, vUv).rgb; float a = max(C.r, max(C.g, C.b)); gl_FragColor = vec4(C, a); }{@}divergenceShader.fs{@}varying highp vec2 vUv; varying highp vec2 vL; varying highp vec2 vR; varying highp vec2 vT; varying highp vec2 vB; uniform sampler2D uVelocity; void main () { float L = texture2D(uVelocity, vL).x; float R = texture2D(uVelocity, vR).x; float T = texture2D(uVelocity, vT).y; float B = texture2D(uVelocity, vB).y; vec2 C = texture2D(uVelocity, vUv).xy; if (vL.x < 0.0) { L = -C.x; } if (vR.x > 1.0) { R = -C.x; } if (vT.y > 1.0) { T = -C.y; } if (vB.y < 0.0) { B = -C.y; } float div = 0.5 * (R - L + T - B); gl_FragColor = vec4(div, 0.0, 0.0, 1.0); } {@}fluidBase.vs{@}varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB; uniform vec2 texelSize; void main () { vUv = uv; vL = vUv - vec2(texelSize.x, 0.0); vR = vUv + vec2(texelSize.x, 0.0); vT = vUv + vec2(0.0, texelSize.y); vB = vUv - vec2(0.0, texelSize.y); gl_Position = vec4(position, 1.0); }{@}gradientSubtractShader.fs{@}varying highp vec2 vUv; varying highp vec2 vL; varying highp vec2 vR; varying highp vec2 vT; varying highp vec2 vB; uniform sampler2D uPressure; uniform sampler2D uVelocity; vec2 boundary (vec2 uv) { return uv; // uv = min(max(uv, 0.0), 1.0); // return uv; } void main () { float L = texture2D(uPressure, boundary(vL)).x; float R = texture2D(uPressure, boundary(vR)).x; float T = texture2D(uPressure, boundary(vT)).x; float B = texture2D(uPressure, boundary(vB)).x; vec2 velocity = texture2D(uVelocity, vUv).xy; velocity.xy -= vec2(R - L, T - B); gl_FragColor = vec4(velocity, 0.0, 1.0); }{@}pressureShader.fs{@}varying highp vec2 vUv; varying highp vec2 vL; varying highp vec2 vR; varying highp vec2 vT; varying highp vec2 vB; uniform sampler2D uPressure; uniform sampler2D uDivergence; vec2 boundary (vec2 uv) { return uv; // uncomment if you use wrap or repeat texture mode // uv = min(max(uv, 0.0), 1.0); // return uv; } void main () { float L = texture2D(uPressure, boundary(vL)).x; float R = texture2D(uPressure, boundary(vR)).x; float T = texture2D(uPressure, boundary(vT)).x; float B = texture2D(uPressure, boundary(vB)).x; float C = texture2D(uPressure, vUv).x; float divergence = texture2D(uDivergence, vUv).x; float pressure = (L + R + B + T - divergence) * 0.25; gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0); }{@}splatShader.fs{@}varying vec2 vUv; uniform sampler2D uTarget; uniform float aspectRatio; uniform vec3 color; uniform vec3 bgColor; uniform vec2 point; uniform vec2 prevPoint; uniform float radius; uniform float canRender; uniform float uAdd; float blendScreen(float base, float blend) { return 1.0-((1.0-base)*(1.0-blend)); } vec3 blendScreen(vec3 base, vec3 blend) { return vec3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b)); } float l(vec2 uv, vec2 point1, vec2 point2) { vec2 pa = uv - point1, ba = point2 - point1; pa.x *= aspectRatio; ba.x *= aspectRatio; float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); return length(pa - ba * h); } float cubicOut(float t) { float f = t - 1.0; return f * f * f + 1.0; } void main () { vec3 splat = (1.0 - cubicOut(clamp(l(vUv, prevPoint.xy, point.xy) / radius, 0.0, 1.0))) * color; vec3 base = texture2D(uTarget, vUv).xyz; base *= canRender; vec3 outColor = mix(blendScreen(base, splat), base + splat, uAdd); gl_FragColor = vec4(outColor, 1.0); }{@}vorticityShader.fs{@}varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB; uniform sampler2D uVelocity; uniform sampler2D uCurl; uniform float curl; uniform float dt; void main () { float L = texture2D(uCurl, vL).x; float R = texture2D(uCurl, vR).x; float T = texture2D(uCurl, vT).x; float B = texture2D(uCurl, vB).x; float C = texture2D(uCurl, vUv).x; vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L)); force /= length(force) + 0.0001; force *= curl * C; force.y *= -1.0; // force.y += 400.3; vec2 vel = texture2D(uVelocity, vUv).xy; gl_FragColor = vec4(vel + force * dt, 0.0, 1.0); }{@}CompositeStreak.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tHigh; uniform sampler2D tDown; uniform sampler2D tPrefiltered; uniform vec3 uStreakColor; uniform float uStreakIntensity; uniform float uGlowIntensity; uniform bool uDebugHalo; uniform float uFlareIntensity; uniform float uAspectCorrection; uniform float uHaloChroma; uniform float uHaloScale; uniform float uRotateStreak; uniform float uHaloSoftness; uniform float uHaloRotateSrc; uniform float uHaloConstant; uniform vec3 uHaloColor; uniform vec4 uHaloRing; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: Fragment #require(transformUV.glsl) #define PI 3.1415926 float createRingSDF(vec2 uv, vec2 center, float scale, float innerRadius, float outerRadius, float smoothness) { // Scale the UV coordinates vec2 scaledUV = (uv - center) * scale; // Calculate the distance from the center float dist = distance(vec2(0.0), scaledUV); // Apply smoothstep for the outer and inner edges of the ring float outerEdge = smoothstep(outerRadius - smoothness, outerRadius, dist); float innerEdge = smoothstep(innerRadius, innerRadius + smoothness, dist); // Create the ring by subtracting the inner edge from the outer edge return outerEdge - innerEdge; } vec2 getSpriteUVForAtlasIndex(vec2 uv, float index, vec2 atlasSize, vec2 spriteSize) { vec2 spriteIndex = vec2(mod(index, atlasSize.x), floor(index / atlasSize.x)); vec2 spriteUV = uv * spriteSize + spriteIndex * spriteSize; return spriteUV; } void main() { vec2 uv = vUv; //rotate the uv but compensate for aspect ratio uv = rotateUV(uv, uRotateStreak); vec3 c3 = (texture2D(tHigh, uv).rgb) * uStreakIntensity * uStreakColor; vec3 down = texture2D(tDown, uv).rgb * uStreakColor * uGlowIntensity; vec2 haloUV = uv; haloUV = rotateUV(haloUV, -(uRotateStreak + uHaloRotateSrc)); haloUV.x -= 0.5; haloUV.x *= mix( 1.0, resolution.x / resolution.y, uAspectCorrection); haloUV.x += 0.5; vec2 haloVec = normalize( vec2(0.5) - haloUV ) * uHaloScale; vec2 aspectUV = vUv; aspectUV.x -= 0.5; aspectUV.x *= mix( 1.0, resolution.x / resolution.y, uAspectCorrection); aspectUV.x += 0.5; vec2 haloWarpUV = aspectUV + haloVec; haloWarpUV.x = 1.0 - haloWarpUV.x; haloWarpUV = scaleUV( haloWarpUV, vec2(1.0 + uHaloSoftness) ); float haloMask = createRingSDF(aspectUV, vec2(0.5), uHaloRing.x, uHaloRing.y, uHaloRing.z, uHaloRing.w); vec2 haloWarpUVR = haloWarpUV + vec2(uHaloChroma, uHaloChroma); vec2 haloWarpUVG = haloWarpUV; vec2 haloWarpUVB = haloWarpUV - vec2(uHaloChroma, uHaloChroma); float haloR = texture2D(tPrefiltered, haloWarpUVR).r * haloMask; float haloG = texture2D(tPrefiltered, haloWarpUVG).g * haloMask; float haloB = texture2D(tPrefiltered, haloWarpUVB).b * haloMask; vec3 halo = vec3(haloR, haloG, haloB) * uHaloColor * uFlareIntensity; vec3 streaks = c3 + down; vec3 col = streaks + halo; float debugHalo = float(uDebugHalo); col = mix(col, vec3(haloMask), debugHalo); float constantHaloMaskR = createRingSDF(aspectUV, vec2(0.5), uHaloRing.x * 1.05, uHaloRing.y, uHaloRing.z, uHaloRing.w); float constantHaloMaskG = createRingSDF(aspectUV, vec2(0.5), uHaloRing.x, uHaloRing.y, uHaloRing.z, uHaloRing.w); float constantHaloMaskB = createRingSDF(aspectUV, vec2(0.5), uHaloRing.x * 0.98, uHaloRing.y, uHaloRing.z, uHaloRing.w); vec3 constantMask = vec3(constantHaloMaskR, constantHaloMaskG, constantHaloMaskB) * uHaloConstant; constantMask *= vec3(1.0) - halo; gl_FragColor = vec4( col + constantMask, 1.0 ); }{@}HydraLensStreakPass.fs{@}{@}LensFlareDown.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform vec2 uResolution; uniform float uStretch; #!VARYINGS varying vec2 vUv; #!SHADER: LensFlareDown.vs void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: LensFlareDown.fs #require(transformUV.glsl) void main() { vec2 uv = vUv; float dx = 1. / uResolution.x; float stretch = uStretch; float u0 = uv.x - ((dx * 5.) * stretch); float u1 = uv.x - ((dx * 3.) * stretch); float u2 = uv.x - ((dx * 1.) * stretch); float u3 = uv.x + ((dx * 1.) * stretch); float u4 = uv.x + ((dx * 3.) * stretch); float u5 = uv.x + ((dx * 5.) * stretch); vec3 c0 = texture2D(tMap, vec2(u0, uv.y)).rgb; vec3 c1 = texture2D(tMap, vec2(u1, uv.y)).rgb; vec3 c2 = texture2D(tMap, vec2(u2, uv.y)).rgb; vec3 c3 = texture2D(tMap, vec2(u3, uv.y)).rgb; vec3 c4 = texture2D(tMap, vec2(u4, uv.y)).rgb; vec3 c5 = texture2D(tMap, vec2(u5, uv.y)).rgb; vec3 col = vec3((c0 + c1 * 2. + c2 * 3. + c3 * 3. + c4 * 2. + c5) / 12.); gl_FragColor = vec4( col.rgb, 1.0 ); }{@}LensFlarePrefilter.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform float uThreshold; uniform float uRotate; #!VARYINGS varying vec2 vUv; #!SHADER: LensFlarePrefilter.vs void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: LensFlarePrefilter.fs #require(transformUV.glsl) #require(luma.fs) void main() { vec2 uv = vUv; uv = rotateUV(uv, -uRotate); vec4 c = texture2D(tMap, vec2(uv.x, uv.y)); // threshold the brightness float brightness = luma(c.rgb); if (brightness < uThreshold) { c = vec4(0.); } gl_FragColor = vec4(c.rgb, 1.0); }{@}LensFlareUp.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tHigh; uniform sampler2D tScene; uniform float uStretch; uniform float uSoftenEdge; uniform vec2 uResolution; #!VARYINGS varying vec2 vUv; #!SHADER: LensFlareUp.vs void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: LensFlareUp.fs void main() { vec2 uv = vUv; float dx = 1. / uResolution.x; float u0 = uv.x - dx; float u1 = uv.x; float u2 = uv.x + dx; // sample horizontally vec3 c0 = texture2D(tScene, vec2(u0, uv.y)).rgb / 4.; vec3 c1 = texture2D(tScene, vec2(u1, uv.y)).rgb / 2.; vec3 c2 = texture2D(tScene, vec2(u2, uv.y)).rgb / 4.; vec3 c3 = texture2D(tHigh, uv).rgb; vec3 cStretch = c0 + c1 + c2; // sample vertically vec3 c4 = texture2D(tScene, vec2(uv.x, uv.y - (dx * 0.75))).rgb / 4.; vec3 c5 = texture2D(tScene, vec2(uv.x, uv.y + (dx * 0.75))).rgb / 4.; cStretch += (c4 + c5) * uSoftenEdge; vec4 col = vec4(cStretch, 1.); gl_FragColor = col; }{@}AreaLights.glsl{@}mat3 transposeMat3( mat3 m ) { mat3 tmp; tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); return tmp; } // Real-Time Polygonal-Light Shading with Linearly Transformed Cosines // by Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt // code: https://github.com/selfshadow/ltc_code/ vec2 LTC_Uv( vec3 N, vec3 V, float roughness ) { float LUT_SIZE = 64.0; float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE; float LUT_BIAS = 0.5 / LUT_SIZE; float dotNV = clamp( dot( N, V ), 0.0, 1.0 ); // texture parameterized by sqrt( GGX alpha ) and sqrt( 1 - cos( theta ) ) vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) ); uv = uv * LUT_SCALE + LUT_BIAS; return uv; } float LTC_ClippedSphereFormFactor( vec3 f ) { // Real-Time Area Lighting: a Journey from Research to Production (p.102) // An approximation of the form factor of a horizon-clipped rectangle. float l = length( f ); return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 ); } vec3 LTC_EdgeVectorFormFactor( vec3 v1, vec3 v2 ) { float x = dot( v1, v2 ); float y = abs( x ); // rational polynomial approximation to theta / sin( theta ) / 2PI float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y; float b = 3.4175940 + ( 4.1616724 + y ) * y; float v = a / b; float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v; return cross( v1, v2 ) * theta_sintheta; } vec3 LTC_Evaluate( vec3 N, vec3 V, vec3 P, mat3 mInv, vec3 rectCoords[ 4 ] ) { // bail if point is on back side of plane of light // assumes ccw winding order of light vertices vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ]; vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ]; vec3 lightNormal = cross( v1, v2 ); if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 ); // construct orthonormal basis around N vec3 T1, T2; T1 = normalize( V - N * dot( V, N ) ); T2 = - cross( N, T1 ); // negated from paper; possibly due to a different handedness of world coordinate system // compute transform mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) ); // transform rect vec3 coords[ 4 ]; coords[ 0 ] = mat * ( rectCoords[ 0 ] - P ); coords[ 1 ] = mat * ( rectCoords[ 1 ] - P ); coords[ 2 ] = mat * ( rectCoords[ 2 ] - P ); coords[ 3 ] = mat * ( rectCoords[ 3 ] - P ); // project rect onto sphere coords[ 0 ] = normalize( coords[ 0 ] ); coords[ 1 ] = normalize( coords[ 1 ] ); coords[ 2 ] = normalize( coords[ 2 ] ); coords[ 3 ] = normalize( coords[ 3 ] ); // calculate vector form factor vec3 vectorFormFactor = vec3( 0.0 ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] ); vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] ); // adjust for horizon clipping float result = LTC_ClippedSphereFormFactor( vectorFormFactor ); return vec3( result ); }{@}Lighting.glsl{@}#!ATTRIBUTES #!UNIFORMS struct LightConfig { vec3 normal; bool phong; bool areaToPoint; float phongAttenuation; float phongShininess; vec3 phongColor; vec3 lightColor; bool overrideColor; }; uniform sampler2D tLTC1; //ignoreUIL uniform sampler2D tLTC2; //ignoreUIL #!VARYINGS varying vec3 vPos; varying vec3 vWorldPos; varying vec3 vNormal; varying vec3 vViewDir; #!SHADER: lighting.vs void setupLight(vec3 p0, vec3 p1) { //inlinemain vPos = p0; vNormal = normalize(normalMatrix * p1); vWorldPos = vec3(modelMatrix * vec4(p0, 1.0)); vViewDir = -vec3(modelViewMatrix * vec4(p0, 1.0)); } #test !window.Metal void setupLight(vec3 p0) { setupLight(p0, normal); } #endtest #!SHADER: lighting.fs #require(LightingCommon.glsl) void setupLight() { } vec3 getCombinedColor(LightConfig config, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix, sampler2D tLTC1, sampler2D tLTC2) { vec3 color = vec3(0.0); #pragma unroll_loop for (int i = 0; i < NUM_LIGHTS; i++) { vec3 lColor = config.overrideColor ? config.lightColor : lightColor[i].rgb; vec3 lPos = lightPos[i].rgb; vec4 lData = lightData[i]; vec4 lData2 = lightData2[i]; vec4 lData3 = lightData3[i]; vec4 lProps = lightProperties[i]; if (lProps.w < 1.0) continue; if (lProps.w < 1.1) { color += lightDirectional(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } else if (lProps.w < 2.1) { color += lightPoint(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } else if (lProps.w < 3.1) { color += lightCone(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } else if (lProps.w < 4.1) { color += lightArea(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix, tLTC1, tLTC2); } } return lclamp(color); } vec3 getCombinedColor(LightConfig config) { #test !window.Metal return getCombinedColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix, tLTC1, tLTC2); #endtest return vec3(0.0); } vec3 getCombinedColor() { LightConfig config; config.normal = vNormal; return getCombinedColor(config); } vec3 getCombinedColor(vec3 normal) { LightConfig config; config.normal = normal; return getCombinedColor(config); } vec3 getCombinedColor(vec3 normal, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix, sampler2D tLTC1, sampler2D tLTC2) { LightConfig config; config.normal = normal; return getCombinedColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix, tLTC1, tLTC2); } vec3 getPointLightColor(LightConfig config, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { vec3 color = vec3(0.0); #pragma unroll_loop for (int i = 0; i < NUM_LIGHTS; i++) { vec3 lColor = config.overrideColor ? config.lightColor : lightColor[i].rgb; vec3 lPos = lightPos[i].rgb; vec4 lData = lightData[i]; vec4 lData2 = lightData2[i]; vec4 lData3 = lightData3[i]; vec4 lProps = lightProperties[i]; if (lProps.w > 1.9 && lProps.w < 2.1) { color += lightPoint(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } } return lclamp(color); } vec3 getPointLightColor(LightConfig config) { #test !window.Metal return getPointLightColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); #endtest return vec3(0.0); } vec3 getPointLightColor() { LightConfig config; config.normal = vNormal; return getPointLightColor(config); } vec3 getPointLightColor(vec3 normal) { LightConfig config; config.normal = normal; return getPointLightColor(config); } vec3 getPointLightColor(vec3 normal, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { LightConfig config; config.normal = normal; return getPointLightColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } vec3 getAreaLightColor(float roughness, LightConfig config, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix, sampler2D tLTC1, sampler2D tLTC2) { vec3 color = vec3(0.0); #test Lighting.fallbackAreaToPointTest() config.areaToPoint = true; #endtest #pragma unroll_loop for (int i = 0; i < NUM_LIGHTS; i++) { vec3 lColor = config.overrideColor ? config.lightColor : lightColor[i].rgb; vec3 lPos = lightPos[i].rgb; vec4 lData = lightData[i]; vec4 lData2 = lightData2[i]; vec4 lData3 = lightData3[i]; vec4 lProps = lightProperties[i]; lData.w *= roughness; if (lProps.w > 3.9 && lProps.w < 4.1) { if (config.areaToPoint) { color += lightPoint(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } else { color += lightArea(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix, tLTC1, tLTC2); } } } return lclamp(color); } vec3 getAreaLightColor(float roughness, LightConfig config) { #test !window.Metal return getAreaLightColor(roughness, config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix, tLTC1, tLTC2); #endtest return vec3(0.0); } vec3 getAreaLightColor(float roughness) { LightConfig config; config.normal = vNormal; return getAreaLightColor(roughness, config); } vec3 getAreaLightColor() { LightConfig config; config.normal = vNormal; return getAreaLightColor(1.0, config); } vec3 getAreaLightColor(LightConfig config) { return getAreaLightColor(1.0, config); } vec3 getAreaLightColor(vec3 normal) { LightConfig config; config.normal = normal; return getAreaLightColor(1.0, config); } vec3 getAreaLightColor(vec3 normal, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix, sampler2D tLTC1, sampler2D tLTC2) { LightConfig config; config.normal = normal; return getAreaLightColor(1.0, config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix, tLTC1, tLTC2); } vec3 getSpotLightColor(LightConfig config, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { vec3 color = vec3(0.0); #pragma unroll_loop for (int i = 0; i < NUM_LIGHTS; i++) { vec3 lColor = config.overrideColor ? config.lightColor : lightColor[i].rgb; vec3 lPos = lightPos[i].rgb; vec4 lData = lightData[i]; vec4 lData2 = lightData2[i]; vec4 lData3 = lightData3[i]; vec4 lProps = lightProperties[i]; if (lProps.w > 2.9 && lProps.w < 3.1) { color += lightCone(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } } return lclamp(color); } vec3 getSpotLightColor(LightConfig config) { #test !window.Metal return getSpotLightColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); #endtest return vec3(0.0); } vec3 getSpotLightColor() { LightConfig config; config.normal = vNormal; return getSpotLightColor(config); } vec3 getSpotLightColor(vec3 normal) { LightConfig config; config.normal = normal; return getSpotLightColor(config); } vec3 getSpotLightColor(vec3 normal, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { LightConfig config; config.normal = normal; return getSpotLightColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } vec3 getDirectionalLightColor(LightConfig config, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { vec3 color = vec3(0.0); #pragma unroll_loop for (int i = 0; i < NUM_LIGHTS; i++) { vec3 lColor = config.overrideColor ? config.lightColor : lightColor[i].rgb; vec3 lPos = lightPos[i].rgb; vec4 lData = lightData[i]; vec4 lData2 = lightData2[i]; vec4 lData3 = lightData3[i]; vec4 lProps = lightProperties[i]; if (lProps.w > 0.9 && lProps.w < 1.1) { color += lightDirectional(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } } return lclamp(color); } vec3 getDirectionalLightColor(LightConfig config) { #test !window.Metal return getDirectionalLightColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); #endtest return vec3(0.0); } vec3 getDirectionalLightColor(vec3 normal) { LightConfig config; config.normal = normal; return getDirectionalLightColor(config); } vec3 getDirectionalLightColor() { LightConfig config; config.normal = vNormal; return getDirectionalLightColor(config); } vec3 getDirectionalLightColor(vec3 normal, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { LightConfig config; config.normal = vNormal; return getDirectionalLightColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } vec3 getStandardColor(LightConfig config, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { vec3 color = vec3(0.0); #pragma unroll_loop for (int i = 0; i < NUM_LIGHTS; i++) { vec3 lColor = config.overrideColor ? config.lightColor : lightColor[i].rgb; vec3 lPos = lightPos[i].rgb; vec4 lData = lightData[i]; vec4 lData2 = lightData2[i]; vec4 lData3 = lightData3[i]; vec4 lProps = lightProperties[i]; if (lProps.w < 1.0) continue; if (lProps.w < 1.1) { color += lightDirectional(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } else if (lProps.w < 2.1) { color += lightPoint(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } } return lclamp(color); } vec3 getStandardColor(LightConfig config) { #test !window.Metal return getStandardColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); #endtest return vec3(0.0); } vec3 getStandardColor() { LightConfig config; config.normal = vNormal; return getStandardColor(config); } vec3 getStandardColor(vec3 normal) { LightConfig config; config.normal = normal; return getStandardColor(config); } vec3 getStandardColor(vec3 normal, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { LightConfig config; config.normal = normal; return getStandardColor(config, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); } {@}LightingCommon.glsl{@}#require(AreaLights.glsl) vec3 lworldLight(vec3 lightPos, vec3 localPos, mat4 modelViewMatrix, mat4 viewMatrix) { vec4 mvPos = modelViewMatrix * vec4(localPos, 1.0); vec4 worldPosition = viewMatrix * vec4(lightPos, 1.0); return worldPosition.xyz - mvPos.xyz; } float lrange(float oldValue, float oldMin, float oldMax, float newMin, float newMax) { vec3 sub = vec3(oldValue, newMax, oldMax) - vec3(oldMin, newMin, oldMin); return sub.x * sub.y / sub.z + newMin; } vec3 lclamp(vec3 v) { return clamp(v, vec3(0.0), vec3(1.0)); } float lcrange(float oldValue, float oldMin, float oldMax, float newMin, float newMax) { return clamp(lrange(oldValue, oldMin, oldMax, newMin, newMax), min(newMax, newMin), max(newMin, newMax)); } #require(Phong.glsl) vec3 lightDirectional(LightConfig config, vec3 lColor, vec3 lPos, vec4 lData, vec4 lData2, vec4 lData3, vec4 lProps, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { vec3 lDir = lworldLight(lPos, vPos, modelViewMatrix, viewMatrix); float volume = dot(normalize(lDir), config.normal); return lColor * lcrange(volume, 0.0, 1.0, lProps.z, 1.0); } vec3 lightPoint(LightConfig config, vec3 lColor, vec3 lPos, vec4 lData, vec4 lData2, vec4 lData3, vec4 lProps, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { float dist = length(vWorldPos - lPos); if (dist > lProps.y) return vec3(0.0); vec3 color = vec3(0.0); vec3 lDir = lworldLight(lPos, vPos, modelViewMatrix, viewMatrix); float falloff = pow(lcrange(dist, 0.0, lProps.y, 1.0, 0.0), 2.0); if (config.phong) { color += falloff * phong(lProps.x, lColor, config.phongColor, config.phongShininess, config.phongAttenuation, config.normal, normalize(lDir), vViewDir, lProps.z); } else { float volume = dot(normalize(lDir), config.normal); volume = lcrange(volume, 0.0, 1.0, lProps.z, 1.0); color += lColor * volume * lProps.x * falloff; } return color; } vec3 lightCone(LightConfig config, vec3 lColor, vec3 lPos, vec4 lData, vec4 lData2, vec4 lData3, vec4 lProps, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix) { float dist = length(vWorldPos - lPos); if (dist > lProps.y) return vec3(0.0); vec3 lDir = lworldLight(lPos, vPos, modelViewMatrix, viewMatrix); vec3 sDir = degrees(-lData.xyz); float radius = lData.w; vec3 surfacePos = vWorldPos; vec3 surfaceToLight = normalize(lPos - surfacePos); float lightToSurfaceAngle = degrees(acos(dot(-surfaceToLight, normalize(sDir)))); float attenuation = 1.0; vec3 nColor = lightPoint(config, lColor, lPos, lData, lData2, lData3, lProps, vPos, vWorldPos, vViewDir, modelViewMatrix, viewMatrix); float featherMin = 1.0 - lData2.x*0.1; float featherMax = 1.0 + lData2.x*0.1; attenuation *= smoothstep(lightToSurfaceAngle*featherMin, lightToSurfaceAngle*featherMax, radius); nColor *= attenuation; return nColor; } vec3 lightArea(LightConfig config, vec3 lColor, vec3 lPos, vec4 lData, vec4 lData2, vec4 lData3, vec4 lProps, vec3 vPos, vec3 vWorldPos, vec3 vViewDir, mat4 modelViewMatrix, mat4 viewMatrix, sampler2D tLTC1, sampler2D tLTC2) { float dist = length(vWorldPos - lPos); if (dist > lProps.y) return vec3(0.0); vec3 color = vec3(0.0); vec3 normal = config.normal; vec3 viewDir = normalize(vViewDir); vec3 position = -vViewDir; float roughness = lData.w; vec3 mPos = lData.xyz; vec3 halfWidth = lData2.xyz; vec3 halfHeight = lData3.xyz; float falloff = pow(lcrange(dist, 0.0, lProps.y, 1.0, 0.0), 2.0); vec3 rectCoords[ 4 ]; rectCoords[ 0 ] = mPos + halfWidth - halfHeight; rectCoords[ 1 ] = mPos - halfWidth - halfHeight; rectCoords[ 2 ] = mPos - halfWidth + halfHeight; rectCoords[ 3 ] = mPos + halfWidth + halfHeight; vec2 uv = LTC_Uv( normal, viewDir, roughness ); #test !!window.Metal uv.y = 1.0 - uv.y; #endtest vec4 t1 = texture2D(tLTC1, uv); vec4 t2 = texture2D(tLTC2, uv); mat3 mInv = mat3( vec3( t1.x, 0, t1.y ), vec3( 0, 1, 0 ), vec3( t1.z, 0, t1.w ) ); vec3 fresnel = ( lColor * t2.x + ( vec3( 1.0 ) - lColor ) * t2.y ); color += lColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords ) * falloff * lProps.x; color += lColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords ) * falloff * lProps.x; return color; }{@}LitMaterial.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; #!VARYINGS varying vec2 vUv; varying vec3 vPos; #!SHADER: Vertex #require(lighting.vs) void main() { vUv = uv; vPos = position; setupLight(position); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: Fragment #require(lighting.fs) #require(shadows.fs) void main() { setupLight(); vec3 color = texture2D(tMap, vUv).rgb; color *= getShadow(vPos); color += getCombinedColor(); gl_FragColor = vec4(color, 1.0); }{@}Phong.glsl{@}float pclamp(float v) { return clamp(v, 0.0, 1.0); } float dPhong(float shininess, float dotNH) { return (shininess * 0.5 + 1.0) * pow(dotNH, shininess); } vec3 schlick(vec3 specularColor, float dotLH) { float fresnel = exp2((-5.55437 * dotLH - 6.98316) * dotLH); return (1.0 - specularColor) * fresnel + specularColor; } vec3 calcBlinnPhong(vec3 specularColor, float shininess, vec3 normal, vec3 lightDir, vec3 viewDir) { vec3 halfDir = normalize(lightDir + viewDir); float dotNH = pclamp(dot(normal, halfDir)); float dotLH = pclamp(dot(lightDir, halfDir)); vec3 F = schlick(specularColor, dotLH); float G = 0.85; float D = dPhong(shininess, dotNH); return F * G * D; } vec3 calcBlinnPhong(vec3 specularColor, float shininess, vec3 normal, vec3 lightDir, vec3 viewDir, float minTreshold) { vec3 halfDir = normalize(lightDir + viewDir); float dotNH = pclamp(dot(normal, halfDir)); float dotLH = pclamp(dot(lightDir, halfDir)); dotNH = lrange(dotNH, 0.0, 1.0, minTreshold, 1.0); dotLH = lrange(dotLH, 0.0, 1.0, minTreshold, 1.0); vec3 F = schlick(specularColor, dotLH); float G = 0.85; float D = dPhong(shininess, dotNH); return F * G * D; } vec3 phong(float amount, vec3 diffuse, vec3 specular, float shininess, float attenuation, vec3 normal, vec3 lightDir, vec3 viewDir, float minThreshold) { float cosineTerm = pclamp(lrange(dot(normal, lightDir), 0.0, 1.0, minThreshold, 1.0)); vec3 brdf = calcBlinnPhong(specular, shininess, normal, lightDir, viewDir, minThreshold); return brdf * amount * diffuse * attenuation * cosineTerm; }{@}mousefluid.fs{@}uniform sampler2D tFluid; uniform sampler2D tFluidMask; vec2 getFluidVelocity() { vec2 screenuv = gl_FragCoord.xy / resolution; float fluidMask = smoothstep(0.1, 0.7, texture2D(tFluidMask, screenuv).r); return texture2D(tFluid, vUv).xy * fluidMask; } vec3 getFluidVelocityMask() { vec2 screenuv = gl_FragCoord.xy / resolution; float fluidMask = smoothstep(0.1, 0.7, texture2D(tFluidMask, screenuv).r); return vec3(texture2D(tFluid, vUv).xy * fluidMask, fluidMask); }{@}SceneLayout.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform float uAlpha; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { vec3 pos = position; vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); } #!SHADER: Fragment void main() { gl_FragColor = texture2D(tMap, vUv); gl_FragColor.a *= uAlpha; gl_FragColor.rgb /= gl_FragColor.a; }{@}SnapshotFrame.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: Fragment void main() { gl_FragColor = texture2D(tMap, vUv); } {@}calcnormalfromdepth.glsl{@}vec3 uvToEyePos(in sampler2D depth, in vec2 uv) { float linearDepth = getDepthValue(depth, uv, 0.1, 1000.0); return (vec3(2.0 * uv - 1.0, -1.0) * uFrustum * linearDepth); } vec3 uvToEyePos(in float depth, in vec2 uv) { float linearDepth = getDepthValue(depth, 0.1, 1000.0); return (vec3(2.0 * uv - 1.0, -1.0) * uFrustum * linearDepth); } //if we trivialy accept differences between depths, there can be cases //where the shortest difference does not belong to the same edge, and because of that //a second depth is used to extrapolate the nearest depth value. //points that are on the same surface should (based on the diagram) more or less //end up at the same depth as the sampled one. //this is explained here: https://atyuwen.github.io/posts/normal-reconstruction/ vec3 calcNormalFromDepth(in float _depth, in vec2 _uv) { vec2 texSize = 1.0 / uResolution; ivec2 uv = ivec2(_uv * uResolution); if (abs(_depth) >= 1.0) { return vec3(0.0); } vec3 posEye = uvToEyePos(_depth, _uv); //find best depth along x... float dr = texelFetch(tDepth, uv + ivec2(1, 0), 0).x; float dr2 = texelFetch(tDepth, uv + ivec2(2, 0), 0).x; float dl = texelFetch(tDepth, uv - ivec2(1, 0), 0).x; float dl2 = texelFetch(tDepth, uv - ivec2(2, 0), 0).x; vec3 ddx = uvToEyePos(dr, _uv + vec2(texSize.x, 0.0)) - posEye; vec3 ddx2 = posEye - uvToEyePos(dl, _uv - vec2(texSize.x, 0.0)); float horizontalEdgeRight = abs((2.0*dr - dr2) - _depth); float horizontalEdgeLeft = abs((2.0*dl - dl2) - _depth); vec3 deltaX = horizontalEdgeRight < horizontalEdgeLeft ? ddx : ddx2; //find best depth along y... float dt = texelFetch(tDepth, uv + ivec2(0, 1), 0).x; float dt2 = texelFetch(tDepth, uv + ivec2(0, 2), 0).x; float db = texelFetch(tDepth, uv - ivec2(0, 1), 0).x; float db2 = texelFetch(tDepth, uv - ivec2(0, 2), 0).x; vec3 ddy = uvToEyePos(dt, _uv + vec2(0.0, texSize.y)) - posEye; vec3 ddy2 = posEye - uvToEyePos(db, _uv - vec2(0.0, texSize.y)); float verticalEdgeTop = abs((2.0 * dt - dt2) - _depth); float verticalEdgeBottom = abs((2.0 * db - db2) - _depth); vec3 deltaY = verticalEdgeTop < verticalEdgeBottom ? ddy : ddy2; return normalize(cross(deltaX, deltaY)); } {@}deNoiseSSAO.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform sampler2D tDepth; uniform vec2 uDirection; uniform float uDepthSigma; uniform float uSpatialSigma; uniform float uNormalSigma; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment #define BILATERAL_BLUR #define PI 3.14159265359 #define TAU 3.14159265359 * 2.0 float gaussianWeight(in float sigma, in float x) { float sigma2 = sigma * sigma; return exp(-(x * x) / (2.0 * sigma2)); } void main() { float result = 0.0; vec2 texel = (floor(vUv * resolution.xy) + 0.5) / resolution.xy; vec2 aoDepthP = texelFetch(tMap, ivec2(texel * resolution.xy), 0).xy; vec3 normP = texelFetch(tDepth, ivec2(texel * resolution.xy), 0).xyz; #ifdef BILATERAL_BLUR if (abs(aoDepthP.y) >= (1000.0 - 0.1)) { gl_FragColor = vec4(aoDepthP, 0.0, 1.0); return; } vec2 blurDirection = uDirection * (1.0 / resolution.xy); float wsum = 0.0; float filterRadius = 5.0; float spatialWeight = 0.0; float normWeight = 0.0; float rangeWeight = 0.0; for(float x=-filterRadius; x<=filterRadius; x+=1.0) { vec2 offset = blurDirection * x; vec2 coord = texel + offset; vec2 aoDepthQ = texelFetch(tMap, ivec2(coord * resolution.xy), 0).xy; vec3 normQ = texelFetch(tDepth, ivec2(coord * resolution.xy), 0).xyz; spatialWeight = gaussianWeight(uSpatialSigma, abs(x)); rangeWeight = gaussianWeight(uDepthSigma, abs(aoDepthQ.y - aoDepthP.y)); // normWeight = gaussianWeight(uNormalSigma, 1.0 - dot(normP, normQ)); normWeight = max(0.0, dot(normP, normQ)); result += aoDepthQ.x * spatialWeight * rangeWeight * normWeight; wsum += spatialWeight * rangeWeight * normWeight; } if(wsum > 0.0) { result /= wsum; } else { result = aoDepthP.x; } gl_FragColor = vec4(result, aoDepthP.y, 0.0, 1.0); #else float weight = 0.0; for(float i = -2.0; i < 2.0; i++) { for(float j = -2.0; j < 2.0; j++) { vec2 coord = vUv + (vec2(j, i) * (1.0/resolution.xy)); result += texture2D(tMap, coord).x; } } result /= 16.0; gl_FragColor = vec4(result, aoDepthP.y, 0.0, 1.0); #endif } {@}depthDownNormalCalc.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tDepth; uniform sampler2D tNormals; uniform vec2 uResolution; uniform vec2 uCameraNearFar; uniform vec3 uFrustum; uniform mat4 uInverseProjectionMatrix; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment #require(depthvalue.fs) // #define USE_CHECKERBOARD_DEPTH //if we trivialy accept differences between depths, there can be cases //where the shortest difference does not belong to the same edge, and because of that //a second depth is used to extrapolate the nearest depth value. //points that are on the same surface should (based on the diagram) more or less //end up at the same depth as the sampled one. //this is explained here: https://atyuwen.github.io/posts/normal-reconstruction/ vec3 calcNormalFromDepth(in float _depth, in vec2 _uv) { vec2 texSize = 1.0 / uResolution; ivec2 uv = ivec2(_uv * uResolution); if (abs(_depth) >= 1.0) { return vec3(0.0); } vec3 posEye = eyePosFromDepth(_depth, 0.1, 1000.0, _uv * uResolution, false); //find best depth along x... float dr = texelFetch(tDepth, uv + ivec2(1, 0), 0).x; float dr2 = texelFetch(tDepth, uv + ivec2(2, 0), 0).x; float dl = texelFetch(tDepth, uv - ivec2(1, 0), 0).x; float dl2 = texelFetch(tDepth, uv - ivec2(2, 0), 0).x; vec3 ddx = eyePosFromDepth(dr, 0.1, 1000.0, (_uv + vec2(texSize.x, 0.0))*uResolution, false) - posEye; vec3 ddx2 = posEye - eyePosFromDepth(dl, 0.1, 1000.0, (_uv - vec2(texSize.x, 0.0)) * uResolution, false); float horizontalEdgeRight = abs((2.0*dr - dr2) - _depth); float horizontalEdgeLeft = abs((2.0*dl - dl2) - _depth); vec3 deltaX = horizontalEdgeRight < horizontalEdgeLeft ? ddx : ddx2; //find best depth along y... float dt = texelFetch(tDepth, uv + ivec2(0, 1), 0).x; float dt2 = texelFetch(tDepth, uv + ivec2(0, 2), 0).x; float db = texelFetch(tDepth, uv - ivec2(0, 1), 0).x; float db2 = texelFetch(tDepth, uv - ivec2(0, 2), 0).x; vec3 ddy = eyePosFromDepth(dt, 0.1, 1000.0, (_uv + vec2(0.0, texSize.y)) * uResolution, false) - posEye; vec3 ddy2 = posEye - eyePosFromDepth(db, 0.1, 1000.0, (_uv - vec2(0.0, texSize.y)) * uResolution, false); float verticalEdgeTop = abs((2.0 * dt - dt2) - _depth); float verticalEdgeBottom = abs((2.0 * db - db2) - _depth); vec3 deltaY = verticalEdgeTop < verticalEdgeBottom ? ddy : ddy2; return normalize(cross(deltaX, deltaY)); } void main() { vec2 texel = (floor(vUv * uResolution) + 0.5) / uResolution; vec2 texSize = 1.0 / uResolution; vec2 desiredCoord = vec2(0.0); vec2 bl = texel; vec2 br = texel + vec2(texSize.x, 0.0); vec2 tl = texel + vec2(0.0, texSize.y); vec2 tr = texel + vec2(texSize); ivec2 fullResCoord = ivec2(vUv * uResolution); float bld = texelFetch(tDepth, fullResCoord, 0).x; float brd = texelFetch(tDepth, fullResCoord + ivec2(1, 0), 0).x; float tld = texelFetch(tDepth, fullResCoord + ivec2(0, 1), 0).x; float trd = texelFetch(tDepth, fullResCoord + ivec2(1, 1), 0).x; float depth; float maxDepth = max(max(bld, brd), max(tld, trd)); #ifdef USE_CHECKERBOARD_DEPTH float minDepth = min(min(bld, brd), min(tld, trd)); depth = mix(maxDepth, minDepth, float(int(gl_FragCoord.x) & 1 * int(gl_FragCoord.y) & 1)); #else depth = maxDepth; #endif int index = 0; float[] samples = float[4](bld, brd, tld, trd); vec2[] coords = vec2[4](bl, br, tl, tr); for(int i = 0; i < 4; ++i) { if (samples[i] == depth) { index = i; break; } } vec3 normal = calcNormalFromDepth(samples[index], coords[index]); // vec3 normal = calcNormalFromDepth(samples[0], coords[0]); gl_FragColor = vec4(normal, getEyeZ(samples[index], 0.1, 1000.0)); } {@}ssaoplus.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tNormal; uniform sampler2D tRotations; uniform sampler2D tBlueNoise; uniform vec3[24] uSampleOffsets; uniform vec3 uFrustum; uniform float uSampleRadius; uniform float uBias; uniform float uIntensity; uniform float uContrast; uniform float uProjectionScale; uniform float uTau; uniform float uQuality; uniform mat4 uInverseProjectionMatrix; uniform vec2 uCameraNearFar; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment #require(depthvalue.fs) #require(tridither.glsl) //#define USE_BLUE_NOISE //#define USE_PROJECTED_OFFSET #define PI 3.14159265359 #define TAU 3.14159265359 * 2.0 float alchemyHash(in vec2 c) { ivec2 iC = ivec2(c); return float(30 * iC.x ^ iC.y + iC.x * iC.y * 10); } vec2 getSampleOffset(in float i, in vec2 coord, in float r, float omega) { float alpha = (i + 0.5) * (1.0/uQuality); float hPrime = r * alpha; float turn = floor(uTau); float theta = alpha * (TAU * turn) + omega; return vec2(cos(theta), sin(theta)) * hPrime; } //sources: //https://casual-effects.com/research/McGuire2011AlchemyAO/VV11AlchemyAO.pdf //https://casual-effects.com/research/McGuire2012SAO/index.html //https://learnopengl.com/Advanced-Lighting/SSAO void main() { //vec2 coord = (floor(vUv * resolution.xy) + 0.5) / resolution.xy; vec2 coord = gl_FragCoord.xy; vec4 normalDepth = texelFetch(tNormal, ivec2(coord + 0.5), 0); vec3 normal = normalDepth.xyz; float depth = normalDepth.w; if (abs(depth) >= (uCameraNearFar.y - uCameraNearFar.x)) { gl_FragColor = vec4(1.0, depth, 0.0, 1.0); return; } vec3 viewPos = eyePosFromDepth(depth, uCameraNearFar.x, uCameraNearFar.y, coord, true); vec3 rVec; #ifdef USE_BLUE_NOISE rVec = vec3(2.0 * texture2D(tBlueNoise, gl_FragCoord.xy / 64.0) - 1.0) * vec3(1.0, 1.0, 0.0); #else rVec = normalize(texture2D(tRotations, gl_FragCoord.xy / 4.0).xyz); #endif #ifdef USE_PROJECTED_OFFSET vec3 tangent = normalize(rVec - (normal * dot(rVec, normal))); vec3 bitangent = cross(normal, tangent); mat3 tbn = mat3(tangent, bitangent, normal); #endif float occluded = 0.0; float quality = uQuality; float sampleRadius = -uSampleRadius * uProjectionScale / viewPos.z; float radius2 = uSampleRadius * uSampleRadius; float omega = alchemyHash(coord); for (float i = 0.0; i < quality; i++) { #ifdef USE_PROJECTED_OFFSET vec3 sampleDirection = tbn * uSampleOffsets[int(i)]; vec3 samplePos = viewPos + sampleDirection * sampleRadius; vec4 offset = projectionMatrix * vec4(samplePos, 1.0); offset.xyz /= offset.w; offset.xyz = offset.xyz * 0.5 + 0.5; offset.xy = (floor(offset.xy * resolution.xy) + 0.5) / resolution.xy; vec3 sampledPos = uvToEyePos(texelFetch(tNormal, ivec2(offset.xy * resolution.xy), 0).w, offset.xy); #else vec2 sampleOffset = getSampleOffset(i, coord, sampleRadius, omega); vec2 c = coord + sampleOffset; vec3 sampledPos = eyePosFromDepth(texelFetch(tNormal, ivec2(c+0.5), 0).w, uCameraNearFar.x, uCameraNearFar.y, c, true); #endif vec3 delta = sampledPos - viewPos; float nDotv = dot(delta, normal); float eps = 0.01; float denom = dot(delta, delta); float f = max(radius2 - denom, 0.0); //float bias = viewPos.z * uBias * 0.01; float bias = uBias * 0.01; occluded += max(0.0, (nDotv - bias) / (denom + eps)) * f * f * f; } float tmp = radius2 * uSampleRadius; occluded /= tmp * tmp; float a = pow(max(0.0, 1.0 - (((2.0 * uIntensity) / quality) * occluded)), uContrast); // gl_FragColor = vec4(a, getDepthValue(depth, uCameraNearFar.x, uCameraNearFar.y), 0.0 , 1.0); // a = dither1(a, gl_FragCoord.xy, time); gl_FragColor = vec4(a, depth, 0.0 , 1.0); } {@}upSampleSSAO.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tMap; uniform sampler2D tDepth; uniform vec2 uDownSampledDepthResolution; uniform vec2 uCameraNearFar; uniform float uSigma; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment #require(depthvalue.fs) //#define BILTERIAL_UPSAMPLE float gaussianWeight(in float sigma, in float x) { float sigma2 = sigma * sigma; return exp(-(x * x) / (2.0 * sigma2)); } void main() { vec2 depthCoord = floor(vUv * uDownSampledDepthResolution)/uDownSampledDepthResolution; vec2 desiredCoord = vec2(0.0); vec2 texSizeDepth = vec2(1.0 / uDownSampledDepthResolution.xy); vec2 texSize = vec2(1.0 / resolution.xy); float col = 0.0; vec2[4] coords; coords[0] = depthCoord; coords[1] = depthCoord + vec2(texSizeDepth.x, 0.0); coords[2] = depthCoord + vec2(0.0, texSizeDepth.y); coords[3] = depthCoord + vec2(texSizeDepth); vec2 fullResDepthCoord = floor(vUv * resolution.xy)/resolution.xy; float currentDepth = getEyeZ(texelFetch(tDepth, ivec2(gl_FragCoord.xy), 0).x, uCameraNearFar.x, uCameraNearFar.y); float[4] distances; distances[0] = abs(currentDepth - texelFetch(tMap, ivec2(coords[0]), 0).y); distances[1] = abs(currentDepth - texelFetch(tMap, ivec2(coords[1]), 0).y); distances[2] = abs(currentDepth - texelFetch(tMap, ivec2(coords[2]), 0).y); distances[3] = abs(currentDepth - texelFetch(tMap, ivec2(coords[3]), 0).y); #ifdef BILTERIAL_UPSAMPLE vec2 bfCoord = vUv * uDownSampledDepthResolution - 0.5; vec2 fCoord = fract(bfCoord); bfCoord = (floor(bfCoord) + 0.5) / uDownSampledDepthResolution; float a = texture2D(tMap, bfCoord).x; float b = texture2D(tMap, bfCoord + vec2(texSizeDepth.x, 0.0)).x; float c = texture2D(tMap, bfCoord + vec2(0.0, texSizeDepth.y)).x; float d = texture2D(tMap, bfCoord + texSizeDepth).x; float weightA = gaussianWeight(uSigma, distances[0]); float weightB = gaussianWeight(uSigma, distances[1]); float weightC = gaussianWeight(uSigma, distances[2]); float weightD = gaussianWeight(uSigma, distances[3]); col = mix(mix(a * weightA, b * weightB, fCoord.x), mix(c * weightC, d * weightD, fCoord.x), fCoord.y); #else //bilinearly sample SSAO texture if all depth samples are more or less on the same surface float depthThreshold = 0.0001; if( distances[0] < depthThreshold && distances[1] < depthThreshold && distances[2] < depthThreshold && distances[3] < depthThreshold ) { vec2 bfCoord = vUv * uDownSampledDepthResolution - 0.5; vec2 fCoord = fract(bfCoord); bfCoord = (floor(bfCoord) + 0.5) / uDownSampledDepthResolution; float a = texture2D(tMap, bfCoord).x; float b = texture2D(tMap, bfCoord + vec2(texSizeDepth.x, 0.0)).x; float c = texture2D(tMap, bfCoord + vec2(0.0, texSizeDepth.y)).x; float d = texture2D(tMap, bfCoord + texSizeDepth).x; col = mix(mix(a, b, fCoord.x), mix(c, d, fCoord.x), fCoord.y); } else { float minDist = distances[0]; desiredCoord = coords[0]; if(distances[1] < minDist) { minDist = distances[1]; desiredCoord = coords[1]; } if(distances[2] < minDist) { minDist = distances[2]; desiredCoord = coords[2]; } if(distances[3] < minDist) { minDist = distances[3]; desiredCoord = coords[3]; } col = texture2D(tMap, desiredCoord).x; } #endif gl_FragColor = vec4(col, 0.0, 0.0, 1.0); } {@}worldposdebug.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tDepth; uniform vec3 uFrustum; uniform vec2 uCameraNearFar; #!VARYINGS varying vec3 vRay; varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); //vRay = (inverse(mat3(viewMatrix)) * vec3(position.xy, -1.0) * uFrustum); // vec4 r = inverse(projectionMatrix) * vec4(position.xy, 1.0, 1.0); // r /= r.w; // vRay = r.xyz; //vRay = (viewMatrix[0].xyz * uFrustum.x * position.x) + (viewMatrix[1].xyz * uFrustum.y * position.y) + (viewMatrix[3].xyz * uCameraNearFar.y); vRay = mat3(viewMatrix) * vec3(position.xy, -1.0) * uFrustum; vUv = uv; } #!SHADER: Fragment #require(depthvalue.fs) vec3 uvToEye(in sampler2D depth, in vec2 uv) { vec4 mvPos = inverse(projectionMatrix) * vec4(2.0 * uv - 1.0, 2.0 * texture2D(depth, uv).x - 1.0, 1.0); mvPos /= mvPos.w; return mvPos.xyz; } vec3 uvToEye(in float depth, in vec2 uv) { vec4 mvPos = inverse(projectionMatrix) * vec4(2.0 * uv - 1.0, 2.0 * depth - 1.0, 1.0); mvPos /= mvPos.w; return mvPos.xyz; } float LinearizeDepth(float depth, float near, float far) { float z = depth * 2.0 - 1.0; // back to NDC return (2.0 * near * far) / (far + near - z * (far - near)); } void main() { // float linearDepth = getDepthValue(texelFetch(tDepth, ivec2(gl_FragCoord.xy + 0.5), 0).x, uCameraNearFar.x, uCameraNearFar.y); float linearDepth = LinearizeDepth(texelFetch(tDepth, ivec2(gl_FragCoord.xy + 0.5), 0).x, uCameraNearFar.x, uCameraNearFar.y); //vec3 worldPos = (vec3(2.0 * vUv - 1.0, -1.0) * uFrustum * linearDepth); float x = (1.0 - projectionMatrix[2][0]) / projectionMatrix[0][0] - (2.0 * (gl_FragCoord.x + 0.5) / (resolution.x * projectionMatrix[0][0])); float y = (1.0 + projectionMatrix[2][1]) / projectionMatrix[1][1] - (2.0 * (gl_FragCoord.y + 0.5) / (resolution.y * projectionMatrix[1][1])); gl_FragColor = vec4(vec2(x,y)*-linearDepth, -linearDepth, 1.0); // gl_FragColor = vec4(uvToEye(tDepth, vUv), 1.0); } {@}TweenUILPathFallbackShader.glsl{@}#!ATTRIBUTES attribute float speed; #!UNIFORMS uniform vec3 uColor; uniform vec3 uColor2; uniform float uOpacity; #!VARYINGS varying vec3 vColor; #!SHADER: Vertex void main() { vColor = mix(uColor, uColor2, speed); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } #!SHADER: Fragment void main() { gl_FragColor = vec4(vColor, uOpacity); } {@}TweenUILPathShader.glsl{@}#!ATTRIBUTES attribute float speed; #!UNIFORMS uniform vec3 uColor2; #!VARYINGS #!SHADER: Vertex void main() { vColor = mix(uColor, uColor2, speed); } void customDirection() { // Use screen space coordinates for final position, so line thickness is // independent of camera. finalPosition = vec4(currentP.x / aspect, currentP.y, min(0.0, finalPosition.z), 1.0); } #!SHADER: Fragment float tri(float v) { return mix(v, 1.0 - v, step(0.5, v)) * 2.0; } void main() { float signedDist = tri(vUv.y) - 0.5; gl_FragColor.a *= clamp(signedDist/fwidth(signedDist) + 0.5, 0.0, 1.0); } {@}UnrealBloom.fs{@}uniform sampler2D tUnrealBloom; vec3 getUnrealBloom(vec2 uv) { return texture2D(tUnrealBloom, uv).rgb; }{@}UnrealBloomComposite.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D blurTexture1; uniform float bloomStrength; uniform float bloomRadius; uniform vec3 bloomTintColor; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex.vs void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: Fragment.fs float lerpBloomFactor(const in float factor) { float mirrorFactor = 1.2 - factor; return mix(factor, mirrorFactor, bloomRadius); } void main() { gl_FragColor = bloomStrength * (lerpBloomFactor(1.0) * vec4(bloomTintColor, 1.0) * texture2D(blurTexture1, vUv)); }{@}UnrealBloomGaussian.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D colorTexture; uniform vec2 texSize; uniform vec2 direction; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex.vs void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: Fragment.fs float gaussianPdf(in float x, in float sigma) { return 0.39894 * exp(-0.5 * x * x / (sigma * sigma)) / sigma; } void main() { vec2 invSize = 1.0 / texSize; float fSigma = float(SIGMA); float weightSum = gaussianPdf(0.0, fSigma); vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum; for(int i = 1; i < KERNEL_RADIUS; i ++) { float x = float(i); float w = gaussianPdf(x, fSigma); vec2 uvOffset = direction * invSize * x; vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb; vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb; diffuseSum += (sample1 + sample2) * w; weightSum += 2.0 * w; } gl_FragColor = vec4(diffuseSum/weightSum, 1.0); }{@}UnrealBloomLuminosity.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tDiffuse; uniform vec3 defaultColor; uniform float defaultOpacity; uniform float luminosityThreshold; uniform float smoothWidth; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex.vs void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: Fragment.fs #require(luma.fs) void main() { vec4 texel = texture2D(tDiffuse, vUv); float v = luma(texel.xyz); vec4 outputColor = vec4(defaultColor.rgb, defaultOpacity); float alpha = smoothstep(luminosityThreshold, luminosityThreshold + smoothWidth, v); gl_FragColor = mix(outputColor, texel, alpha); }{@}UnrealBloomPass.fs{@}#require(UnrealBloom.fs) void main() { vec4 color = texture2D(tDiffuse, vUv); color.rgb += getUnrealBloom(vUv); gl_FragColor = color; }{@}luma.fs{@}float luma(vec3 color) { return dot(color, vec3(0.299, 0.587, 0.114)); } float luma(vec4 color) { return dot(color.rgb, vec3(0.299, 0.587, 0.114)); }{@}DrawShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform sampler2D tSource; uniform sampler2D tBrush; uniform sampler2D tNoise; uniform vec2 uPosition; uniform vec2 uResolution; uniform float uSharp; uniform float uSize; uniform float uTrail; uniform float uVelocity; uniform vec2 uMouseMove; uniform sampler2D tFluidMask; #!VARYINGS varying vec2 vUv; #!SHADER: DrawShader.vs void main() { vUv = uv; gl_Position = vec4(position, 1.0); } #!SHADER: DrawShader.fs #require(simplenoise.glsl) void main() { vec2 uv = gl_FragCoord.xy / uResolution.xx; vec2 st = gl_FragCoord.xy / resolution; vec3 noiseT = texture2D(tNoise, uv).rgb; vec2 uv2 = vUv; uv2.y += uVelocity * smoothstep(0.8, 0.05, length(uMouseMove-uv)) * 0.004; float fluidMask = 0.; fluidMask = texture2D(tFluidMask, uv2).r; vec4 brush = texture2D(tBrush, st + noiseT.g * 0.02); vec3 trail = texture2D(tSource, uv2).rgb * uTrail; float trailG = smoothstep(texture2D(tSource, uv2).g, 0.2, 1.) ; float noise = getNoise(uv, trail.r); vec2 mousePos = vec2(uPosition.x, uResolution.y - uPosition.y) / uResolution.xx; float sharp = uSharp * 0.5; gl_FragColor = vec4(vec3(brush.r, brush.g, brush.b) * noise, 0.2); gl_FragColor.r += trail.r * 0.998; gl_FragColor.g += trail.g * 0.994; gl_FragColor.b += trail.b * 0.992; gl_FragColor.rgb = min(vec3(gl_FragColor.rgb), 1.); // gl_FragColor.g = fluidMask; }{@}NoiseShader.glsl{@}#!ATTRIBUTES #!UNIFORMS uniform float uMask; uniform float uFreqNoise; uniform float uFactorTime; uniform float uStrengthPattern; uniform float uGlobalAmplitude; uniform vec3 uNoiseActive; #!VARYINGS varying vec2 vUv; #!SHADER: Vertex void main() { gl_Position = vec4(position, 1.0); vUv = uv; } #!SHADER: Fragment #require(perlin.glsl) void main() { float ratio = resolution.x / resolution.y; vec2 squareUV = vUv / vec2(1., ratio); vec2 uv = squareUV; float gradientMask = distance(vUv, vec2(0.5)) * uMask; float noiseR = uNoiseActive.x > 0.5 ? perlin(vec3(uv * uFreqNoise, time * 0.4 * uFactorTime)) * uStrengthPattern + uGlobalAmplitude + gradientMask : 0.; float noiseG = uNoiseActive.y > 0.5 ? perlin(vec3(uv * uFreqNoise * 1., time * 1. * uFactorTime)) * uStrengthPattern + uGlobalAmplitude + gradientMask : 0.; float noiseB = uNoiseActive.z > 0.5 ? perlin(vec3(uv * uFreqNoise * 4., time * 0.4 * uFactorTime)) * uStrengthPattern + uGlobalAmplitude + gradientMask : 0.; gl_FragColor = vec4(vec3(noiseR, noiseG, noiseB), 1.0); } {@}perlin.glsl{@}vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);} vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;} vec3 fade(vec3 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);} float perlin(vec3 P){ vec3 Pi0 = floor(P); // Integer part for indexing vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1 Pi0 = mod(Pi0, 289.0); Pi1 = mod(Pi1, 289.0); vec3 Pf0 = fract(P); // Fractional part for interpolation vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); vec4 iy = vec4(Pi0.yy, Pi1.yy); vec4 iz0 = Pi0.zzzz; vec4 iz1 = Pi1.zzzz; vec4 ixy = permute(permute(ix) + iy); vec4 ixy0 = permute(ixy + iz0); vec4 ixy1 = permute(ixy + iz1); vec4 gx0 = ixy0 / 7.0; vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5; gx0 = fract(gx0); vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); vec4 sz0 = step(gz0, vec4(0.0)); gx0 -= sz0 * (step(0.0, gx0) - 0.5); gy0 -= sz0 * (step(0.0, gy0) - 0.5); vec4 gx1 = ixy1 / 7.0; vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5; gx1 = fract(gx1); vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); vec4 sz1 = step(gz1, vec4(0.0)); gx1 -= sz1 * (step(0.0, gx1) - 0.5); gy1 -= sz1 * (step(0.0, gy1) - 0.5); vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); g000 *= norm0.x; g010 *= norm0.y; g100 *= norm0.z; g110 *= norm0.w; vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); g001 *= norm1.x; g011 *= norm1.y; g101 *= norm1.z; g111 *= norm1.w; float n000 = dot(g000, Pf0); float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); float n111 = dot(g111, Pf1); vec3 fade_xyz = fade(Pf0); vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); return 2.2 * n_xyz; } {@}spritesheetUV.glsl{@}#require(uvgrid.glsl) vec2 spritesheetUV(vec2 uv, float gridTime, float gridWidth, float gridHeight, float loop) { float size = gridWidth * gridHeight; float index = gridTime * size - 0.001; if (loop > 0.5) { index = mod(gridTime * size, size); } index = floor(index); float xOffset = mod(index, gridWidth); float yOffset = floor(index / gridHeight); yOffset = gridHeight - 1.0 - yOffset; return getUVForGrid(uv, gridWidth, gridHeight, xOffset, yOffset); }