From 52e24e9b2be7aec579970a5a777503e6f33a8664 Mon Sep 17 00:00:00 2001 From: lxsang Date: Mon, 21 Jun 2021 00:04:52 +0200 Subject: [PATCH] update ShaderPlayground --- ShaderPlayground/README.md | 3 + ShaderPlayground/build.json | 17 +- ShaderPlayground/build/debug/README.md | 3 + ShaderPlayground/build/debug/glslx.js | 77 ---- ShaderPlayground/build/debug/main.js | 2 +- ShaderPlayground/build/debug/package.json | 46 ++- .../build/release/ShaderPlayground.zip | Bin 44449 -> 5716 bytes ShaderPlayground/glslx.js | 77 ---- ShaderPlayground/main.ts | 361 ++++++++++++++++-- ShaderPlayground/package.json | 46 ++- packages.json | 2 +- 11 files changed, 419 insertions(+), 215 deletions(-) delete mode 100644 ShaderPlayground/build/debug/glslx.js delete mode 100644 ShaderPlayground/glslx.js diff --git a/ShaderPlayground/README.md b/ShaderPlayground/README.md index 8b9d26f..73fc187 100644 --- a/ShaderPlayground/README.md +++ b/ShaderPlayground/README.md @@ -4,4 +4,7 @@ Playground for working with Open GL shader language, the sharder is rendered with the Three.js library ## Change logs +- v0.0.2-a: + - Remove GLSLX, use the default WEBGL API for shader compiling + - Allow save/open shader source code to/from file (JSON) - v0.0.1-a: Initial version \ No newline at end of file diff --git a/ShaderPlayground/build.json b/ShaderPlayground/build.json index dfa7ad9..caba844 100644 --- a/ShaderPlayground/build.json +++ b/ShaderPlayground/build.json @@ -47,8 +47,7 @@ "scheme.html", "package.json", "README.md", - "main.css", - "glslx.js" + "main.css" ], "dest":"build/debug" } @@ -79,6 +78,20 @@ "build and run": { "depend": ["clean", "build", "copy", "run"], "jobs": [] + }, + "locale": { + "require": ["locale"], + "jobs": [ + { + "name":"locale-gen", + "data": { + "src": "", + "exclude": ["build/"], + "locale": "en_GB", + "dest": "package.json" + } + } + ] } } } \ No newline at end of file diff --git a/ShaderPlayground/build/debug/README.md b/ShaderPlayground/build/debug/README.md index 8b9d26f..73fc187 100644 --- a/ShaderPlayground/build/debug/README.md +++ b/ShaderPlayground/build/debug/README.md @@ -4,4 +4,7 @@ Playground for working with Open GL shader language, the sharder is rendered with the Three.js library ## Change logs +- v0.0.2-a: + - Remove GLSLX, use the default WEBGL API for shader compiling + - Allow save/open shader source code to/from file (JSON) - v0.0.1-a: Initial version \ No newline at end of file diff --git a/ShaderPlayground/build/debug/glslx.js b/ShaderPlayground/build/debug/glslx.js deleted file mode 100644 index 5767934..0000000 --- a/ShaderPlayground/build/debug/glslx.js +++ /dev/null @@ -1,77 +0,0 @@ -(function(){var ah=Object.create||function(a){return{__proto__:a}};function ph(a,b){a.prototype=ah(b.prototype),a.prototype.constructor=a}var qh=Math.imul||function(a,b){return (a*(b>>>16)<<16)+a*(b&65535)|0};var Xe;function rh(a){return typeof a==='string'}function sh(a){return a===null?a:a+''}function Ue(c,a,b){return c.a=a,c.b=b,c.c=a.length,c}function Ve(c){if(c.b>=c.c)return-1;var a=c.a.charCodeAt((c.b=c.b+1|0)-1|0);if(a&64512^55296)return a;if(c.b>=c.c)return-1;var b=c.a.charCodeAt((c.b=c.b+1|0)-1|0);return ((a<<10)+b|0)-56613888|0}function sc(a){return a.c=a.c+1|0,a.c}function Sc(p,a){switch(a){case 0:var b={};return Array.from(p.b.keys()).forEach(function(c){b[c]=p.b.get(c)}),JSON.stringify({shaders:p.a?p.a.map(function(d){return{name:d.a,contents:d.b}}):null,renaming:b},null,2)+'\n';case 1:if(p.a){for(var e='',C=0,B=p.a,U=B.length;C',"\nimport {\n // The variable `gl_Position` is available only in the vertex language and is intended for writing the\n // homogeneous vertex position. This value will be used by primitive assembly, clipping, culling, and other\n // fixed functionality operations that operate on primitives after vertex processing has occurred.\n //\n // All executions of a well-formed vertex shader should write a value into this variable. It can be\n // written at any time during shader execution. It may also be read back by the shader after being written.\n // Compilers may generate a diagnostic message if they detect `gl_Position` is not written, or read before\n // being written, but not all such cases are detectable. The value of `gl_Position` is undefined if a vertex\n // shader is executed and does not write `gl_Position`.\n highp vec4 gl_Position;\n\n // The variable `gl_PointSize` is available only in the vertex language and is intended for\n // a vertex shader to write the size of the point to be rasterized. It is measured in pixels.\n mediump float gl_PointSize;\n\n const int gl_MaxVertexAttribs;\n const int gl_MaxVertexUniformVectors;\n const int gl_MaxVaryingVectors;\n const int gl_MaxVertexTextureImageUnits;\n const int gl_MaxCombinedTextureImageUnits;\n const int gl_MaxTextureImageUnits;\n const int gl_MaxFragmentUniformVectors;\n const int gl_MaxDrawBuffers;\n\n // The fragment shader has access to the read-only built-in variable `gl_FrontFacing` whose value is `true` if\n // the fragment belongs to a front-facing primitive. One use of this is to emulate two-sided lighting by\n // selecting one of two colors calculated by the vertex shader.\n const bool gl_FrontFacing;\n\n // The fragment shader has access to the read-only built-in variable `gl_PointCoord`. The values in\n // `gl_PointCoord` are two-dimensional coordinates indicating where within a point primitive the current\n // fragment is located. They range from 0.0 to 1.0 across the point. If the current primitive is not a\n // point, then the values read from `gl_PointCoord` are undefined.\n const mediump vec2 gl_PointCoord;\n\n // The variable `gl_FragCoord` is available as a read-only variable from within fragment shaders and it holds\n // the window relative coordinates `x`, `y`, `z`, and `1/w` values for the fragment. This value is the result\n // of the fixed functionality that interpolates primitives after vertex processing to generate fragments. The `z`\n // component is the depth value that will be used for the fragment's depth.\n const mediump vec4 gl_FragCoord;\n\n // Writing to `gl_FragColor` specifies the fragment color that will be used by the subsequent fixed\n // functionality pipeline.\n //\n // If subsequent fixed functionality consumes fragment color and an execution of a fragment shader\n // does not write a value to `gl_FragColor` then the fragment color consumed is undefined.\n mediump vec4 gl_FragColor;\n\n // The variable `gl_FragData` is an array. Writing to `gl_FragData[n]` specifies the fragment data that will be\n // used by the subsequent fixed functionality pipeline for data `n`.\n //\n // If subsequent fixed functionality consumes fragment data and an execution of a fragment shader does not write\n // a value to it, then the fragment data consumed is undefined.\n mediump vec4 gl_FragData[gl_MaxDrawBuffers];\n\n // Depth range in window coordinates\n struct gl_DepthRangeParameters {\n float near;\n float far;\n // Equal to `far - near`\n float diff;\n };\n\n uniform gl_DepthRangeParameters gl_DepthRange;\n\n ////////////////////////////////////////////////////////////////////////////////\n // Angle and Trigonometry Functions\n\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n float radians(float degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec2 radians(vec2 degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec3 radians(vec3 degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec4 radians(vec4 degrees);\n\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n float degrees(float radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec2 degrees(vec2 radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec3 degrees(vec3 radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec4 degrees(vec4 radians);\n\n // The standard trigonometric sine function.\n float sin(float angle);\n // The standard trigonometric sine function.\n vec2 sin(vec2 angle);\n // The standard trigonometric sine function.\n vec3 sin(vec3 angle);\n // The standard trigonometric sine function.\n vec4 sin(vec4 angle);\n\n // The standard trigonometric cosine function.\n float cos(float angle);\n // The standard trigonometric cosine function.\n vec2 cos(vec2 angle);\n // The standard trigonometric cosine function.\n vec3 cos(vec3 angle);\n // The standard trigonometric cosine function.\n vec4 cos(vec4 angle);\n\n // The standard trigonometric tangent.\n float tan(float angle);\n // The standard trigonometric tangent.\n vec2 tan(vec2 angle);\n // The standard trigonometric tangent.\n vec3 tan(vec3 angle);\n // The standard trigonometric tangent.\n vec4 tan(vec4 angle);\n\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n float asin(float x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec2 asin(vec2 x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec3 asin(vec3 x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec4 asin(vec4 x);\n\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n float acos(float x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec2 acos(vec2 x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec3 acos(vec3 x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec4 acos(vec4 x);\n\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n float atan(float y, float x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec2 atan(vec2 y, vec2 x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec3 atan(vec3 y, vec3 x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec4 atan(vec4 y, vec4 x);\n\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n float atan(float y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec2 atan(vec2 y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec3 atan(vec3 y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec4 atan(vec4 y_over_x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Exponential Functions\n\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n float pow(float x, float y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec2 pow(vec2 x, vec2 y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec3 pow(vec3 x, vec3 y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec4 pow(vec4 x, vec4 y);\n\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n float exp(float x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec2 exp(vec2 x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec3 exp(vec3 x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec4 exp(vec4 x);\n\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n float log(float x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec2 log(vec2 x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec3 log(vec3 x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec4 log(vec4 x);\n\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n float exp2(float x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec2 exp2(vec2 x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec3 exp2(vec3 x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec4 exp2(vec4 x);\n\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n float log2(float x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec2 log2(vec2 x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec3 log2(vec3 x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec4 log2(vec4 x);\n\n // Returns `√x`. Results are undefined if `x < 0`.\n float sqrt(float x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec2 sqrt(vec2 x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec3 sqrt(vec3 x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec4 sqrt(vec4 x);\n\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n float inversesqrt(float x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec2 inversesqrt(vec2 x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec3 inversesqrt(vec3 x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec4 inversesqrt(vec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Common Functions\n\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n float abs(float x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec2 abs(vec2 x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec3 abs(vec3 x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec4 abs(vec4 x);\n\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n float sign(float x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec2 sign(vec2 x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec3 sign(vec3 x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec4 sign(vec4 x);\n\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n float floor(float x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec2 floor(vec2 x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec3 floor(vec3 x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec4 floor(vec4 x);\n\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n float ceil(float x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec2 ceil(vec2 x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec3 ceil(vec3 x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec4 ceil(vec4 x);\n\n // Returns `x - floor(x)`\n float fract(float x);\n // Returns `x - floor(x)`\n vec2 fract(vec2 x);\n // Returns `x - floor(x)`\n vec3 fract(vec3 x);\n // Returns `x - floor(x)`\n vec4 fract(vec4 x);\n\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n float mod(float x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec2 mod(vec2 x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec3 mod(vec3 x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec4 mod(vec4 x, float y);\n\n // Modulus. Returns `x - y * floor(x/y)`\n vec2 mod(vec2 x, vec2 y);\n // Modulus. Returns `x - y * floor(x/y)`\n vec3 mod(vec3 x, vec3 y);\n // Modulus. Returns `x - y * floor(x/y)`\n vec4 mod(vec4 x, vec4 y);\n\n // Returns `y` if `y < x`, otherwise it returns `x`\n float min(float x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec2 min(vec2 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec2 min(vec2 x, vec2 y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec3 min(vec3 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec3 min(vec3 x, vec3 y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec4 min(vec4 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec4 min(vec4 x, vec4 y);\n\n // Returns `y` if `x < y`, otherwise it returns `x`\n float max(float x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec2 max(vec2 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec2 max(vec2 x, vec2 y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec3 max(vec3 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec3 max(vec3 x, vec3 y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec4 max(vec4 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec4 max(vec4 x, vec4 y);\n\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n float clamp(float x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec2 clamp(vec2 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec3 clamp(vec3 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec4 clamp(vec4 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);\n\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n float mix(float x, float y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec2 mix(vec2 x, vec2 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec2 mix(vec2 x, vec2 y, vec2 a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec3 mix(vec3 x, vec3 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec3 mix(vec3 x, vec3 y, vec3 a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec4 mix(vec4 x, vec4 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec4 mix(vec4 x, vec4 y, vec4 a);\n\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n float step(float edge, float x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec2 step(float edge, vec2 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec2 step(vec2 edge, vec2 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec3 step(float edge, vec3 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec3 step(vec3 edge, vec3 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec4 step(float edge, vec4 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec4 step(vec4 edge, vec4 x);\n\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n float smoothstep(float edge0, float edge1, float x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec2 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec2 smoothstep(float edge0, float edge1, vec2 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec2 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec3 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec3 smoothstep(float edge0, float edge1, vec3 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec3 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec4 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec4 smoothstep(float edge0, float edge1, vec4 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec4 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Geometric Functions\n\n // Returns the length of vector `x`, i.e. `√x²`\n float length(float x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]²`\n float length(vec2 x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]² + x[2]²`\n float length(vec3 x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]² + x[2]² + x[3]²`\n float length(vec4 x);\n\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(float p0, float p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec2 p0, vec2 p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec3 p0, vec3 p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec4 p0, vec4 p1);\n\n // Returns the dot product of `x` and `y`, i.e. `x*y`\n float dot(float x, float y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1]`\n float dot(vec2 x, vec2 y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1] + x[2]*y[2]`\n float dot(vec3 x, vec3 y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3]`\n float dot(vec4 x, vec4 y);\n\n // Returns the cross product of `x` and `y`, i.e.\n //\n // ```glslx\n // vec3(\n // x[1]*y[2] - y[1]*x[2],\n // x[2]*y[0] - y[2]*x[0],\n // x[0]*y[1] - y[0]*x[1])\n // ```\n vec3 cross(vec3 x, vec3 y);\n\n // Returns a vector in the same direction as `x` but with a length of 1.\n float normalize(float x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec2 normalize(vec2 x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec3 normalize(vec3 x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec4 normalize(vec4 x);\n\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n float faceforward(float N, float I, float Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec2 faceforward(vec2 N, vec2 I, vec2 Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec3 faceforward(vec3 N, vec3 I, vec3 Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec4 faceforward(vec4 N, vec4 I, vec4 Nref);\n\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n float reflect(float I, float N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec2 reflect(vec2 I, vec2 N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec3 reflect(vec3 I, vec3 N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec4 reflect(vec4 I, vec4 N);\n\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return float(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n float refract(float I, float N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec2(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec2 refract(vec2 I, vec2 N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec3(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec3 refract(vec3 I, vec3 N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec4(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec4 refract(vec4 I, vec4 N, float eta);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Matrix Functions\n\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat2 matrixCompMult(mat2 x, mat2 y);\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat3 matrixCompMult(mat3 x, mat3 y);\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat4 matrixCompMult(mat4 x, mat4 y);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Vector Relational Functions\n\n // Returns the component-wise compare of `x < y`.\n bvec2 lessThan(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x < y`.\n bvec2 lessThan(vec2 x, vec2 y);\n // Returns the component-wise compare of `x < y`.\n bvec3 lessThan(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x < y`.\n bvec3 lessThan(vec3 x, vec3 y);\n // Returns the component-wise compare of `x < y`.\n bvec4 lessThan(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x < y`.\n bvec4 lessThan(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x <= y`.\n bvec2 lessThanEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x <= y`.\n bvec2 lessThanEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x <= y`.\n bvec3 lessThanEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x <= y`.\n bvec3 lessThanEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x <= y`.\n bvec4 lessThanEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x <= y`.\n bvec4 lessThanEqual(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x > y`.\n bvec2 greaterThan(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x > y`.\n bvec2 greaterThan(vec2 x, vec2 y);\n // Returns the component-wise compare of `x > y`.\n bvec3 greaterThan(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x > y`.\n bvec3 greaterThan(vec3 x, vec3 y);\n // Returns the component-wise compare of `x > y`.\n bvec4 greaterThan(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x > y`.\n bvec4 greaterThan(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x >= y`.\n bvec2 greaterThanEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x >= y`.\n bvec2 greaterThanEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x >= y`.\n bvec3 greaterThanEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x >= y`.\n bvec3 greaterThanEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x >= y`.\n bvec4 greaterThanEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x >= y`.\n bvec4 greaterThanEqual(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(bvec2 x, bvec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(vec2 x, vec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(bvec3 x, bvec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(vec3 x, vec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(bvec4 x, bvec4 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(bvec2 x, bvec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(bvec3 x, bvec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(bvec4 x, bvec4 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(vec4 x, vec4 y);\n\n // Returns true if any component of `x` is `true`.\n bool any(bvec2 x);\n // Returns true if any component of `x` is `true`.\n bool any(bvec3 x);\n // Returns true if any component of `x` is `true`.\n bool any(bvec4 x);\n\n // Returns true only if all components of `x` are `true`.\n bool all(bvec2 x);\n // Returns true only if all components of `x` are `true`.\n bool all(bvec3 x);\n // Returns true only if all components of `x` are `true`.\n bool all(bvec4 x);\n\n // Returns the component-wise logical complement of `x`.\n bvec2 not(bvec2 x);\n // Returns the component-wise logical complement of `x`.\n bvec3 not(bvec3 x);\n // Returns the component-wise logical complement of `x`.\n bvec4 not(bvec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Texture Lookup Functions\n\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2D(sampler2D sampler, vec2 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2D(sampler2D sampler, vec2 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProj(sampler2D sampler, vec3 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProj(sampler2D sampler, vec4 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);\n\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCube(samplerCube sampler, vec3 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCube(samplerCube sampler, vec3 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);\n\n #extension GL_OES_standard_derivatives {\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n float dFdx(float v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec2 dFdx(vec2 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec3 dFdx(vec3 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec4 dFdx(vec4 v);\n\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n float dFdy(float v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec2 dFdy(vec2 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec3 dFdy(vec3 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec4 dFdy(vec4 v);\n\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n float fwidth(float v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec2 fwidth(vec2 v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec3 fwidth(vec3 v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec4 fwidth(vec4 v);\n }\n\n #extension GL_EXT_frag_depth {\n // Available only in the fragment language, `gl_FragDepthEXT` is an output variable that is used to establish the depth value for the current fragment.\n // If depth buffering is enabled and no shader writes to `gl_FragDepthEXT`, then the fixed function value for depth will be used (this value is contained\n // in the `z` component of `gl_FragCoord`) otherwise, the value written to `gl_FragDepthEXT` is used.\n //\n // If a shader statically assigns to `gl_FragDepthEXT`, then the value of the fragment's depth may be undefined for executions of the shader that take\n // that path. That is, if the set of linked fragment shaders statically contain a write to `gl_FragDepthEXT`, then it is responsible for always writing it.\n float gl_FragDepthEXT;\n }\n\n #extension GL_EXT_shader_texture_lod {\n vec4 texture2DGradEXT(sampler2D sampler, vec2 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DLodEXT(sampler2D sampler, vec2 coord, float lod);\n vec4 texture2DProjGradEXT(sampler2D sampler, vec3 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DProjGradEXT(sampler2D sampler, vec4 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DProjLodEXT(sampler2D sampler, vec3 coord, float lod);\n vec4 texture2DProjLodEXT(sampler2D sampler, vec4 coord, float lod);\n vec4 textureCubeGradEXT(samplerCube sampler, vec3 P, vec3 dPdx, vec3 dPdy);\n vec4 textureCubeLodEXT(samplerCube sampler, vec3 coord, float lod);\n }\n}\n")); -for(var o=0,k=b.length;o',"\nimport {\n // The variable `gl_Position` is available only in the vertex language and is intended for writing the\n // homogeneous vertex position. This value will be used by primitive assembly, clipping, culling, and other\n // fixed functionality operations that operate on primitives after vertex processing has occurred.\n //\n // All executions of a well-formed vertex shader should write a value into this variable. It can be\n // written at any time during shader execution. It may also be read back by the shader after being written.\n // Compilers may generate a diagnostic message if they detect `gl_Position` is not written, or read before\n // being written, but not all such cases are detectable. The value of `gl_Position` is undefined if a vertex\n // shader is executed and does not write `gl_Position`.\n highp vec4 gl_Position;\n\n // The variable `gl_PointSize` is available only in the vertex language and is intended for\n // a vertex shader to write the size of the point to be rasterized. It is measured in pixels.\n mediump float gl_PointSize;\n\n const int gl_MaxVertexAttribs;\n const int gl_MaxVertexUniformVectors;\n const int gl_MaxVaryingVectors;\n const int gl_MaxVertexTextureImageUnits;\n const int gl_MaxCombinedTextureImageUnits;\n const int gl_MaxTextureImageUnits;\n const int gl_MaxFragmentUniformVectors;\n const int gl_MaxDrawBuffers;\n\n // The fragment shader has access to the read-only built-in variable `gl_FrontFacing` whose value is `true` if\n // the fragment belongs to a front-facing primitive. One use of this is to emulate two-sided lighting by\n // selecting one of two colors calculated by the vertex shader.\n const bool gl_FrontFacing;\n\n // The fragment shader has access to the read-only built-in variable `gl_PointCoord`. The values in\n // `gl_PointCoord` are two-dimensional coordinates indicating where within a point primitive the current\n // fragment is located. They range from 0.0 to 1.0 across the point. If the current primitive is not a\n // point, then the values read from `gl_PointCoord` are undefined.\n const mediump vec2 gl_PointCoord;\n\n // The variable `gl_FragCoord` is available as a read-only variable from within fragment shaders and it holds\n // the window relative coordinates `x`, `y`, `z`, and `1/w` values for the fragment. This value is the result\n // of the fixed functionality that interpolates primitives after vertex processing to generate fragments. The `z`\n // component is the depth value that will be used for the fragment's depth.\n const mediump vec4 gl_FragCoord;\n\n // Writing to `gl_FragColor` specifies the fragment color that will be used by the subsequent fixed\n // functionality pipeline.\n //\n // If subsequent fixed functionality consumes fragment color and an execution of a fragment shader\n // does not write a value to `gl_FragColor` then the fragment color consumed is undefined.\n mediump vec4 gl_FragColor;\n\n // The variable `gl_FragData` is an array. Writing to `gl_FragData[n]` specifies the fragment data that will be\n // used by the subsequent fixed functionality pipeline for data `n`.\n //\n // If subsequent fixed functionality consumes fragment data and an execution of a fragment shader does not write\n // a value to it, then the fragment data consumed is undefined.\n mediump vec4 gl_FragData[gl_MaxDrawBuffers];\n\n // Depth range in window coordinates\n struct gl_DepthRangeParameters {\n float near;\n float far;\n // Equal to `far - near`\n float diff;\n };\n\n uniform gl_DepthRangeParameters gl_DepthRange;\n\n ////////////////////////////////////////////////////////////////////////////////\n // Angle and Trigonometry Functions\n\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n float radians(float degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec2 radians(vec2 degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec3 radians(vec3 degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec4 radians(vec4 degrees);\n\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n float degrees(float radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec2 degrees(vec2 radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec3 degrees(vec3 radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec4 degrees(vec4 radians);\n\n // The standard trigonometric sine function.\n float sin(float angle);\n // The standard trigonometric sine function.\n vec2 sin(vec2 angle);\n // The standard trigonometric sine function.\n vec3 sin(vec3 angle);\n // The standard trigonometric sine function.\n vec4 sin(vec4 angle);\n\n // The standard trigonometric cosine function.\n float cos(float angle);\n // The standard trigonometric cosine function.\n vec2 cos(vec2 angle);\n // The standard trigonometric cosine function.\n vec3 cos(vec3 angle);\n // The standard trigonometric cosine function.\n vec4 cos(vec4 angle);\n\n // The standard trigonometric tangent.\n float tan(float angle);\n // The standard trigonometric tangent.\n vec2 tan(vec2 angle);\n // The standard trigonometric tangent.\n vec3 tan(vec3 angle);\n // The standard trigonometric tangent.\n vec4 tan(vec4 angle);\n\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n float asin(float x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec2 asin(vec2 x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec3 asin(vec3 x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec4 asin(vec4 x);\n\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n float acos(float x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec2 acos(vec2 x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec3 acos(vec3 x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec4 acos(vec4 x);\n\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n float atan(float y, float x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec2 atan(vec2 y, vec2 x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec3 atan(vec3 y, vec3 x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec4 atan(vec4 y, vec4 x);\n\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n float atan(float y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec2 atan(vec2 y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec3 atan(vec3 y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec4 atan(vec4 y_over_x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Exponential Functions\n\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n float pow(float x, float y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec2 pow(vec2 x, vec2 y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec3 pow(vec3 x, vec3 y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec4 pow(vec4 x, vec4 y);\n\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n float exp(float x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec2 exp(vec2 x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec3 exp(vec3 x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec4 exp(vec4 x);\n\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n float log(float x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec2 log(vec2 x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec3 log(vec3 x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec4 log(vec4 x);\n\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n float exp2(float x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec2 exp2(vec2 x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec3 exp2(vec3 x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec4 exp2(vec4 x);\n\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n float log2(float x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec2 log2(vec2 x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec3 log2(vec3 x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec4 log2(vec4 x);\n\n // Returns `√x`. Results are undefined if `x < 0`.\n float sqrt(float x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec2 sqrt(vec2 x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec3 sqrt(vec3 x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec4 sqrt(vec4 x);\n\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n float inversesqrt(float x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec2 inversesqrt(vec2 x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec3 inversesqrt(vec3 x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec4 inversesqrt(vec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Common Functions\n\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n float abs(float x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec2 abs(vec2 x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec3 abs(vec3 x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec4 abs(vec4 x);\n\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n float sign(float x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec2 sign(vec2 x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec3 sign(vec3 x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec4 sign(vec4 x);\n\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n float floor(float x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec2 floor(vec2 x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec3 floor(vec3 x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec4 floor(vec4 x);\n\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n float ceil(float x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec2 ceil(vec2 x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec3 ceil(vec3 x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec4 ceil(vec4 x);\n\n // Returns `x - floor(x)`\n float fract(float x);\n // Returns `x - floor(x)`\n vec2 fract(vec2 x);\n // Returns `x - floor(x)`\n vec3 fract(vec3 x);\n // Returns `x - floor(x)`\n vec4 fract(vec4 x);\n\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n float mod(float x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec2 mod(vec2 x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec3 mod(vec3 x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec4 mod(vec4 x, float y);\n\n // Modulus. Returns `x - y * floor(x/y)`\n vec2 mod(vec2 x, vec2 y);\n // Modulus. Returns `x - y * floor(x/y)`\n vec3 mod(vec3 x, vec3 y);\n // Modulus. Returns `x - y * floor(x/y)`\n vec4 mod(vec4 x, vec4 y);\n\n // Returns `y` if `y < x`, otherwise it returns `x`\n float min(float x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec2 min(vec2 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec2 min(vec2 x, vec2 y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec3 min(vec3 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec3 min(vec3 x, vec3 y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec4 min(vec4 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec4 min(vec4 x, vec4 y);\n\n // Returns `y` if `x < y`, otherwise it returns `x`\n float max(float x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec2 max(vec2 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec2 max(vec2 x, vec2 y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec3 max(vec3 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec3 max(vec3 x, vec3 y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec4 max(vec4 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec4 max(vec4 x, vec4 y);\n\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n float clamp(float x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec2 clamp(vec2 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec3 clamp(vec3 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec4 clamp(vec4 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);\n\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n float mix(float x, float y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec2 mix(vec2 x, vec2 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec2 mix(vec2 x, vec2 y, vec2 a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec3 mix(vec3 x, vec3 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec3 mix(vec3 x, vec3 y, vec3 a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec4 mix(vec4 x, vec4 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec4 mix(vec4 x, vec4 y, vec4 a);\n\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n float step(float edge, float x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec2 step(float edge, vec2 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec2 step(vec2 edge, vec2 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec3 step(float edge, vec3 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec3 step(vec3 edge, vec3 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec4 step(float edge, vec4 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec4 step(vec4 edge, vec4 x);\n\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n float smoothstep(float edge0, float edge1, float x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec2 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec2 smoothstep(float edge0, float edge1, vec2 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec2 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec3 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec3 smoothstep(float edge0, float edge1, vec3 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec3 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec4 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec4 smoothstep(float edge0, float edge1, vec4 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec4 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Geometric Functions\n\n // Returns the length of vector `x`, i.e. `√x²`\n float length(float x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]²`\n float length(vec2 x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]² + x[2]²`\n float length(vec3 x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]² + x[2]² + x[3]²`\n float length(vec4 x);\n\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(float p0, float p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec2 p0, vec2 p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec3 p0, vec3 p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec4 p0, vec4 p1);\n\n // Returns the dot product of `x` and `y`, i.e. `x*y`\n float dot(float x, float y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1]`\n float dot(vec2 x, vec2 y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1] + x[2]*y[2]`\n float dot(vec3 x, vec3 y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3]`\n float dot(vec4 x, vec4 y);\n\n // Returns the cross product of `x` and `y`, i.e.\n //\n // ```glslx\n // vec3(\n // x[1]*y[2] - y[1]*x[2],\n // x[2]*y[0] - y[2]*x[0],\n // x[0]*y[1] - y[0]*x[1])\n // ```\n vec3 cross(vec3 x, vec3 y);\n\n // Returns a vector in the same direction as `x` but with a length of 1.\n float normalize(float x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec2 normalize(vec2 x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec3 normalize(vec3 x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec4 normalize(vec4 x);\n\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n float faceforward(float N, float I, float Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec2 faceforward(vec2 N, vec2 I, vec2 Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec3 faceforward(vec3 N, vec3 I, vec3 Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec4 faceforward(vec4 N, vec4 I, vec4 Nref);\n\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n float reflect(float I, float N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec2 reflect(vec2 I, vec2 N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec3 reflect(vec3 I, vec3 N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec4 reflect(vec4 I, vec4 N);\n\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return float(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n float refract(float I, float N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec2(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec2 refract(vec2 I, vec2 N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec3(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec3 refract(vec3 I, vec3 N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec4(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec4 refract(vec4 I, vec4 N, float eta);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Matrix Functions\n\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat2 matrixCompMult(mat2 x, mat2 y);\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat3 matrixCompMult(mat3 x, mat3 y);\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat4 matrixCompMult(mat4 x, mat4 y);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Vector Relational Functions\n\n // Returns the component-wise compare of `x < y`.\n bvec2 lessThan(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x < y`.\n bvec2 lessThan(vec2 x, vec2 y);\n // Returns the component-wise compare of `x < y`.\n bvec3 lessThan(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x < y`.\n bvec3 lessThan(vec3 x, vec3 y);\n // Returns the component-wise compare of `x < y`.\n bvec4 lessThan(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x < y`.\n bvec4 lessThan(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x <= y`.\n bvec2 lessThanEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x <= y`.\n bvec2 lessThanEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x <= y`.\n bvec3 lessThanEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x <= y`.\n bvec3 lessThanEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x <= y`.\n bvec4 lessThanEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x <= y`.\n bvec4 lessThanEqual(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x > y`.\n bvec2 greaterThan(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x > y`.\n bvec2 greaterThan(vec2 x, vec2 y);\n // Returns the component-wise compare of `x > y`.\n bvec3 greaterThan(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x > y`.\n bvec3 greaterThan(vec3 x, vec3 y);\n // Returns the component-wise compare of `x > y`.\n bvec4 greaterThan(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x > y`.\n bvec4 greaterThan(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x >= y`.\n bvec2 greaterThanEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x >= y`.\n bvec2 greaterThanEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x >= y`.\n bvec3 greaterThanEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x >= y`.\n bvec3 greaterThanEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x >= y`.\n bvec4 greaterThanEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x >= y`.\n bvec4 greaterThanEqual(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(bvec2 x, bvec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(vec2 x, vec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(bvec3 x, bvec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(vec3 x, vec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(bvec4 x, bvec4 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(bvec2 x, bvec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(bvec3 x, bvec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(bvec4 x, bvec4 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(vec4 x, vec4 y);\n\n // Returns true if any component of `x` is `true`.\n bool any(bvec2 x);\n // Returns true if any component of `x` is `true`.\n bool any(bvec3 x);\n // Returns true if any component of `x` is `true`.\n bool any(bvec4 x);\n\n // Returns true only if all components of `x` are `true`.\n bool all(bvec2 x);\n // Returns true only if all components of `x` are `true`.\n bool all(bvec3 x);\n // Returns true only if all components of `x` are `true`.\n bool all(bvec4 x);\n\n // Returns the component-wise logical complement of `x`.\n bvec2 not(bvec2 x);\n // Returns the component-wise logical complement of `x`.\n bvec3 not(bvec3 x);\n // Returns the component-wise logical complement of `x`.\n bvec4 not(bvec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Texture Lookup Functions\n\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2D(sampler2D sampler, vec2 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2D(sampler2D sampler, vec2 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProj(sampler2D sampler, vec3 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProj(sampler2D sampler, vec4 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);\n\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCube(samplerCube sampler, vec3 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCube(samplerCube sampler, vec3 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);\n\n #extension GL_OES_standard_derivatives {\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n float dFdx(float v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec2 dFdx(vec2 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec3 dFdx(vec3 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec4 dFdx(vec4 v);\n\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n float dFdy(float v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec2 dFdy(vec2 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec3 dFdy(vec3 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec4 dFdy(vec4 v);\n\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n float fwidth(float v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec2 fwidth(vec2 v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec3 fwidth(vec3 v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec4 fwidth(vec4 v);\n }\n\n #extension GL_EXT_frag_depth {\n // Available only in the fragment language, `gl_FragDepthEXT` is an output variable that is used to establish the depth value for the current fragment.\n // If depth buffering is enabled and no shader writes to `gl_FragDepthEXT`, then the fixed function value for depth will be used (this value is contained\n // in the `z` component of `gl_FragCoord`) otherwise, the value written to `gl_FragDepthEXT` is used.\n //\n // If a shader statically assigns to `gl_FragDepthEXT`, then the value of the fragment's depth may be undefined for executions of the shader that take\n // that path. That is, if the set of linked fragment shaders statically contain a write to `gl_FragDepthEXT`, then it is responsible for always writing it.\n float gl_FragDepthEXT;\n }\n\n #extension GL_EXT_shader_texture_lod {\n vec4 texture2DGradEXT(sampler2D sampler, vec2 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DLodEXT(sampler2D sampler, vec2 coord, float lod);\n vec4 texture2DProjGradEXT(sampler2D sampler, vec3 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DProjGradEXT(sampler2D sampler, vec4 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DProjLodEXT(sampler2D sampler, vec3 coord, float lod);\n vec4 texture2DProjLodEXT(sampler2D sampler, vec4 coord, float lod);\n vec4 textureCubeGradEXT(samplerCube sampler, vec3 P, vec3 dPdx, vec3 dPdy);\n vec4 textureCubeLodEXT(samplerCube sampler, vec3 coord, float lod);\n }\n}\n")); -for(var Q=0,ia=b.length;Q',a,b,10);break;case 42:V(c,'>=',a,b,10);break;case 44:V(c,'<',a,b,10);break;case 45:V(c,'<=',a,b,10);break;case 46:V(c,'&&',a,b,5);break;case 47:V(c,'||',a,b,3);break;case 48:V(c,'^^',a,b,4);break;case 49:V(c,'*',a,b,13);break;case 50:V(c,'!=',a,b,10);break;case 51:V(c,'-',a,b,12); -break;case 52:V(c,'=',a,b,2);break;case 53:V(c,'+=',a,b,2);break;case 54:V(c,'/=',a,b,2);break;case 55:V(c,'*=',a,b,2);break;case 56:V(c,'-=',a,b,2);break;default:c.a+=Sg[a.b];break}}function _b(f,a,b,c){var d=b.g,e=d.b;f.a+=a,(a.charCodeAt(0)==45&&(e==31||e==34||Wf(d))||a.charCodeAt(0)==43&&(e==33||e==35))&&(f.a+=' '),I(f,d,14)}function Nd(d,a,b,c){I(d,b.g,15),d.a+=a}function V(f,a,b,c,d){var e=Bc(b.b);dZ});case 42:return tc(a,function($,ca){return $>=ca});case 44:return tc(a,function(ua,aa){return ua2&&(d=2),Yb(c,d)}function tf(a,b,c){switch(c){case 48:switch(b){case 65:return!0;case 96:return!1}break;case 47:switch(b){case 62:return!0;case 96:return!1}break;case 65:if(b==65)return!0;break;case 62:if(b==62)return!0;break;case 85:if(ud(b)||b==88)return!1;break;case 84:if(ud(b)||b==88)return!1;break;case 81:case 90:case 89:case 88:case 82:return!1;case 87:if(b==83)return!1;break}switch(b){case 85:case 84:case 82:case 49:case 46:return!1;case 65:case 62:switch(a){case 99:case 85:case 84:case 81:case 80:case 90:case 49:case 46:case 32:case 12:return!1}if(Fg(a))return!1;break;case 48:case 47:if(c==96)return!1;break}return!0}function uc(a){return a==10||a==13}function uf(a){for(var b=0,c=a.length;b0&&!uc(b.charCodeAt(g-1|0));)g=g-1|0;for(var i=b.slice(g),o=i,C=0,B=e.slice(1),U=B.length;C',a),h=Jc(e,f,1);if(e.c)return a;var m='',l=99,g=99,i=0,o=0,k=!0,r=0,s=null,w=function(p){return!vc(a.slice(h[p-1|0].a.c,h[p].a.b))},C=function(B,U){switch(B){case 90:case 87: -return!0;case 4:case 9:case 10:case 11:case 12:case 15:case 17:case 32:case 43:return!U}return!1},F=null,Q=function(){for(var ia=1,M=r;M0;s=s-1|0){for(var w=[],Va=0,wa=k,xa=wa.length;Va=s&&w.push(p)}if(w.length){k=w;break}}if(k.length>1){var C=k.slice();Ab(C,function(B){for(var U=l[B].i,F=0,eb=Math.min(U.length,h.length);F-1){c+=' {\n';for(var i=0,o=b.g,k=o.length;id&&c.charCodeAt(e-1|0)==32;)e=e-1|0;b!=''&&(b+='\n'), -b+=c.slice(d,e)}return b}function $d(a,b,c){if(!b)return a+': '+c+'\n';var d=ld(b,0);return kd(b)+': '+a+': '+c+'\n'+d.a+'\n'+d.b+'\n'}function Ff(c){for(var a=new nh,d=0,e=c.a,f=e.length;d1&&a.charCodeAt(0)==48&&a.charCodeAt(1)^120&&a.charCodeAt(1)^88?parseInt(a,8):a|0}function Yf(){var a=new Oh,b=function(c,d,e){return ae(c.a,d.a),v(t(new Jh(27),K),_a(d.a,e.c))},f=function(h,m,l,g){return ae(h.a,l.a),v(t(new Jh(27),K),_a(m.c,g.c))};return P(a,36,function(i,o){return v(t(Ba(new Jh(28),!0),Y),o.a)}),P(a,13,function(k,r){return v(t(Ba(new Jh(28),!1),Y),r.a)}),P(a,97,function(s,w){return v(t(_(new Jh(30),Xf(L(w.a))),ga),w.a)}),P(a,95,function(p,C){return v(t(ma(new Jh(29),+L(C.a)),da),C.a)}),P(a,3,ba(Y)),P(a,5,ba(Lb)),P(a,6,ba(Mb)),P(a,7,ba(Nb)),P(a,14,ba(da)),P(a,20,ba(ga)),P(a,22,ba(vb)),P(a,23,ba(wb)),P(a,24,ba(xb)),P(a,26,ba(ob)),P(a,27,ba(pb)),P(a,28,ba(qb)),P(a,39,ba(Fa)),P(a,40,ba(Ga)),P(a,41,ba(Ha)),P(a,42,ba(yd)),Ib(a,46,14,b),Ib(a,47,14,ec(34)), -Ib(a,48,14,ec(35)),Ib(a,62,14,ec(31)),Ib(a,49,14,ec(32)),Ib(a,65,14,ec(33)),ve(a,47,15,me(36)),ve(a,48,15,me(37)),R(a,53,13,W(39)),R(a,54,10,W(40)),R(a,55,10,W(41)),R(a,56,10,W(42)),R(a,57,10,W(44)),R(a,58,10,W(45)),R(a,62,12,W(51)),R(a,63,13,W(49)),R(a,64,10,W(50)),R(a,65,12,W(38)),R(a,66,13,f),R(a,67,11,f),R(a,68,11,f),R(a,60,3,W(47)),R(a,61,4,W(48)),R(a,59,5,W(46)),R(a,50,8,f),R(a,51,6,f),R(a,52,7,f),ta(a,69,2,W(52)),ta(a,70,2,W(53)),ta(a,71,2,f),ta(a,72,2,f),ta(a,73,2,f),ta(a,74,2,W(54)),ta(a,75,2,W(55)),ta(a,76,2,f),ta(a,77,2,f),ta(a,78,2,f),ta(a,79,2,W(56)),P(a,96,function(B,U){var F=L(U.a),Q=pd(B.l,F);return Q?(Q.m!=null&&ya(B.c.a,Q.m,0)==1&&u(B.a,U.a,'Cannot use "'+F+'" from disabled extension "'+Q.m+'"'),v(Q instanceof Tb?t(new Jh(26),J(Q)):Cc(new Jh(23),Q),U.a)):(Jf(B.a,U.a),v(t(new Jh(24),K),U.a))}),R(a,81,1,function(ia,M,ha,Z){return M.b^25&&(M=v(n(new Jh(25),M),M.c)),n(M,Z),v(M,A(ia,M.c))}),Da(a,82,16).c=function($,ca){var ua=y($).a;E($);var aa=y($).a;return z($,96)?Qa(v(cc(n(new Jh(21),ca),L(aa)), -A($,ca.c)),aa):Qa(v(cc(n(new Jh(21),ca),''),A($,ca.c)),xe(ua))},Da(a,85,0).b=function(ka){var va=E(ka),Ua=T(a,ka,0);return !Ua||!z(ka,89)?v(t(new Jh(24),K),A(ka,va.a)):v(Ua,A(ka,va.a))},Da(a,85,15).c=function(la,rb){var La=E(la),Va=n(new Jh(20),rb);return Zf(la,Va,89)?Qa(v(Va,A(la,rb.c)),A(la,La.a)):v(t(new Jh(24),K),A(la,La.a))},Da(a,84,16).c=function(wa,xa){var eb=E(wa);if(y(wa).b==88)return Gb(wa),E(wa),v(t(new Jh(24),K),A(wa,eb.a));var Ia=T(a,wa,0);return !Ia||!z(wa,88)?v(t(new Jh(24),K),A(wa,eb.a)):Qa(v(n(n(new Jh(43),xa),Ia),A(wa,xa.c)),A(wa,eb.a))},Da(a,86,2).c=function(Ja,fb){var sb=E(Ja),tb=T(a,Ja,1);if(!tb||!z(Ja,80))return v(t(new Jh(24),K),A(Ja,sb.a));var bb=T(a,Ja,1);return bb?v(n(n(n(new Jh(22),fb),tb),bb),A(Ja,fb.c)):v(t(new Jh(24),K),A(Ja,sb.a))},a}function Zf(a,b,c){for(var d=!0;!O(a,c);){d||z(a,81);var e=y(a),f=T(db,a,1);if(f)n(b,f);else if(n(b,v(t(new Jh(24),K),A(a,e.a))),y(a).b^81&&y(a).b^c)return!1;d=!1}return!0}function _f(a){var b=E(a);a.l=new Vh(3,a.l);var c=Za(a,2);if(!c||!z(a,43)||!z(a, -85))return null;var d=T(db,a,0);return !d||!z(a,89)?null:(Hb(a),Eb(a,b.a,n(n(new Jh(7),c),d)))}function $f(a){var b=E(a),c=a.h;if(a.h|=b.b^44?2048:1024,O(a,83)){var d=new Jh(13);return !fc(a,d,1)||!z(a,87)?null:(a.h=c,v(d,A(a,b.a)))}var e=Za(a,1);return e&&(a.h=c,e)}function bg(a){var b=E(a),c=y(a).a;if(!z(a,96))return null;var d=L(c);if(O(a,83)){a.c.a.has(d)||Na(a.c.a,d,0);var e=new Jh(13);if(!fc(a,e,1)||!z(a,87))return null;for(var f=e.g;f;f=f.k)if(f.b^17)f.e&&(f.e.m=d);else for(var h=f.g.k;h;h=h.k)h.e.m=d;return v(e,A(a,b.a))}if(!bh.has(d)&&!a.c.a.has(d)&&Gf(a.a,c,'The extension "'+d+'" is not in the known list of valid WebGL extensions'),!z(a,80))return null;var m=L(y(a).a);if(!ag.has(m))return Gb(a),null;E(a);var l=ag.get(m);return Na(a.c.a,d,l),Qa(v(_(cc(new Jh(9),d),l),A(a,b.a)),c)}function cg(a){var b=E(a);if(a.l=new Vh(3,a.l),!z(a,85))return null;var c=null;if(!O(a,90)){var d=pe(a),e=hd(a,2),f=null;if(e){if(f=Fb(a,1),!f)return null}else f=Fb(a,0);if(f){if(c=oe(a,b.a,e,f,0,d),!c)return null}else if((c=T(db, -a,0),!c)||!z(a,90))return null}var h=null;if(!O(a,90)&&((h=T(db,a,0),!h)||!z(a,90)))return null;var m=null;if(!O(a,89)&&((m=T(db,a,0),!m)||!z(a,89)))return null;var l=Za(a,2);return l&&(Hb(a),v(ke(c,h,m,l),A(a,b.a)))}function dg(a){var b=E(a);if(!z(a,85))return null;var c=y(a),d=T(db,a,0);if(d||(d=v(t(new Jh(24),K),A(a,c.a))),!z(a,89))return null;var e=Za(a,2);if(!e)return null;var f=null;return O(a,12)&&(f=Za(a,2),!f)?null:v(n(n(n(new Jh(12),d),e),f),A(a,b.a))}function eg(a){var b=E(a),c=y(a).a;return z(a,97)?v(_(new Jh(18),L(c)|0),A(a,b.a)):null}function fg(a){var b=E(a);if(a.l=new Vh(3,a.l),!z(a,85))return null;var c=y(a),d=T(db,a,0);if(d||(d=v(t(new Jh(24),K),A(a,c.a))),!z(a,89))return null;var e=Za(a,2);return e&&(Hb(a),v(n(n(new Jh(19),d),e),A(a,b.a)))}function gg(a){var b=E(a),c=null;if(!O(a,90)){var d=y(a);c=T(db,a,0),c||(c=v(t(new Jh(24),K),A(a,d.a))),z(a,90)}return v(n(new Jh(15),c),A(a,b.a))}function hg(a){var b=E(a),c=0;switch(y(a).b){case 25:c=32;break;case 29:c=64;break;case 16:c=4;break;default: -return Gb(a),null}E(a);var d=Fb(a,1);return d&&Eb(a,b.a,n(_(new Jh(14),c),d))}function ig(a,b,c){var d=y(a).a;if(!z(a,96))return null;var e=new Tb(sc(a.c),d,L(d),new Vh(4,a.l));if(e.e|=a.h|b,e.f=c,!id(a,e))return null;var f=y(a).a,h=new Jh(1),m=null;if(!z(a,83))return null;for(a.l=e.d;y(a).b^87&&y(a).b^99;){var l=Za(a,3);if(!l)return null;if(l.b^17)u(a.a,l.c,'This statement cannot be used inside a struct');else{n(h,l);for(var g=l.g.k;g;g=g.k){var i=g.e;e.g.push(i),N(i)&&u(a.a,N(i).c,'Cannot initialize struct variables')}}}if(Hb(a),!z(a,87))return null;if(v(h,A(a,f)),y(a).b^96)z(a,90);else if(m=te(0,t(new Jh(26),J(e)),E(a).a,a,c),!m)return null;return n(n(Cc(new Jh(16),e),h),m)}function ne(a,b,c){for(var d=!1,e=a.l;e;e=e.b)if(e.a==3){d=!0;break}return d||u(a.a,b,'This statement cannot be used outside a loop'),Eb(a,b,c)}function Eb(a,b,c){return z(a,90),v(c,A(a,b))}function oe(a,b,c,d,e,f){var h=y(a).a;if(!c&&y(a).b^96){var m=ue(db,a,0,d);return m&&Eb(a,b,n(new Jh(8),m))}if(!z(a,96))return null;if(O(a,85))return kg(c, -d,h,a,f);var l=te(c,d,h,a,f);return l&&v(l,A(a,b))}function pe(a){var b=y(a),c=b.c;if(!c)return null;for(var d=b.a.b,e=null,f=c.length-1|0;f>-1;f=f-1|0){for(var h=c[f],m=h.a.b.slice(h.c,d),l=0,g=0;g1)break;(e||(e=[])).push(L(h)),d=h.b}return e&&e.reverse(),e}function Za(a,b){var c=y(a);switch(c.b){case 4:return ne(a,E(a).a,new Jh(4));case 9:return ne(a,E(a).a,new Jh(5));case 10:return Eb(a,E(a).a,new Jh(6));case 11:return _f(a);case 44:case 45:return $f(a);case 91:return bg(a);case 15:return cg(a);case 17:return dg(a);case 83:return re(a);case 31:return hg(a);case 32:return gg(a);case 90:return v(new Jh(3),E(a).a);case 92:return eg(a);case 43:return fg(a)}var d=pe(a),e=hd(a,b),f=null;if(O(a,35)){var h=ig(a,e,d);return h&&v(h,A(a,c.a))}if(e){if(f=Fb(a,1),!f)return null}else f=Fb(a,0);if(f)return oe(a,c.a,e,f,1,d);var m=T(db,a,0);return m&&Eb(a,c.a,n(new Jh(8),m))}function qe(a,b){if(b.b^17&&b.b^16){ -var c=a.l.a==1||a.l.a==4,d=b.b==9||b.b==11||b.b==14||b.b==18;d&&!c?u(a.a,b.c,'This statement cannot be used inside a function'):!d&&c&&u(a.a,b.c,'This statement cannot be used outside a function')}}function jg(a,b){var c=y(a).a;if(!z(a,98))return!1;var d=null;try{d=JSON.parse(L(c))}catch(l){return u(a.a,c,'Invalid string literal'),!1}var e=a.c.b;if(!e)return u(a.a,c,'Cannot include files without access to a file system'),!1;var f=e(d,c.a.a);if(!f)return u(a.a,c,'Cannot read the file '+JSON.stringify(d)),!1;if(a.e.has(f.a))return!0;Na(a.e,f.a,!0),a.f.push(new Lh(c,Cg(f)));var h=Jc(a.a,f,0),m=new Mh(a.a,h,a.c,a.d,a.e);return m.l=a.l,!fc(m,b,1)||!z(m,99)?!1:!0}function re(a){var b=y(a),c=new Jh(3);return a.l=new Vh(2,a.l),!z(a,83)||!fc(a,c,2)||!z(a,87)?null:(Hb(a),v(c,A(a,b.a)))}function hd(a,b){for(var c=0;;){var d=y(a).b;switch(d){case 2:c|=1;break;case 8:c|=2;break;case 16:c|=4;break;case 18:c|=8;break;case 19:c|=16;break;case 25:c|=32;break;case 29:c|=64;break;case 30:c|=128;break;case 37:c|=256;break;case 38: -c|=512;break;default:return c}(!b&&(d==2||d==37||d==38)||b==3&&d^25&&d^29&&d^16||b&&(d==18||d==30||d==19))&&u(a.a,y(a).a,'Cannot use this qualifier here'),E(a)}}function Fb(a,b){var c=y(a),d=null;switch(c.b){case 3:d=Y;break;case 5:d=Lb;break;case 6:d=Mb;break;case 7:d=Nb;break;case 14:d=da;break;case 20:d=ga;break;case 22:d=vb;break;case 23:d=wb;break;case 24:d=xb;break;case 26:d=ob;break;case 27:d=pb;break;case 28:d=qb;break;case 33:d=Lg;break;case 34:d=Mg;break;case 39:d=Fa;break;case 40:d=Ga;break;case 41:d=Ha;break;case 42:d=yd;break;case 96:var e=pd(a.l,L(c.a));if(!e||!(e instanceof Tb))return b^1||Gb(a),null;d=J(e);break;default:return b^1||Gb(a),null}return E(a),v(t(new Jh(26),d),A(a,c.a))}function kg(a,b,c,d,e){var f=d.l,h=new oc(sc(d.c),c,L(c),new Vh(0,f));if(h.e|=d.h|a|(h.c=='main'?1024:0),h.f=e,h.o=b,d.l=h.d,O(d,42)){if(!z(d,89))return null}else if(!O(d,89)){for(;;){var m=hd(d,0),l=Fb(d,1);if(!l)return null;var g=y(d).a;if(!z(d,96))return null;var i=new Ge(sc(d.c),g,L(g),d.l,0);if(i.e|=m,i.p=l,h.i.push(i), -id(d,i),!se(d,i))return null;if(!O(d,81))break}if(!z(d,89))return null}var o=ya(f.c,L(c),null),k=!O(d,90);if(o){if(o instanceof oc){for(var r=o;r;r=r.r)if(Eg(r,h)){r.o.f!=h.o.f?Kf(d.a,h.o.c,h.c,h.o.f,r.o.f,r.o.c):r.k||!k?bd(d.a,h.b,r.b):(r.s=h,h.s=r,h.e|=r.e,r.e=h.e);break}h.r=o,Bg(f,h)}else return bd(d.a,c,o.b),null}else Fe(f,h);if(k){var s=d.h;if(d.h&=-3073,h.k=re(d),d.h&=s,!h.k)return null}return Hb(d),v(Cc(new Jh(11),h),A(d,b.c))}function se(a,b){var c=y(a);if(O(a,84)){if(O(a,88))return u(a.a,A(a,c.a),'All array sizes must be specified'),!0;if(b.B=T(db,a,0),!b.B||!z(a,88))return!1;var d=0;if(X(a.d,b.B),pa(a.d,b.B,ga),b.B.f!=K){var e=G(b.B);if(e){if(e.b==30){var f=e.h|0;f<1?u(a.a,b.B.c,'Cannot declare an array with a size of "'+f+'"'):d=f}}else u(a.a,b.B.c,'This value must be a compile-time constant')}for(;y(a).b==84;){if(c=E(a),y(a).b^88&&!T(db,a,0)||!z(a,88))return!1;u(a.a,A(a,c.a),'Multidimensional arrays are not a part of the language')}b.p=v(t(new Jh(26),Ig(b.p.f,d)),b.p.c)}return!0}function te(a,b,c,d,e){ -for(var f=n(_(new Jh(17),d.h|a),b);;){var h=new Ge(sc(d.c),c,L(c),d.l,d.l.a^1?d.l.a^4?2:3:1);if(h.e|=d.h|a,h.f=e,h.p=b,!se(d,h))return null;var m=y(d).a,l=null;if(O(d,69)){var g=y(d);l=T(db,d,1),l||(l=v(t(new Jh(24),K),A(d,g.a)))}else m=null;var i=Qa(v(n(Cc(new Jh(2),h),l),A(d,h.b)),m);if(h.C=i,h.e&2&&X(d.d,i),n(f,i),id(d,h),!O(d,81))return z(d,90),f;if(c=y(d).a,!z(d,96))return null}}function id(a,b){var c=ya(a.l.c,b.c,null);return c?(bd(a.a,b.b,c.b),!1):(Fe(a.l,b),!0)}function fc(a,b,c){for(;y(a).b^99&&y(a).b^87;){var d=y(a).a;if(O(a,93)){if(c^1)return u(a.a,d,'"#include" statements cannot be used here'),O(a,98),!1;if(!jg(a,b))return!1}else{var e=Za(a,c);if(!e)return!1;if(e.b^13)qe(a,e),n(b,e);else for(;e.g;){var f=q(e.g);qe(a,f),n(b,f)}}}return!0}function jd(a,b,c,d,e,f){db||(db=Yf());var h=new Map,m=new Mh(a,b,d,f,h);return m.l=e,fc(m,c,1)&&z(m,99),new Kh(m.f)}function y(a){return a.b[a.m]}function E(b){var a=y(b);return (b.m+1|0)0?c.m-1|0:0];return b.a.c0?e.b[e.m-1|0]:b).a;return a==90||we(d).a^we(c).a?u(e.a,xe(d),'Expected '+Oe[a]):u(e.a,c,'Expected '+Oe[a]+' but found '+Oe[b.b]),!1}function Gb(a){If(a.a,y(a))}function Hb(a){a.l=a.l.b}function Da(e,a,b){var c=ra(e.a,a,null);if(c)b>c.a&&(c.a=b);else{var d=new Nh(b);c=d,za(e.a,a,d)}return c}function T(f,a,b){var c=y(a),d=ra(f.a,c.b,null);if(!d||!d.b)return Gb(a),null;var e=ue(f,a,b,d.b(a));return e}function ue(f,a,b,c){for(;c;){var d=y(a).b,e=ra(f.a,d,null);if(!e||!e.c||e.a<=b)break;c=e.c(a,c)}return c}function P(d,a,b){Da(d,a,0).b=function(c){return b(c,E(c))}}function Ib(h,a,b,c){Da(h,a,0).b=function(d){var e=E(d),f=T(h,d,b);return f&&c(d,e,f)}}function ve(f,a,b,c){Da(f,a,b).c=function(d,e){return c(d,e,E(d))}}function R(m,a,b,c){Da(m,a,b).c=function(d,e){var f=E(d),h=T(m,d,b);return h&&c(d,e,f,h)}}function ta(m,a,b,c){Da(m,a,b).c=function(d,e){var f=E(d),h=T(m,d,b-1|0);return h&&c(d,e,f,h)}}function L(a){ -return a.a.b.slice(a.b,a.c)}function kd(b){var a=Jb(b.a,b.b);return b.a.a+':'+(a.a+1|0)+':'+(a.b+1|0)}function lg(b,a){return b.a==a.a&&b.b0&&k>a){var r=Math.min(g-l|0,a/2|0),s=Math.max((a-r|0)/2|0,3);if(l(a-3|0)&&(g=a-3|0);else if((k-l|0)<(a-s|0)){var w=k-a|0;d='...'+rc(m.slice(w+3|0,k)),l=l-w|0,g=g-w|0}else{var p=l-s|0;d='...'+rc(m.slice(p+3|0,(p+a|0)-3|0))+'...',l=l-p|0,g=g-p|0,g>(a-3|0)&&(g=a-3|0)}}else d=rc(m);return new Ph(d,Yb(' ',l)+((g-l|0)<2?'^':Yb('~',g-l|0)))}function mg(c,a,b){return new Qh(c.a,c.b+a|0,c.b+b|0)}function we(a){return Jb(a.a,a.b)}function xe(a){return new Qh(a.a,a.c,a.c)}function _a(a,b){return new Qh(a.a,a.b,b.c)}function ng(a){ -var b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'[a%53];for(a=a/53|0;a>0;)a=a-1|0,b+='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789'[a%63],a=a/63|0;return b}function og(o,a){for(var b=0,k=a.length;b=g)&&u(i.a,c.c,'Index "'+l+'" is out of bounds for type "'+D(d)+'"')}}break}a.f==K&&d!=K&&e!=K&&(a.b^43?Qf(i.a,a.d,L(a.d),d,e):u(i.a,a.d,'No index operator for type "'+D(d)+'" and type "'+D(e)+'"'))}function ug(m,a){var b=a.g;X(m,b);for(var c=b.f,d=c.a,e=[],f=!1,h=b.k;h;h=h.k)ja(m, -h),e.push(h),h.f==K&&(f=!0);if(!f){if(d){if(d instanceof oc){wg(m,d,a,e);return}if(d instanceof Tb){xg(m,c,a,e);return}}c!=K&&u(m.a,b.c,'Cannot call type "'+D(c)+'"')}}function vg(m,a){var b=a.g,c=a.m,d=a.d;if(ja(m,b),c!=''){var e=b.f,f=he(a);switch(e){case Lb:case vb:case Fa:case Mb:case wb:case Ga:case Nb:case xb:case Ha:a.f=yg(m,d,e,c,f);break;case K:break;default:if(e.a&&e.a instanceof Tb)for(var l=0,g=e.a.g,i=g.length;l=d&&Lf(w.a,h.c,a,d,f+l|0),ab(m)&&(e=!0),f=f+l|0}var g=ab(a)&&e;g&&c.length^1?u(w.a,b.d,'If a matrix argument is given to a matrix constructor, it is an error to have any other arguments'):f4)return u(l.a,a,'Invalid swizzle "'+c+'" on type "'+D(b)+'"'),K;for(var f=Ea(b),g=0,i=rd(f),o=i.length;g(jc.h|0)):ub.b==29&&jc.b==29&&S(x,a,ub.h>jc.h);break;case 42:var Ka=a.g,Wa=a.i;Ka.b^30?Wa.b^30?Ka.b==30&&Wa.b==30?S(x,a,(Ka.h|0)>=(Wa.h|0)):Ka.b==29&&Wa.b==29&&S(x,a,Ka.h>=Wa.h):(a.b=41,_(Wa,(Wa.h|0)-1|0),x.a=!0):(a.b=41,_(Ka,(Ka.h|0)+1|0),x.a=!0);break;case 43:var pc=a.g,kc=a.i,Oc=pc.f;if(kc.b==30){var Ob=kc.h|0,Pb=0;switch(Oc){case Lb:case vb:case Fa:Pb=2;break;case Mb:case wb:case Ga:Pb=3;break;case Nb:case xb:case Ha: -Pb=4;break}Ob>-1&&Ob=d.d.length)return'';var b=d.d[a],c=(a+1|0)0;){var d=b/2|0,e=c+d|0;h.d[e]<=a?(c=e+1|0,b=(b-d|0)-1|0):b=d}var f=c>0?a-h.d[c-1|0]|0:a;return new Wh(c-1|0,f)}function Kb(d,a,b){if(qd(d),a>-1&&a-1&&(c+b|0)<((a+1|0)64&&r<91||r>96&&r<123||r==95){var s=ya(Gg,g,99);s^99?e.push(new Zh(k, -s,f)):Hg.has(g)?Hf(a,k):e.push(new Zh(k,96,f))}else if(r>47&&r<58||r==46&&i>1)e.push(new Zh(k,gh.test(g)?97:95,f));else if(r^35){if(r^34){var p=ya(hh,g,99);p^99||(g.startsWith('//')?c^1?(f||(f=[])).push(k):p=0:g.startsWith('/*')&&(c^1?(f||(f=[])).push(k):p=1)),p^99&&e.push(new Zh(k,p,f))}else e.push(new Zh(k,98,f))}else{var w=94;switch(g){case'#version':w=92;break;case'#extension':w=91;break;case'#include':w=93;break}e.push(new Zh(k,w,f))}}else if(g!=''){u(a,k,'Syntax error "'+g+'"');break}e.length^h&&(f=null,h=e.length),m=o}return e.push(new Zh(new Qh(b,m,m),99,f)),e}function He(a){return a.b?He(a.b):a}function Ig(c,a){c.f||(c.f=new Map);var b=ra(c.f,a,null);return b||(za(c.f,a,b=new _h(null,c,a)),b.d=!0,b.e=c.e),b}function D(a){return a.b?a.c?D(a.b)+'['+a.c+']':D(a.b)+'[]':a.a.c}function Sa(a){switch(a){case Lb:case Fa:case vb:case ob:return 2;case Mb:case Ga:case wb:case pb:return 3;case Nb:case Ha:case xb:case qb:return 4}return a.c}function vd(a){switch(a){case Lb:case Mb:case Nb:return Y;case Fa:case Ga:case Ha: -return da;case vb:case wb:case xb:return ga;case ob:return Fa;case pb:return Ga;case qb:return Ha}return a.b}function Ea(a){switch(a){case Y:case da:case ga:return 1;case Lb:case Fa:case vb:return 2;case Mb:case Ga:case wb:return 3;case Nb:case Ha:case xb:case ob:return 4;case pb:return 9;case qb:return 16}return 0}function fa(a){switch(a){case Y:case Lb:case Mb:case Nb:return Y;case da:case Fa:case Ga:case Ha:case ob:case pb:case qb:return da;case ga:case vb:case wb:case xb:return ga}return null}function wd(a){switch(a){case Lb:case Mb:case Nb:case vb:case wb:case xb:case Fa:case Ga:case Ha:return!0}return!1}function ab(a){switch(a){case ob:case pb:case qb:return!0}return!1}function Kc(a){switch(a){case ga:case vb:case wb:case xb:return!0}return!1}function Lc(a){switch(a){case da:case Fa:case Ga:case Ha:return!0;case ob:case pb:case qb:return!0}return!1}function Jg(a){return Kc(a)||Lc(a)}function Kg(a){return !a.e&&!a.d}function Ie(a){return a.e=!0,a}function Je(b){var a=b.a.length;return b.a.push(a),a}function xd(c,a,b){ -c.a[Mc(c,a)]=Mc(c,b)}function Mc(c,a){var b=c.a[a];return b^a&&(b=Mc(c,b),c.a[a]=b),b}function qa(a,b){Ke(a),process.stdout.write(b),Ke(0)}function Og(a){qa(3,'error: '),qa(1,a+'\n')}function Pg(a){qa(2,'note: '),qa(1,a+'\n')}function Qg(a){qa(7,'warning: '),qa(1,a+'\n')}function Le(a){for(var b=process.stdout.columns,l=0,g=a.a,i=g.length;l',a)];if(a instanceof Array){for(var b=[],c=0,e=a.length;c27&&a<31}function dd(a){return a>30&&a<38}function Rf(a){return a>30&&a<36}function ed(a){return a>33&&a<38}function Ac(a){return a>37&&a<57}function Bc(a){return a>51&&a<57}function Sf(a){return a==4||a==5||a==6||a==15}function ce(a){return a==7||a==10||a==19}function $a(b){var a='';return b&1&&(a+='attribute '),b&2&&(a+='const '),b&256&&(a+='uniform '),b&512&&(a+='varying '),b&4&&(a+='highp '),b&32&&(a+='lowp '),b&64&&(a+='mediump '),b&8&&(a+='in '),b&16&&(a+='inout '),b&128&&(a+='out '),a}function Fg(a){return a>49&&a<80}function ud(a){switch(a){case 96:case 42:case 33:case 34:case 14:case 39:case 40:case 41:case 20:case 22:case 23:case 24:case 3:case 5:case 6:case 7:case 26:case 27:case 28:return!0}return!1}function Ke(a){process.stdout.isTTY&&process.stdout.write('\x1B[0;'+ih.get(a)+'m')} -function hb(b,a){return b[b.length-1|0]=a}function Rc(a){return a[a.length-1|0]}function Ze(c,a){for(var d=0,e=a.length;db|0)|0}function rc(a){for(var b=new nh,d=0,e=a.length;db|0)|0}function Yb(d,a){for(var b='',c=0;c>10)+55296|0)+String.fromCharCode((a-65536&1023)+56320|0)}function Nc(a){if(!a)return null;var b=a.a,c=Jb(b,a.b),d=Jb(b,a.c);return{source:b.a,start:{line:c.a,column:c.b}, -end:{line:d.a,column:d.b}}}function jh(a,b){b=b||{};var c=Me(a),d=new Ih,e=new th;e.c=ya(Re,b.renaming,0),b.disableRewriting&&(e.a=!1),b.prettyPrint&&(e.b=!1),b.keepSymbols&&(e.d=!1),b.fileAccess&&(e.e=Ne(b.fileAccess));var f=Gd(d,c,e);return{log:Ff(d),output:f?Sc(f,ya(Qe,b.format,0)):null}}function kh(a,b){b=b||{};var c=Me(a),d=new Ih,e=new th;b.fileAccess&&(e.e=Ne(b.fileAccess));var f=_e(d,c,e),h=function(m){for(var Xb,l=m.source+'',g=m.line|0,i=m.column|0,o=!!m.ignoreDiagnostics,k=null,r=null,s=null,zd=0,Ug=c.length;zd>=?|[()[\\]{}\\.,?:;]|[+\\-*/%=!<>&|^~]=?|[A-Za-z_][A-Za-z0-9_]*\\b|#\\w+\\b|"(?:[^"\\\\]|\\\\.)*")'),gh=new RegExp('^([1-9][0-9]*|0[0-7]*|0[xX][0-9A-Fa-f]+)$'),Gg=j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(new Map, -'attribute',2),'bool',3),'break',4),'bvec2',5),'bvec3',6),'bvec4',7),'const',8),'continue',9),'discard',10),'do',11),'else',12),'false',13),'float',14),'for',15),'highp',16),'if',17),'in',18),'inout',19),'int',20),'invariant',21),'ivec2',22),'ivec3',23),'ivec4',24),'lowp',25),'mat2',26),'mat3',27),'mat4',28),'mediump',29),'out',30),'precision',31),'return',32),'sampler2D',33),'samplerCube',34),'struct',35),'true',36),'uniform',37),'varying',38),'vec2',39),'vec3',40),'vec4',41),'void',42),'while',43),'export',44),'import',45),hh=j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(new Map,'~',46),'--',47),'++',48),'!',49),'&',50),'|',51),'^',52),'/',53),'==',54),'>',55),'>=',56),'<',57),'<=',58),'&&',59),'||',60),'^^',61),'-',62),'*',63),'!=',64),'+',65),'%',66),'<<',67),'>>',68),'=',69),'+=',70),'&=',71),'|=',72),'^=',73),'/=',74),'*=',75),'%=',76),'<<=',77),'>>=',78),'-=',79),':',80),',',81),'.',82),'{',83),'[',84),'(',85),'?',86),'}',87),']',88),')',89),';',90),Hg=j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(new Map, -'asm',0),'cast',0),'class',0),'default',0),'double',0),'dvec2',0),'dvec3',0),'dvec4',0),'enum',0),'extern',0),'external',0),'fixed',0),'flat',0),'fvec2',0),'fvec3',0),'fvec4',0),'goto',0),'half',0),'hvec2',0),'hvec3',0),'hvec4',0),'inline',0),'input',0),'interface',0),'long',0),'namespace',0),'noinline',0),'output',0),'packed',0),'public',0),'sampler1D',0),'sampler1DShadow',0),'sampler2DRect',0),'sampler2DRectShadow',0),'sampler2DShadow',0),'sampler3D',0),'sampler3DRect',0),'short',0),'sizeof',0),'static',0),'superp',0),'switch',0),'template',0),'this',0),'typedef',0),'union',0),'unsigned',0),'using',0),'volatile',0),Y=J(new Tb(-1,null,'bool',null)),Lb=J(new Tb(-2,null,'bvec2',null)),Mb=J(new Tb(-3,null,'bvec3',null)),Nb=J(new Tb(-4,null,'bvec4',null)),K=J(new Tb(-5,null,'',null)),da=J(new Tb(-6,null,'float',null)),ga=J(new Tb(-7,null,'int',null)),vb=J(new Tb(-8,null,'ivec2',null)),wb=J(new Tb(-9,null,'ivec3',null)),xb=J(new Tb(-10,null,'ivec4',null)),ob=J(new Tb(-11,null,'mat2',null)),pb=J(new Tb(-12,null, -'mat3',null)),qb=J(new Tb(-13,null,'mat4',null)),Lg=Ie(J(new Tb(-14,null,'sampler2D',null))),Mg=Ie(J(new Tb(-15,null,'samplerCube',null))),Fa=J(new Tb(-16,null,'vec2',null)),Ga=J(new Tb(-17,null,'vec3',null)),Ha=J(new Tb(-18,null,'vec4',null)),yd=J(new Tb(-19,null,'void',null)),Ng=[Y,Lb,Mb,Nb,da,ga,vb,wb,xb,ob,pb,qb,Lg,Mg,Fa,Ga,Ha],Qe=j(j(j(j(j(new Map,'json',0),'js',1),'c++',2),'skew',3),'rust',4),Re=j(j(j(new Map,'all',0),'internal-only',1),'none',2),mh=['ERROR','WARNING'],Sg=['GLOBAL','STRUCT_BLOCK','VARIABLE','BLOCK','BREAK','CONTINUE','DISCARD','DO_WHILE','EXPRESSION','EXTENSION','FOR','FUNCTION','IF','MODIFIER_BLOCK','PRECISION','RETURN','STRUCT','VARIABLES','VERSION','WHILE','CALL','DOT','HOOK','NAME','PARSE_ERROR','SEQUENCE','TYPE','UNKNOWN_CONSTANT','BOOL','FLOAT','INT','NEGATIVE','NOT','POSITIVE','PREFIX_DECREMENT','PREFIX_INCREMENT','POSTFIX_DECREMENT','POSTFIX_INCREMENT','ADD','DIVIDE','EQUAL','GREATER_THAN','GREATER_THAN_OR_EQUAL','INDEX','LESS_THAN','LESS_THAN_OR_EQUAL','LOGICAL_AND','LOGICAL_OR', -'LOGICAL_XOR','MULTIPLY','NOT_EQUAL','SUBTRACT','ASSIGN','ASSIGN_ADD','ASSIGN_DIVIDE','ASSIGN_MULTIPLY','ASSIGN_SUBTRACT'],Oe=['SINGLE_LINE_COMMENT','MULTI_LINE_COMMENT','ATTRIBUTE','BOOL','BREAK','BVEC2','BVEC3','BVEC4','CONST','CONTINUE','DISCARD','DO','ELSE','FALSE','FLOAT','FOR','HIGHP','IF','IN','INOUT','INT','INVARIANT','IVEC2','IVEC3','IVEC4','LOWP','MAT2','MAT3','MAT4','MEDIUMP','OUT','PRECISION','RETURN','SAMPLER2D','SAMPLERCUBE','STRUCT','TRUE','UNIFORM','VARYING','VEC2','VEC3','VEC4','VOID','WHILE','EXPORT','IMPORT','COMPLEMENT','DECREMENT','INCREMENT','NOT','BITWISE_AND','BITWISE_OR','BITWISE_XOR','DIVIDE','EQUAL','GREATER_THAN','GREATER_THAN_OR_EQUAL','LESS_THAN','LESS_THAN_OR_EQUAL','LOGICAL_AND','LOGICAL_OR','LOGICAL_XOR','MINUS','MULTIPLY','NOT_EQUAL','PLUS','REMAINDER','SHIFT_LEFT','SHIFT_RIGHT','ASSIGN','ASSIGN_ADD','ASSIGN_BITWISE_AND','ASSIGN_BITWISE_OR','ASSIGN_BITWISE_XOR','ASSIGN_DIVIDE','ASSIGN_MULTIPLY','ASSIGN_REMAINDER','ASSIGN_SHIFT_LEFT','ASSIGN_SHIFT_RIGHT','ASSIGN_SUBTRACT','COLON', -'COMMA','DOT','LEFT_BRACE','LEFT_BRACKET','LEFT_PARENTHESIS','QUESTION','RIGHT_BRACE','RIGHT_BRACKET','RIGHT_PARENTHESIS','SEMICOLON','EXTENSION','VERSION','INCLUDE','PRAGMA','FLOAT_LITERAL','IDENTIFIER','INT_LITERAL','STRING_LITERAL','END_OF_FILE'],ih=Oa(Oa(Oa(Oa(Oa(Oa(Oa(Oa(Oa(new Map,0,0),1,1),2,90),3,31),4,32),5,33),6,34),7,35),8,36);ai()})(); \ No newline at end of file diff --git a/ShaderPlayground/build/debug/main.js b/ShaderPlayground/build/debug/main.js index 2c5d9a8..859131c 100644 --- a/ShaderPlayground/build/debug/main.js +++ b/ShaderPlayground/build/debug/main.js @@ -1 +1 @@ -var OS;!function(e){let t,i;!function(e){let t;!function(e){class t extends e.ListViewItemTag{itemlayout(){return{el:"div",children:[{el:"img",ref:"img"},{el:"p",ref:"name"}]}}ondatachange(){const e=this.data,t=this.refs.img,i=e.path.asFileHandle().getlink();t.src=i,$(this.refs.name).text(e.name)}init(){this.closable=!0}reload(e){}}e.define("afx-shader-texture-item",t)}(t=e.tag||(e.tag={}))}(t=e.GUI||(e.GUI={})),function(e){class i extends t.BasicDialog{constructor(){super("AddTextureDialog",i.scheme)}main(){super.main();const e=$("input",this.scheme);this.find("btnOk").onbtclick=t=>{let i={};for(const t of e){let e=t;if(""==e.value.trim())return this.notify(__("All fields should be filled"));i[e.name]=e.value.trim()}this.handle&&this.handle(i),this.quit()},this.find("btnFile").onbtclick=e=>{this.openDialog("FileDialog",{title:__("Select image file"),type:"file",mimes:["image/.*"]}).then(e=>{this.find("txtPath").value=e.file.path})}}}i.scheme='\n \n
\n \n
\n \n \n
\n \n \n \n \n \n
\n
\n \n
\n
\n
\n
\n
\n
';class s{constructor(e,t){this.renderer=t,this.ums=[new ace.UndoManager,new ace.UndoManager],this.current_idx=-1,this.glsl_values=["void main(){}",""],ace.require("ace/ext/language_tools"),this.editor=ace.edit(e),this.editor.setOptions({enableBasicAutocompletion:!0,enableLiveAutocompletion:!0,enableSnippets:!0,highlightActiveLine:!0}),this.editor.getSession().setUseWrapMode(!0),this.editor.session.setMode("ace/mode/glsl"),this.editor.setTheme("ace/theme/monokai"),this.cursors=[this.editor.getCursorPosition(),this.editor.getCursorPosition()],this.editor.on("input",e=>{const t=this.editor.getValue(),i=GLSLX.compile(t,{format:"json"});if(i.output)this.editor.getSession().setAnnotations([]),this.glsl_values[this.current_idx]=t,this.renderer.apply_mat(this.glsl_values[0],this.glsl_values[1]);else{const e=":([0-9]+):([0-9]+):\\s*error:\\s*(.*)\\n",t=i.log.match(new RegExp(e,"g"));t&&this.editor.getSession().setAnnotations(t.map(t=>{const i=t.match(new RegExp(e));let s={};return i&&(s={row:parseInt(i[1])-1,column:parseInt(i[2]),text:i[3],type:"error"}),s}))}})}edit(e){if(e<0)return;if(2!=e&&2!=this.current_idx)0===e?(this.glsl_values[1]=this.editor.getValue(),this.cursors[1]=this.editor.getCursorPosition()):(this.glsl_values[0]=this.editor.getValue(),this.cursors[0]=this.editor.getCursorPosition());else if(2==e)return this.glsl_values[this.current_idx]=this.editor.getValue(),this.cursors[this.current_idx]=this.editor.getCursorPosition(),void(this.current_idx=e);this.current_idx=e,this.editor.getSession().setUndoManager(new ace.UndoManager),this.editor.setValue(this.glsl_values[e]),this.editor.getSession().setUndoManager(this.ums[e]);const t=this.cursors[e];this.editor.renderer.scrollCursorIntoView({row:t.row,column:t.column},.5),this.editor.selection.moveTo(t.row,t.column),this.editor.focus()}cleanup(){this.renderer.cleanup()}resize(){this.editor.resize(),this.renderer.viewport_resize()}}class r{constructor(e){this.textures=[],this.renderer=new THREE.WebGLRenderer({canvas:e}),this.renderer.autoClearColor=!1,this.clock=new THREE.Clock,this.camera=new THREE.OrthographicCamera(-1,1,1,-1,-1,1),this.scene=new THREE.Scene;const t=new THREE.PlaneGeometry(2,2),i=new THREE.MeshBasicMaterial({color:"white"});this.needupdateTexture=!1,this.mesh=new THREE.Mesh(t,i),this.scene.add(this.mesh),this.uniforms={u_resolution:{value:{x:0,y:0}},u_time:{value:0},u_mouse:{value:{x:0,y:0}}},this.viewport_resize(),this.ani_request_id=requestAnimationFrame(()=>this.viewport_render())}viewport_render(){this.needupdateTexture&&(this.update_textures(),this.needupdateTexture=!1),this.uniforms.u_time.value=this.clock.getElapsedTime();try{this.renderer.render(this.scene,this.camera)}catch(e){console.error(e);const t=new THREE.MeshBasicMaterial({color:"white"});this.mesh.material=t}this.ani_request_id=requestAnimationFrame(()=>this.viewport_render())}viewport_resize(){const e=this.renderer.domElement,t=e.clientWidth,i=e.clientHeight;this.uniforms.u_resolution.value.x=t,this.uniforms.u_resolution.value.y=i,(e.width!==t||e.height!==i)&&this.renderer.setSize(t,i,!1)}cleanup(){console.log("Stop the animation before quitting..."),window.cancelAnimationFrame(this.ani_request_id)}update_textures(){for(const e in this.uniforms)-1===["u_resolution","u_time","u_mouse"].indexOf(e)&&delete this.uniforms[e];for(const e of this.textures)this.uniforms[e.name]={value:e.texture}}apply_mat(e,t){const i={fragmentShader:""===e.trim()?"void main(){}":e,uniforms:this.uniforms,vertexShader:void 0};""!=t.trim()&&(i.vertexShader=t);const s=new THREE.ShaderMaterial(i);this.mesh.material=s}}class n extends e.BaseApplication{constructor(e){super("ShaderPlayground",e)}main(){this.init_editor(),this.init_textures_list()}init_editor(){this.tabbar=this.find("tabbar"),this.tabbar.items=[{text:__("Fragment"),iconclass:"bi bi-palette"},{text:__("Vertex"),iconclass:"bi bi-intersect"},{text:__("Textures"),iconclass:"bi bi-image-alt"}],this.tabbar.ontabselect=e=>{this.selectTab()},this.editor=new s(this.find("editor-container"),new r(this.find("viewport"))),this.on("resize",e=>{this.editor.resize()}),this.tabbar.selected=0}init_textures_list(){const e=this.find("texture-list");e.buttons=[{text:"__(Add texture)",iconclass:"bi bi-plus",onbtclick:t=>{this.openDialog(new i).then(t=>{if(!t)return;const i=(new THREE.TextureLoader).load(t.path.asFileHandle().getlink());i.minFilter=THREE.NearestFilter,i.magFilter=THREE.NearestFilter,i.wrapS=THREE.RepeatWrapping,i.wrapT=THREE.RepeatWrapping,t.texture=i,e.push(t),this.editor.renderer.needupdateTexture=!0})}}],e.itemtag="afx-shader-texture-item",e.onitemclose=e=>(this.editor.renderer.needupdateTexture=!0,!0),e.data=this.editor.renderer.textures}selectTab(){const e=this.tabbar.selected;2===e?($(this.find("editor-container")).hide(),$(this.find("texture-list")).show()):($(this.find("editor-container")).show(),$(this.find("texture-list")).hide()),this.editor.edit(e)}cleanup(e){this.editor.cleanup()}}e.ShaderPlayground=n,n.dependencies=["pkg://libthreejs/main.js","pkg://ACECore/core/ace.js","pkg://ACECore/path.js","pkg://ACECore/core/ext-language_tools.js","pkg://ShaderPlayground/glslx.js"]}(i=e.application||(e.application={}))}(OS||(OS={})); \ No newline at end of file +var OS;!function(e){let t,i;!function(e){let t;!function(e){class t extends e.ListViewItemTag{itemlayout(){return{el:"div",children:[{el:"img",ref:"img"},{el:"p",ref:"name"}]}}ondatachange(){const e=this.data,t=this.refs.img,i=e.path.asFileHandle().getlink();t.src=i,$(this.refs.name).text(e.name)}init(){this.closable=!0}reload(e){}}e.define("afx-shader-texture-item",t)}(t=e.tag||(e.tag={}))}(t=e.GUI||(e.GUI={})),function(e){class i extends t.BasicDialog{constructor(){super("AddTextureDialog",i.scheme)}main(){super.main();const e=$("input",this.scheme);this.find("btnOk").onbtclick=t=>{let i={};for(const t of e){let e=t;if(""==e.value.trim())return this.notify(__("All fields should be filled"));i[e.name]=e.value.trim()}this.handle&&this.handle(i),this.quit()},this.find("btnFile").onbtclick=e=>{this.openDialog("FileDialog",{title:__("Select image file"),type:"file",mimes:["image/.*"]}).then(e=>{this.find("txtPath").value=e.file.path})}}}i.scheme='\n \n
\n \n
\n \n \n
\n \n \n \n \n \n
\n
\n \n
\n
\n
\n
\n
\n
';class s{constructor(e,t){this.glsl_values=[s.frg_template,""],this.renderer=t,this.ums=[new ace.UndoManager,new ace.UndoManager],this.current_idx=-1,this.tmp_canvas=$("")[0],this.gl_compiling_ctx=this.tmp_canvas.getContext("webgl"),this._filehandle=void 0,this.editormux=!1,ace.require("ace/ext/language_tools"),this._onfilechange=e=>{},this._ontextureadded=e=>{},this.editor=ace.edit(e),this.editor.setOptions({enableBasicAutocompletion:!0,enableLiveAutocompletion:!0,enableSnippets:!0,highlightActiveLine:!0}),this.editor.getSession().setUseWrapMode(!0),this.editor.session.setMode("ace/mode/glsl"),this.editor.setTheme("ace/theme/monokai"),this.cursors=[this.editor.getCursorPosition(),this.editor.getCursorPosition()],this.editor.on("input",e=>{const t=this.editor.getValue(),i=0==this.current_idx?this.gl_compiling_ctx.FRAGMENT_SHADER:this.gl_compiling_ctx.VERTEX_SHADER,s=this.compile(t,i);if(!1!==this.filehandle.dirty||this.editormux||(this.filehandle.dirty=!0,this._onfilechange(this.filehandle.path+"*")),this.editormux&&(this.editormux=!1),s){const e="ERROR:\\s*([0-9]+):([0-9]+):\\s*(.*)\\n",t=s.match(new RegExp(e,"g"));t&&this.editor.getSession().setAnnotations(t.map(t=>{const i=t.match(new RegExp(e));let s={};return i&&(s={row:parseInt(i[2])-1,column:0,text:i[3],type:"error"}),s}))}else this.editor.getSession().setAnnotations([]),this.glsl_values[this.current_idx]=t,this.renderer.apply_mat(this.glsl_values[0],this.glsl_values[1])})}set onfilechange(e){this._onfilechange=e}set ontextureadded(e){this._ontextureadded=e}set filehandle(e){this._filehandle=e,this.read()}get filehandle(){return this._filehandle}read(){return new Promise(async(e,t)=>{if(void 0===this._filehandle)return this.renderer.textures.length=0,this._filehandle="Untitled".asFileHandle(),this._onfilechange(this._filehandle.path),this.glsl_values=[s.frg_template,""],2!=this.current_idx&&-1!=this.current_idx&&(this.editormux=!0,this.editor.setValue(this.glsl_values[this.current_idx])),this._ontextureadded(void 0),e(void 0);try{const t=await this._filehandle.read("json");this.glsl_values[0]=t.source[0],this.glsl_values[1]=t.source[1],2!=this.current_idx&&-1!=this.current_idx&&(this.editormux=!0,this.editor.setValue(this.glsl_values[this.current_idx])),this._ontextureadded(void 0);for(const e of t.textures)this._ontextureadded(e);this._onfilechange(this._filehandle.path),e(void 0)}catch(e){t(e)}})}write(e){return new Promise(async(t,i)=>{let s=e;const n=__("Unknown save path");if(!s){if(void 0===this._filehandle)return i(n);s=this._filehandle.path}if("Untitled"===s)return i(n);try{this._filehandle.setPath(s);const e={};2!=this.current_idx&&(this.glsl_values[this.current_idx]=this.editor.getValue()),e.source=this.glsl_values,e.textures=this.renderer.textures.map(e=>({name:e.name,path:e.path})),this.filehandle.cache=e,await this.filehandle.write("object"),this._filehandle.dirty=!1,this._onfilechange(""+this.filehandle.path),t(void 0)}catch(e){i(e)}})}compile(e,t){let i=this.gl_compiling_ctx.createShader(t);this.gl_compiling_ctx.shaderSource(i,e),this.gl_compiling_ctx.compileShader(i);let s=void 0;return this.gl_compiling_ctx.getShaderParameter(i,this.gl_compiling_ctx.COMPILE_STATUS)||(s=this.gl_compiling_ctx.getShaderInfoLog(i)),this.gl_compiling_ctx.deleteShader(i),s}edit(e){if(e<0)return;if(2!=e&&2!=this.current_idx)0===e?(this.glsl_values[1]=this.editor.getValue(),this.cursors[1]=this.editor.getCursorPosition()):1===e&&(this.glsl_values[0]=this.editor.getValue(),this.cursors[0]=this.editor.getCursorPosition());else if(2==e)return this.glsl_values[this.current_idx]=this.editor.getValue(),this.cursors[this.current_idx]=this.editor.getCursorPosition(),void(this.current_idx=e);this.current_idx=e,this.editormux=!0,this.editor.getSession().setUndoManager(new ace.UndoManager),this.editor.setValue(this.glsl_values[e]),this.editor.getSession().setUndoManager(this.ums[e]);const t=this.cursors[e];this.editor.renderer.scrollCursorIntoView({row:t.row,column:t.column},.5),this.editor.selection.moveTo(t.row,t.column),this.editor.focus()}cleanup(){this.renderer.cleanup(),$(this.tmp_canvas).remove()}resize(){this.editor.resize(),this.renderer.viewport_resize()}}class n{constructor(e){this.textures=[],this.renderer=new THREE.WebGLRenderer({canvas:e}),this.renderer.autoClearColor=!1,this.clock=new THREE.Clock,this.camera=new THREE.OrthographicCamera(-1,1,1,-1,-1,1),this.scene=new THREE.Scene;const t=new THREE.PlaneGeometry(2,2),i=new THREE.MeshBasicMaterial({color:"white"});this.needupdateTexture=!1,this.mesh=new THREE.Mesh(t,i),this.scene.add(this.mesh),this.uniforms={u_resolution:{value:{x:0,y:0}},u_time:{value:0},u_mouse:{value:{x:0,y:0}}},this.viewport_resize(),this.ani_request_id=requestAnimationFrame(()=>this.viewport_render())}viewport_render(){this.needupdateTexture&&(this.update_textures(),this.needupdateTexture=!1),this.uniforms.u_time.value=this.clock.getElapsedTime();try{this.renderer.render(this.scene,this.camera)}catch(e){console.error(e);const t=new THREE.MeshBasicMaterial({color:"white"});this.mesh.material=t}this.ani_request_id=requestAnimationFrame(()=>this.viewport_render())}viewport_resize(){const e=this.renderer.domElement,t=e.clientWidth,i=e.clientHeight;this.uniforms.u_resolution.value.x=t,this.uniforms.u_resolution.value.y=i,(e.width!==t||e.height!==i)&&this.renderer.setSize(t,i,!1)}cleanup(){console.log("Stop the animation before quitting..."),window.cancelAnimationFrame(this.ani_request_id)}update_textures(){for(const e in this.uniforms)-1===["u_resolution","u_time","u_mouse"].indexOf(e)&&delete this.uniforms[e];for(const e of this.textures)this.uniforms[e.name]={value:e.texture}}apply_mat(e,t){const i={fragmentShader:""===e.trim()?"void main(){}":e,uniforms:this.uniforms,vertexShader:void 0};""!=t.trim()&&(i.vertexShader=t);const s=new THREE.ShaderMaterial(i);this.mesh.material=s}}s.frg_template="#ifdef GL_ES\nprecision mediump float;\n#endif\n// uniform vec2 u_resolution;\n// uniform vec2 u_mouse;\nuniform float u_time;\n\nvoid main() {\n gl_FragColor = vec4(abs(sin(u_time)),0.0,0.0,1.0);\n} ";class r extends e.BaseApplication{constructor(e){super("ShaderPlayground",e)}main(){this.init_editor(),this.init_textures_list(),this.bindKey("ALT-N",()=>this.newFile()),this.bindKey("ALT-O",()=>this.openFile()),this.bindKey("CTRL-S",()=>this.saveFile())}init_editor(){this.tabbar=this.find("tabbar"),this.tabbar.items=[{text:__("Fragment"),iconclass:"bi bi-palette"},{text:__("Vertex"),iconclass:"bi bi-intersect"},{text:__("Textures"),iconclass:"bi bi-image-alt"}],this.tabbar.ontabselect=e=>{this.selectTab()},this.editor=new s(this.find("editor-container"),new n(this.find("viewport"))),this.on("resize",e=>{this.editor.resize()}),this.editor.onfilechange=e=>{this.scheme.apptitle=e},this.editor.ontextureadded=e=>{this.add_texture(e)},this.editor.filehandle=void 0,this.tabbar.selected=0}add_texture(e){{const t=this.find("texture-list");if(!e)return this.editor.renderer.textures=[],void(t.data=this.editor.renderer.textures);const i=(new THREE.TextureLoader).load(e.path.asFileHandle().getlink());i.minFilter=THREE.NearestFilter,i.magFilter=THREE.NearestFilter,i.wrapS=THREE.RepeatWrapping,i.wrapT=THREE.RepeatWrapping,e.texture=i,t.push(e),this.editor.renderer.needupdateTexture=!0}}init_textures_list(){const e=this.find("texture-list");e.buttons=[{text:"__(Add texture)",iconclass:"bi bi-plus",onbtclick:e=>{this.openDialog(new i).then(e=>this.add_texture(e))}}],e.itemtag="afx-shader-texture-item",e.onitemclose=e=>(this.editor.renderer.needupdateTexture=!0,!0),this.add_texture(void 0)}selectTab(){const e=this.tabbar.selected;2===e?($(this.find("editor-container")).hide(),$(this.find("texture-list")).show()):($(this.find("editor-container")).show(),$(this.find("texture-list")).hide()),this.editor.edit(e)}menu(){return[{text:"__(File)",nodes:[{text:"__(New)",dataid:"new",shortcut:"A-N"},{text:"__(Open)",dataid:"open",shortcut:"A-O"},{text:"__(Save)",dataid:"save",shortcut:"C-S"}],onchildselect:e=>{switch(e.data.item.data.dataid){case"new":return this.newFile();case"open":return this.openFile();case"save":return this.saveFile()}}}]}ignore_unsaved(){return new Promise(async(e,t)=>!0===this.editor.filehandle.dirty?e(!!await this.ask({title:__("Unsaved shader"),text:__("Ignore unsaved file?")})):e(!0))}async newFile(){await this.ignore_unsaved()&&(this.editor.filehandle=void 0)}async openFile(){try{if(!await this.ignore_unsaved())return;const e=await this.openDialog("FileDialog",{title:__("Open file"),mimes:this.meta().mimes});this.editor.filehandle.setPath(e.file.path),await this.editor.read()}catch(e){this.error(__(e.toString()),e)}}async saveFile(){if("Untitled"!==this.editor.filehandle.path)return this.editor.write(void 0);const e=await this.openDialog("FileDialog",{title:__("Save as"),file:this.editor.filehandle});let t=e.file.path.asFileHandle();"file"===e.file.type&&(t=t.parent());try{await this.editor.write(`${t.path}/${e.name}`)}catch(e){this.error(__(e.toString()),e)}}cleanup(e){if(this.editor.filehandle.dirty)return this.ignore_unsaved().then(e=>{e&&(this.editor.filehandle.dirty=!1,this.quit(!0))}),void e.preventDefault();this.editor.cleanup()}}e.ShaderPlayground=r,r.dependencies=["pkg://libthreejs/main.js","pkg://ACECore/core/ace.js","pkg://ACECore/path.js","pkg://ACECore/core/ext-language_tools.js","pkg://ShaderPlayground/glslx.js"]}(i=e.application||(e.application={}))}(OS||(OS={})); \ No newline at end of file diff --git a/ShaderPlayground/build/debug/package.json b/ShaderPlayground/build/debug/package.json index 58426e4..e2b7871 100644 --- a/ShaderPlayground/build/debug/package.json +++ b/ShaderPlayground/build/debug/package.json @@ -1,16 +1,42 @@ { "pkgname": "ShaderPlayground", - "app":"ShaderPlayground", - "name":"OpenGL Shader Playground", - "description":"OpenGL Shader Playground", - "info":{ + "app": "ShaderPlayground", + "name": "OpenGL Shader Playground", + "description": "OpenGL Shader Playground", + "info": { "author": "Xuan Sang LE", "email": "mrsang@iohub.dev" }, - "version":"0.0.1-a", - "category":"Development", - "iconclass":"bi bi-lightbulb-fill", - "mimes":["none"], - "dependencies":["libthreejs@0.0.129-r"], - "locale": {} + "version": "0.0.2-a", + "category": "Development", + "iconclass": "bi bi-lightbulb-fill", + "mimes": [ + "application/json" + ], + "dependencies": [ + "libthreejs@0.0.129-r" + ], + "locale": {}, + "locales": { + "en_GB": { + "Name": "Name", + "Path/URL": "Path/URL", + "Ok": "Ok", + "Add texture": "Add texture", + "File": "File", + "New": "New", + "Open": "Open", + "Save": "Save", + "All fields should be filled": "All fields should be filled", + "Select image file": "Select image file", + "Unknown save path": "Unknown save path", + "Fragment": "Fragment", + "Vertex": "Vertex", + "Textures": "Textures", + "Unsaved shader": "Unsaved shader", + "Ignore unsaved file?": "Ignore unsaved file?", + "Open file": "Open file", + "Save as": "Save as" + } + } } \ No newline at end of file diff --git a/ShaderPlayground/build/release/ShaderPlayground.zip b/ShaderPlayground/build/release/ShaderPlayground.zip index 4a77b63fe45575375e3b426f00e12008671eff7b..d109fccca66e99ef09fc0cf8bc6bfda2c6a7e8fc 100644 GIT binary patch delta 4949 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 R9RMJ?Sxh%?xySU+>>p()Cno>^ literal 44449 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 diff --git a/ShaderPlayground/glslx.js b/ShaderPlayground/glslx.js deleted file mode 100644 index 5767934..0000000 --- a/ShaderPlayground/glslx.js +++ /dev/null @@ -1,77 +0,0 @@ -(function(){var ah=Object.create||function(a){return{__proto__:a}};function ph(a,b){a.prototype=ah(b.prototype),a.prototype.constructor=a}var qh=Math.imul||function(a,b){return (a*(b>>>16)<<16)+a*(b&65535)|0};var Xe;function rh(a){return typeof a==='string'}function sh(a){return a===null?a:a+''}function Ue(c,a,b){return c.a=a,c.b=b,c.c=a.length,c}function Ve(c){if(c.b>=c.c)return-1;var a=c.a.charCodeAt((c.b=c.b+1|0)-1|0);if(a&64512^55296)return a;if(c.b>=c.c)return-1;var b=c.a.charCodeAt((c.b=c.b+1|0)-1|0);return ((a<<10)+b|0)-56613888|0}function sc(a){return a.c=a.c+1|0,a.c}function Sc(p,a){switch(a){case 0:var b={};return Array.from(p.b.keys()).forEach(function(c){b[c]=p.b.get(c)}),JSON.stringify({shaders:p.a?p.a.map(function(d){return{name:d.a,contents:d.b}}):null,renaming:b},null,2)+'\n';case 1:if(p.a){for(var e='',C=0,B=p.a,U=B.length;C',"\nimport {\n // The variable `gl_Position` is available only in the vertex language and is intended for writing the\n // homogeneous vertex position. This value will be used by primitive assembly, clipping, culling, and other\n // fixed functionality operations that operate on primitives after vertex processing has occurred.\n //\n // All executions of a well-formed vertex shader should write a value into this variable. It can be\n // written at any time during shader execution. It may also be read back by the shader after being written.\n // Compilers may generate a diagnostic message if they detect `gl_Position` is not written, or read before\n // being written, but not all such cases are detectable. The value of `gl_Position` is undefined if a vertex\n // shader is executed and does not write `gl_Position`.\n highp vec4 gl_Position;\n\n // The variable `gl_PointSize` is available only in the vertex language and is intended for\n // a vertex shader to write the size of the point to be rasterized. It is measured in pixels.\n mediump float gl_PointSize;\n\n const int gl_MaxVertexAttribs;\n const int gl_MaxVertexUniformVectors;\n const int gl_MaxVaryingVectors;\n const int gl_MaxVertexTextureImageUnits;\n const int gl_MaxCombinedTextureImageUnits;\n const int gl_MaxTextureImageUnits;\n const int gl_MaxFragmentUniformVectors;\n const int gl_MaxDrawBuffers;\n\n // The fragment shader has access to the read-only built-in variable `gl_FrontFacing` whose value is `true` if\n // the fragment belongs to a front-facing primitive. One use of this is to emulate two-sided lighting by\n // selecting one of two colors calculated by the vertex shader.\n const bool gl_FrontFacing;\n\n // The fragment shader has access to the read-only built-in variable `gl_PointCoord`. The values in\n // `gl_PointCoord` are two-dimensional coordinates indicating where within a point primitive the current\n // fragment is located. They range from 0.0 to 1.0 across the point. If the current primitive is not a\n // point, then the values read from `gl_PointCoord` are undefined.\n const mediump vec2 gl_PointCoord;\n\n // The variable `gl_FragCoord` is available as a read-only variable from within fragment shaders and it holds\n // the window relative coordinates `x`, `y`, `z`, and `1/w` values for the fragment. This value is the result\n // of the fixed functionality that interpolates primitives after vertex processing to generate fragments. The `z`\n // component is the depth value that will be used for the fragment's depth.\n const mediump vec4 gl_FragCoord;\n\n // Writing to `gl_FragColor` specifies the fragment color that will be used by the subsequent fixed\n // functionality pipeline.\n //\n // If subsequent fixed functionality consumes fragment color and an execution of a fragment shader\n // does not write a value to `gl_FragColor` then the fragment color consumed is undefined.\n mediump vec4 gl_FragColor;\n\n // The variable `gl_FragData` is an array. Writing to `gl_FragData[n]` specifies the fragment data that will be\n // used by the subsequent fixed functionality pipeline for data `n`.\n //\n // If subsequent fixed functionality consumes fragment data and an execution of a fragment shader does not write\n // a value to it, then the fragment data consumed is undefined.\n mediump vec4 gl_FragData[gl_MaxDrawBuffers];\n\n // Depth range in window coordinates\n struct gl_DepthRangeParameters {\n float near;\n float far;\n // Equal to `far - near`\n float diff;\n };\n\n uniform gl_DepthRangeParameters gl_DepthRange;\n\n ////////////////////////////////////////////////////////////////////////////////\n // Angle and Trigonometry Functions\n\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n float radians(float degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec2 radians(vec2 degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec3 radians(vec3 degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec4 radians(vec4 degrees);\n\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n float degrees(float radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec2 degrees(vec2 radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec3 degrees(vec3 radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec4 degrees(vec4 radians);\n\n // The standard trigonometric sine function.\n float sin(float angle);\n // The standard trigonometric sine function.\n vec2 sin(vec2 angle);\n // The standard trigonometric sine function.\n vec3 sin(vec3 angle);\n // The standard trigonometric sine function.\n vec4 sin(vec4 angle);\n\n // The standard trigonometric cosine function.\n float cos(float angle);\n // The standard trigonometric cosine function.\n vec2 cos(vec2 angle);\n // The standard trigonometric cosine function.\n vec3 cos(vec3 angle);\n // The standard trigonometric cosine function.\n vec4 cos(vec4 angle);\n\n // The standard trigonometric tangent.\n float tan(float angle);\n // The standard trigonometric tangent.\n vec2 tan(vec2 angle);\n // The standard trigonometric tangent.\n vec3 tan(vec3 angle);\n // The standard trigonometric tangent.\n vec4 tan(vec4 angle);\n\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n float asin(float x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec2 asin(vec2 x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec3 asin(vec3 x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec4 asin(vec4 x);\n\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n float acos(float x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec2 acos(vec2 x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec3 acos(vec3 x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec4 acos(vec4 x);\n\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n float atan(float y, float x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec2 atan(vec2 y, vec2 x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec3 atan(vec3 y, vec3 x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec4 atan(vec4 y, vec4 x);\n\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n float atan(float y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec2 atan(vec2 y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec3 atan(vec3 y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec4 atan(vec4 y_over_x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Exponential Functions\n\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n float pow(float x, float y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec2 pow(vec2 x, vec2 y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec3 pow(vec3 x, vec3 y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec4 pow(vec4 x, vec4 y);\n\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n float exp(float x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec2 exp(vec2 x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec3 exp(vec3 x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec4 exp(vec4 x);\n\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n float log(float x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec2 log(vec2 x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec3 log(vec3 x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec4 log(vec4 x);\n\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n float exp2(float x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec2 exp2(vec2 x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec3 exp2(vec3 x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec4 exp2(vec4 x);\n\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n float log2(float x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec2 log2(vec2 x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec3 log2(vec3 x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec4 log2(vec4 x);\n\n // Returns `√x`. Results are undefined if `x < 0`.\n float sqrt(float x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec2 sqrt(vec2 x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec3 sqrt(vec3 x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec4 sqrt(vec4 x);\n\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n float inversesqrt(float x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec2 inversesqrt(vec2 x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec3 inversesqrt(vec3 x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec4 inversesqrt(vec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Common Functions\n\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n float abs(float x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec2 abs(vec2 x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec3 abs(vec3 x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec4 abs(vec4 x);\n\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n float sign(float x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec2 sign(vec2 x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec3 sign(vec3 x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec4 sign(vec4 x);\n\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n float floor(float x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec2 floor(vec2 x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec3 floor(vec3 x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec4 floor(vec4 x);\n\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n float ceil(float x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec2 ceil(vec2 x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec3 ceil(vec3 x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec4 ceil(vec4 x);\n\n // Returns `x - floor(x)`\n float fract(float x);\n // Returns `x - floor(x)`\n vec2 fract(vec2 x);\n // Returns `x - floor(x)`\n vec3 fract(vec3 x);\n // Returns `x - floor(x)`\n vec4 fract(vec4 x);\n\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n float mod(float x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec2 mod(vec2 x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec3 mod(vec3 x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec4 mod(vec4 x, float y);\n\n // Modulus. Returns `x - y * floor(x/y)`\n vec2 mod(vec2 x, vec2 y);\n // Modulus. Returns `x - y * floor(x/y)`\n vec3 mod(vec3 x, vec3 y);\n // Modulus. Returns `x - y * floor(x/y)`\n vec4 mod(vec4 x, vec4 y);\n\n // Returns `y` if `y < x`, otherwise it returns `x`\n float min(float x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec2 min(vec2 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec2 min(vec2 x, vec2 y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec3 min(vec3 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec3 min(vec3 x, vec3 y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec4 min(vec4 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec4 min(vec4 x, vec4 y);\n\n // Returns `y` if `x < y`, otherwise it returns `x`\n float max(float x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec2 max(vec2 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec2 max(vec2 x, vec2 y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec3 max(vec3 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec3 max(vec3 x, vec3 y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec4 max(vec4 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec4 max(vec4 x, vec4 y);\n\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n float clamp(float x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec2 clamp(vec2 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec3 clamp(vec3 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec4 clamp(vec4 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);\n\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n float mix(float x, float y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec2 mix(vec2 x, vec2 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec2 mix(vec2 x, vec2 y, vec2 a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec3 mix(vec3 x, vec3 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec3 mix(vec3 x, vec3 y, vec3 a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec4 mix(vec4 x, vec4 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec4 mix(vec4 x, vec4 y, vec4 a);\n\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n float step(float edge, float x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec2 step(float edge, vec2 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec2 step(vec2 edge, vec2 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec3 step(float edge, vec3 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec3 step(vec3 edge, vec3 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec4 step(float edge, vec4 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec4 step(vec4 edge, vec4 x);\n\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n float smoothstep(float edge0, float edge1, float x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec2 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec2 smoothstep(float edge0, float edge1, vec2 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec2 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec3 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec3 smoothstep(float edge0, float edge1, vec3 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec3 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec4 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec4 smoothstep(float edge0, float edge1, vec4 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec4 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Geometric Functions\n\n // Returns the length of vector `x`, i.e. `√x²`\n float length(float x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]²`\n float length(vec2 x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]² + x[2]²`\n float length(vec3 x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]² + x[2]² + x[3]²`\n float length(vec4 x);\n\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(float p0, float p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec2 p0, vec2 p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec3 p0, vec3 p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec4 p0, vec4 p1);\n\n // Returns the dot product of `x` and `y`, i.e. `x*y`\n float dot(float x, float y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1]`\n float dot(vec2 x, vec2 y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1] + x[2]*y[2]`\n float dot(vec3 x, vec3 y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3]`\n float dot(vec4 x, vec4 y);\n\n // Returns the cross product of `x` and `y`, i.e.\n //\n // ```glslx\n // vec3(\n // x[1]*y[2] - y[1]*x[2],\n // x[2]*y[0] - y[2]*x[0],\n // x[0]*y[1] - y[0]*x[1])\n // ```\n vec3 cross(vec3 x, vec3 y);\n\n // Returns a vector in the same direction as `x` but with a length of 1.\n float normalize(float x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec2 normalize(vec2 x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec3 normalize(vec3 x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec4 normalize(vec4 x);\n\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n float faceforward(float N, float I, float Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec2 faceforward(vec2 N, vec2 I, vec2 Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec3 faceforward(vec3 N, vec3 I, vec3 Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec4 faceforward(vec4 N, vec4 I, vec4 Nref);\n\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n float reflect(float I, float N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec2 reflect(vec2 I, vec2 N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec3 reflect(vec3 I, vec3 N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec4 reflect(vec4 I, vec4 N);\n\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return float(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n float refract(float I, float N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec2(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec2 refract(vec2 I, vec2 N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec3(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec3 refract(vec3 I, vec3 N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec4(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec4 refract(vec4 I, vec4 N, float eta);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Matrix Functions\n\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat2 matrixCompMult(mat2 x, mat2 y);\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat3 matrixCompMult(mat3 x, mat3 y);\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat4 matrixCompMult(mat4 x, mat4 y);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Vector Relational Functions\n\n // Returns the component-wise compare of `x < y`.\n bvec2 lessThan(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x < y`.\n bvec2 lessThan(vec2 x, vec2 y);\n // Returns the component-wise compare of `x < y`.\n bvec3 lessThan(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x < y`.\n bvec3 lessThan(vec3 x, vec3 y);\n // Returns the component-wise compare of `x < y`.\n bvec4 lessThan(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x < y`.\n bvec4 lessThan(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x <= y`.\n bvec2 lessThanEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x <= y`.\n bvec2 lessThanEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x <= y`.\n bvec3 lessThanEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x <= y`.\n bvec3 lessThanEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x <= y`.\n bvec4 lessThanEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x <= y`.\n bvec4 lessThanEqual(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x > y`.\n bvec2 greaterThan(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x > y`.\n bvec2 greaterThan(vec2 x, vec2 y);\n // Returns the component-wise compare of `x > y`.\n bvec3 greaterThan(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x > y`.\n bvec3 greaterThan(vec3 x, vec3 y);\n // Returns the component-wise compare of `x > y`.\n bvec4 greaterThan(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x > y`.\n bvec4 greaterThan(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x >= y`.\n bvec2 greaterThanEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x >= y`.\n bvec2 greaterThanEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x >= y`.\n bvec3 greaterThanEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x >= y`.\n bvec3 greaterThanEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x >= y`.\n bvec4 greaterThanEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x >= y`.\n bvec4 greaterThanEqual(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(bvec2 x, bvec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(vec2 x, vec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(bvec3 x, bvec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(vec3 x, vec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(bvec4 x, bvec4 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(bvec2 x, bvec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(bvec3 x, bvec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(bvec4 x, bvec4 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(vec4 x, vec4 y);\n\n // Returns true if any component of `x` is `true`.\n bool any(bvec2 x);\n // Returns true if any component of `x` is `true`.\n bool any(bvec3 x);\n // Returns true if any component of `x` is `true`.\n bool any(bvec4 x);\n\n // Returns true only if all components of `x` are `true`.\n bool all(bvec2 x);\n // Returns true only if all components of `x` are `true`.\n bool all(bvec3 x);\n // Returns true only if all components of `x` are `true`.\n bool all(bvec4 x);\n\n // Returns the component-wise logical complement of `x`.\n bvec2 not(bvec2 x);\n // Returns the component-wise logical complement of `x`.\n bvec3 not(bvec3 x);\n // Returns the component-wise logical complement of `x`.\n bvec4 not(bvec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Texture Lookup Functions\n\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2D(sampler2D sampler, vec2 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2D(sampler2D sampler, vec2 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProj(sampler2D sampler, vec3 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProj(sampler2D sampler, vec4 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);\n\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCube(samplerCube sampler, vec3 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCube(samplerCube sampler, vec3 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);\n\n #extension GL_OES_standard_derivatives {\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n float dFdx(float v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec2 dFdx(vec2 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec3 dFdx(vec3 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec4 dFdx(vec4 v);\n\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n float dFdy(float v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec2 dFdy(vec2 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec3 dFdy(vec3 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec4 dFdy(vec4 v);\n\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n float fwidth(float v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec2 fwidth(vec2 v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec3 fwidth(vec3 v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec4 fwidth(vec4 v);\n }\n\n #extension GL_EXT_frag_depth {\n // Available only in the fragment language, `gl_FragDepthEXT` is an output variable that is used to establish the depth value for the current fragment.\n // If depth buffering is enabled and no shader writes to `gl_FragDepthEXT`, then the fixed function value for depth will be used (this value is contained\n // in the `z` component of `gl_FragCoord`) otherwise, the value written to `gl_FragDepthEXT` is used.\n //\n // If a shader statically assigns to `gl_FragDepthEXT`, then the value of the fragment's depth may be undefined for executions of the shader that take\n // that path. That is, if the set of linked fragment shaders statically contain a write to `gl_FragDepthEXT`, then it is responsible for always writing it.\n float gl_FragDepthEXT;\n }\n\n #extension GL_EXT_shader_texture_lod {\n vec4 texture2DGradEXT(sampler2D sampler, vec2 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DLodEXT(sampler2D sampler, vec2 coord, float lod);\n vec4 texture2DProjGradEXT(sampler2D sampler, vec3 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DProjGradEXT(sampler2D sampler, vec4 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DProjLodEXT(sampler2D sampler, vec3 coord, float lod);\n vec4 texture2DProjLodEXT(sampler2D sampler, vec4 coord, float lod);\n vec4 textureCubeGradEXT(samplerCube sampler, vec3 P, vec3 dPdx, vec3 dPdy);\n vec4 textureCubeLodEXT(samplerCube sampler, vec3 coord, float lod);\n }\n}\n")); -for(var o=0,k=b.length;o',"\nimport {\n // The variable `gl_Position` is available only in the vertex language and is intended for writing the\n // homogeneous vertex position. This value will be used by primitive assembly, clipping, culling, and other\n // fixed functionality operations that operate on primitives after vertex processing has occurred.\n //\n // All executions of a well-formed vertex shader should write a value into this variable. It can be\n // written at any time during shader execution. It may also be read back by the shader after being written.\n // Compilers may generate a diagnostic message if they detect `gl_Position` is not written, or read before\n // being written, but not all such cases are detectable. The value of `gl_Position` is undefined if a vertex\n // shader is executed and does not write `gl_Position`.\n highp vec4 gl_Position;\n\n // The variable `gl_PointSize` is available only in the vertex language and is intended for\n // a vertex shader to write the size of the point to be rasterized. It is measured in pixels.\n mediump float gl_PointSize;\n\n const int gl_MaxVertexAttribs;\n const int gl_MaxVertexUniformVectors;\n const int gl_MaxVaryingVectors;\n const int gl_MaxVertexTextureImageUnits;\n const int gl_MaxCombinedTextureImageUnits;\n const int gl_MaxTextureImageUnits;\n const int gl_MaxFragmentUniformVectors;\n const int gl_MaxDrawBuffers;\n\n // The fragment shader has access to the read-only built-in variable `gl_FrontFacing` whose value is `true` if\n // the fragment belongs to a front-facing primitive. One use of this is to emulate two-sided lighting by\n // selecting one of two colors calculated by the vertex shader.\n const bool gl_FrontFacing;\n\n // The fragment shader has access to the read-only built-in variable `gl_PointCoord`. The values in\n // `gl_PointCoord` are two-dimensional coordinates indicating where within a point primitive the current\n // fragment is located. They range from 0.0 to 1.0 across the point. If the current primitive is not a\n // point, then the values read from `gl_PointCoord` are undefined.\n const mediump vec2 gl_PointCoord;\n\n // The variable `gl_FragCoord` is available as a read-only variable from within fragment shaders and it holds\n // the window relative coordinates `x`, `y`, `z`, and `1/w` values for the fragment. This value is the result\n // of the fixed functionality that interpolates primitives after vertex processing to generate fragments. The `z`\n // component is the depth value that will be used for the fragment's depth.\n const mediump vec4 gl_FragCoord;\n\n // Writing to `gl_FragColor` specifies the fragment color that will be used by the subsequent fixed\n // functionality pipeline.\n //\n // If subsequent fixed functionality consumes fragment color and an execution of a fragment shader\n // does not write a value to `gl_FragColor` then the fragment color consumed is undefined.\n mediump vec4 gl_FragColor;\n\n // The variable `gl_FragData` is an array. Writing to `gl_FragData[n]` specifies the fragment data that will be\n // used by the subsequent fixed functionality pipeline for data `n`.\n //\n // If subsequent fixed functionality consumes fragment data and an execution of a fragment shader does not write\n // a value to it, then the fragment data consumed is undefined.\n mediump vec4 gl_FragData[gl_MaxDrawBuffers];\n\n // Depth range in window coordinates\n struct gl_DepthRangeParameters {\n float near;\n float far;\n // Equal to `far - near`\n float diff;\n };\n\n uniform gl_DepthRangeParameters gl_DepthRange;\n\n ////////////////////////////////////////////////////////////////////////////////\n // Angle and Trigonometry Functions\n\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n float radians(float degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec2 radians(vec2 degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec3 radians(vec3 degrees);\n // Converts `degrees` to radians, i.e. `π / 180 * degrees`\n vec4 radians(vec4 degrees);\n\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n float degrees(float radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec2 degrees(vec2 radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec3 degrees(vec3 radians);\n // Converts `radians` to degrees, i.e. `180 / π * radians`\n vec4 degrees(vec4 radians);\n\n // The standard trigonometric sine function.\n float sin(float angle);\n // The standard trigonometric sine function.\n vec2 sin(vec2 angle);\n // The standard trigonometric sine function.\n vec3 sin(vec3 angle);\n // The standard trigonometric sine function.\n vec4 sin(vec4 angle);\n\n // The standard trigonometric cosine function.\n float cos(float angle);\n // The standard trigonometric cosine function.\n vec2 cos(vec2 angle);\n // The standard trigonometric cosine function.\n vec3 cos(vec3 angle);\n // The standard trigonometric cosine function.\n vec4 cos(vec4 angle);\n\n // The standard trigonometric tangent.\n float tan(float angle);\n // The standard trigonometric tangent.\n vec2 tan(vec2 angle);\n // The standard trigonometric tangent.\n vec3 tan(vec3 angle);\n // The standard trigonometric tangent.\n vec4 tan(vec4 angle);\n\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n float asin(float x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec2 asin(vec2 x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec3 asin(vec3 x);\n // Arc sine. Returns an angle whose sine is `x`. The range of values returned by this function is `[-π/2, π/2]`. Results are undefined if `∣x∣>1`.\n vec4 asin(vec4 x);\n\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n float acos(float x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec2 acos(vec2 x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec3 acos(vec3 x);\n // Arc cosine. Returns an angle whose cosine is `x`. The range of values returned by this function is `[0, π]`. Results are undefined if `∣x∣>1`.\n vec4 acos(vec4 x);\n\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n float atan(float y, float x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec2 atan(vec2 y, vec2 x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec3 atan(vec3 y, vec3 x);\n // Arc tangent. Returns an angle whose tangent is `y/x`. The signs of `x` and `y` are used to determine what quadrant the\n // angle is in. The range of values returned by this function is `[−π,π]`. Results are undefined if `x` and `y` are both 0.\n vec4 atan(vec4 y, vec4 x);\n\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n float atan(float y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec2 atan(vec2 y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec3 atan(vec3 y_over_x);\n // Arc tangent. Returns an angle whose tangent is `y_over_x`. The range of values returned by this function is `[-π/2, π/2]`.\n vec4 atan(vec4 y_over_x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Exponential Functions\n\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n float pow(float x, float y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec2 pow(vec2 x, vec2 y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec3 pow(vec3 x, vec3 y);\n // Returns `x` raised to the `y` power, i.e., `xʸ`. Results are undefined if `x < 0`. Results are undefined if `x = 0` and `y <= 0`.\n vec4 pow(vec4 x, vec4 y);\n\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n float exp(float x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec2 exp(vec2 x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec3 exp(vec3 x);\n // Returns the natural exponentiation of `x`, i.e., `eˣ`\n vec4 exp(vec4 x);\n\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n float log(float x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec2 log(vec2 x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec3 log(vec3 x);\n // Returns the natural logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = eʸ`. Results are undefined if `x <= 0`.\n vec4 log(vec4 x);\n\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n float exp2(float x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec2 exp2(vec2 x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec3 exp2(vec3 x);\n // Returns 2 raised to the `x` power, i.e., `2ˣ`.\n vec4 exp2(vec4 x);\n\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n float log2(float x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec2 log2(vec2 x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec3 log2(vec3 x);\n // Returns the base 2 logarithm of `x`, i.e., returns the value `y` which satisfies the equation `x = 2ʸ`. Results are undefined if `x <= 0`.\n vec4 log2(vec4 x);\n\n // Returns `√x`. Results are undefined if `x < 0`.\n float sqrt(float x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec2 sqrt(vec2 x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec3 sqrt(vec3 x);\n // Returns `√x`. Results are undefined if `x < 0`.\n vec4 sqrt(vec4 x);\n\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n float inversesqrt(float x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec2 inversesqrt(vec2 x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec3 inversesqrt(vec3 x);\n // Returns `1 / √x`. Results are undefined if `x <= 0`.\n vec4 inversesqrt(vec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Common Functions\n\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n float abs(float x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec2 abs(vec2 x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec3 abs(vec3 x);\n // Returns `x` if `x >= 0`, otherwise it returns `-x`.\n vec4 abs(vec4 x);\n\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n float sign(float x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec2 sign(vec2 x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec3 sign(vec3 x);\n // Returns `1.0` if `x > 0`, `0.0` if `x = 0`, or `-1.0` if `x < 0`\n vec4 sign(vec4 x);\n\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n float floor(float x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec2 floor(vec2 x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec3 floor(vec3 x);\n // Returns a value equal to the nearest integer that is less than or equal to `x`\n vec4 floor(vec4 x);\n\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n float ceil(float x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec2 ceil(vec2 x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec3 ceil(vec3 x);\n // Returns a value equal to the nearest integer that is greater than or equal to `x`\n vec4 ceil(vec4 x);\n\n // Returns `x - floor(x)`\n float fract(float x);\n // Returns `x - floor(x)`\n vec2 fract(vec2 x);\n // Returns `x - floor(x)`\n vec3 fract(vec3 x);\n // Returns `x - floor(x)`\n vec4 fract(vec4 x);\n\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n float mod(float x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec2 mod(vec2 x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec3 mod(vec3 x, float y);\n // Modulus (modulo). Returns `x - y * floor(x/y)`\n vec4 mod(vec4 x, float y);\n\n // Modulus. Returns `x - y * floor(x/y)`\n vec2 mod(vec2 x, vec2 y);\n // Modulus. Returns `x - y * floor(x/y)`\n vec3 mod(vec3 x, vec3 y);\n // Modulus. Returns `x - y * floor(x/y)`\n vec4 mod(vec4 x, vec4 y);\n\n // Returns `y` if `y < x`, otherwise it returns `x`\n float min(float x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec2 min(vec2 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec2 min(vec2 x, vec2 y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec3 min(vec3 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec3 min(vec3 x, vec3 y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec4 min(vec4 x, float y);\n // Returns `y` if `y < x`, otherwise it returns `x`\n vec4 min(vec4 x, vec4 y);\n\n // Returns `y` if `x < y`, otherwise it returns `x`\n float max(float x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec2 max(vec2 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec2 max(vec2 x, vec2 y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec3 max(vec3 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec3 max(vec3 x, vec3 y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec4 max(vec4 x, float y);\n // Returns `y` if `x < y`, otherwise it returns `x`\n vec4 max(vec4 x, vec4 y);\n\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n float clamp(float x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec2 clamp(vec2 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec3 clamp(vec3 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec4 clamp(vec4 x, float minVal, float maxVal);\n // Returns `min(max(x, minVal), maxVal)`. Results are undefined if `minVal > maxVal`.\n vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);\n\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n float mix(float x, float y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec2 mix(vec2 x, vec2 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec2 mix(vec2 x, vec2 y, vec2 a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec3 mix(vec3 x, vec3 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec3 mix(vec3 x, vec3 y, vec3 a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec4 mix(vec4 x, vec4 y, float a);\n // Returns the linear blend of `x` and `y`, i.e. `x * (1-a) + y * a`\n vec4 mix(vec4 x, vec4 y, vec4 a);\n\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n float step(float edge, float x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec2 step(float edge, vec2 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec2 step(vec2 edge, vec2 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec3 step(float edge, vec3 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec3 step(vec3 edge, vec3 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec4 step(float edge, vec4 x);\n // Returns `0.0` if `x < edge`, otherwise it returns `1.0`\n vec4 step(vec4 edge, vec4 x);\n\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n float smoothstep(float edge0, float edge1, float x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec2 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec2 smoothstep(float edge0, float edge1, vec2 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec2 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec3 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec3 smoothstep(float edge0, float edge1, vec3 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec3 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec4 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec4 smoothstep(float edge0, float edge1, vec4 x);\n // Returns `0.0` if `x <= edge0` and `1.0` if `x >= edge1` and performs smooth Hermite interpolation between 0 and 1 when `edge0 < x < edge1`.\n // This is useful in cases where you would want a threshold function with a smooth transition. This is equivalent to:\n //\n // ```glslx\n // vec4 t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n // return t * t * (3.0 - 2.0 * t);\n // ```\n //\n // Results are undefined if `edge0 >= edge1`.\n vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Geometric Functions\n\n // Returns the length of vector `x`, i.e. `√x²`\n float length(float x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]²`\n float length(vec2 x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]² + x[2]²`\n float length(vec3 x);\n // Returns the length of vector `x`, i.e. `√x[0]² + x[1]² + x[2]² + x[3]²`\n float length(vec4 x);\n\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(float p0, float p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec2 p0, vec2 p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec3 p0, vec3 p1);\n // Returns the distance between `p0` and `p1`, i.e. `length(p0 - p1)`\n float distance(vec4 p0, vec4 p1);\n\n // Returns the dot product of `x` and `y`, i.e. `x*y`\n float dot(float x, float y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1]`\n float dot(vec2 x, vec2 y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1] + x[2]*y[2]`\n float dot(vec3 x, vec3 y);\n // Returns the dot product of `x` and `y`, i.e. `x[0]*y[0] + x[1]*y[1] + x[2]*y[2] + x[3]*y[3]`\n float dot(vec4 x, vec4 y);\n\n // Returns the cross product of `x` and `y`, i.e.\n //\n // ```glslx\n // vec3(\n // x[1]*y[2] - y[1]*x[2],\n // x[2]*y[0] - y[2]*x[0],\n // x[0]*y[1] - y[0]*x[1])\n // ```\n vec3 cross(vec3 x, vec3 y);\n\n // Returns a vector in the same direction as `x` but with a length of 1.\n float normalize(float x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec2 normalize(vec2 x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec3 normalize(vec3 x);\n // Returns a vector in the same direction as `x` but with a length of 1.\n vec4 normalize(vec4 x);\n\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n float faceforward(float N, float I, float Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec2 faceforward(vec2 N, vec2 I, vec2 Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec3 faceforward(vec3 N, vec3 I, vec3 Nref);\n // If `dot(Nref, I) < 0` return `N`, otherwise return `-N`\n vec4 faceforward(vec4 N, vec4 I, vec4 Nref);\n\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n float reflect(float I, float N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec2 reflect(vec2 I, vec2 N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec3 reflect(vec3 I, vec3 N);\n // For the incident vector `I` and surface orientation `N`, returns the reflection direction: `I - 2 * dot(N, I) * N`.\n // `N` must already be normalized in order to achieve the desired result.\n vec4 reflect(vec4 I, vec4 N);\n\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return float(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n float refract(float I, float N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec2(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec2 refract(vec2 I, vec2 N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec3(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec3 refract(vec3 I, vec3 N, float eta);\n // For the incident vector `I` and surface normal `N`, and the ratio of indices of refraction `eta`, return the refraction vector.\n // The result is computed by:\n //\n // ```glslx\n // float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I));\n // if (k < 0.0) return vec4(0.0);\n // else return eta * I - (eta * dot(N, I) + sqrt(k)) * N;\n // ```\n //\n // The input parameters for the incident vector `I` and the surface normal `N`.\n vec4 refract(vec4 I, vec4 N, float eta);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Matrix Functions\n\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat2 matrixCompMult(mat2 x, mat2 y);\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat3 matrixCompMult(mat3 x, mat3 y);\n // Multiply matrix `x` by matrix `y` component-wise, i.e., `result[i][j]` is the scalar product of `x[i][j]` and `y[i][j]`.\n // Note: to get linear algebraic matrix multiplication, use the multiply operator (`*`).\n mat4 matrixCompMult(mat4 x, mat4 y);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Vector Relational Functions\n\n // Returns the component-wise compare of `x < y`.\n bvec2 lessThan(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x < y`.\n bvec2 lessThan(vec2 x, vec2 y);\n // Returns the component-wise compare of `x < y`.\n bvec3 lessThan(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x < y`.\n bvec3 lessThan(vec3 x, vec3 y);\n // Returns the component-wise compare of `x < y`.\n bvec4 lessThan(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x < y`.\n bvec4 lessThan(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x <= y`.\n bvec2 lessThanEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x <= y`.\n bvec2 lessThanEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x <= y`.\n bvec3 lessThanEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x <= y`.\n bvec3 lessThanEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x <= y`.\n bvec4 lessThanEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x <= y`.\n bvec4 lessThanEqual(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x > y`.\n bvec2 greaterThan(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x > y`.\n bvec2 greaterThan(vec2 x, vec2 y);\n // Returns the component-wise compare of `x > y`.\n bvec3 greaterThan(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x > y`.\n bvec3 greaterThan(vec3 x, vec3 y);\n // Returns the component-wise compare of `x > y`.\n bvec4 greaterThan(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x > y`.\n bvec4 greaterThan(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x >= y`.\n bvec2 greaterThanEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x >= y`.\n bvec2 greaterThanEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x >= y`.\n bvec3 greaterThanEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x >= y`.\n bvec3 greaterThanEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x >= y`.\n bvec4 greaterThanEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x >= y`.\n bvec4 greaterThanEqual(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(bvec2 x, bvec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec2 equal(vec2 x, vec2 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(bvec3 x, bvec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec3 equal(vec3 x, vec3 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(bvec4 x, bvec4 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x == y`.\n bvec4 equal(vec4 x, vec4 y);\n\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(bvec2 x, bvec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(ivec2 x, ivec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec2 notEqual(vec2 x, vec2 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(bvec3 x, bvec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(ivec3 x, ivec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec3 notEqual(vec3 x, vec3 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(bvec4 x, bvec4 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(ivec4 x, ivec4 y);\n // Returns the component-wise compare of `x != y`.\n bvec4 notEqual(vec4 x, vec4 y);\n\n // Returns true if any component of `x` is `true`.\n bool any(bvec2 x);\n // Returns true if any component of `x` is `true`.\n bool any(bvec3 x);\n // Returns true if any component of `x` is `true`.\n bool any(bvec4 x);\n\n // Returns true only if all components of `x` are `true`.\n bool all(bvec2 x);\n // Returns true only if all components of `x` are `true`.\n bool all(bvec3 x);\n // Returns true only if all components of `x` are `true`.\n bool all(bvec4 x);\n\n // Returns the component-wise logical complement of `x`.\n bvec2 not(bvec2 x);\n // Returns the component-wise logical complement of `x`.\n bvec3 not(bvec3 x);\n // Returns the component-wise logical complement of `x`.\n bvec4 not(bvec4 x);\n\n ////////////////////////////////////////////////////////////////////////////////\n // Texture Lookup Functions\n\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2D(sampler2D sampler, vec2 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2D(sampler2D sampler, vec2 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProj(sampler2D sampler, vec3 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`.\n vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProj(sampler2D sampler, vec4 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the 2D texture currently bound to `sampler`.\n // The texture coordinate `(coord.s, coord.t)` is divided by the last component of `coord`. The third component of `coord` is ignored.\n vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);\n\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCube(samplerCube sampler, vec3 coord);\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCube(samplerCube sampler, vec3 coord, float bias);\n // Use the texture coordinate `coord` to do a texture lookup in the cube map texture currently bound to `sampler`.\n // The direction of `coord` is used to select which face to do a 2-dimensional texture lookup in.\n vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);\n\n #extension GL_OES_standard_derivatives {\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n float dFdx(float v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec2 dFdx(vec2 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec3 dFdx(vec3 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `x` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdx(dFdx(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec4 dFdx(vec4 v);\n\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n float dFdy(float v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec2 dFdy(vec2 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec3 dFdy(vec3 v);\n // Available only in the fragment shader, this function returns the partial derivative of expression `p` with respect to the window `y` coordinate.\n //\n // Expressions that imply higher order derivatives such as `dFdy(dFdy(n))` have undefined results, as do mixed-order derivatives such as\n // `dFdx(dFdy(n))`. It is assumed that the expression `p` is continuous and therefore, expressions evaluated via non-uniform control flow may be undefined.\n vec4 dFdy(vec4 v);\n\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n float fwidth(float v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec2 fwidth(vec2 v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec3 fwidth(vec3 v);\n // Returns the sum of the absolute derivative in `x` and `y` using local differencing for the input argument `p`, i.e. `abs(dFdx(p)) + abs(dFdy(p))`\n vec4 fwidth(vec4 v);\n }\n\n #extension GL_EXT_frag_depth {\n // Available only in the fragment language, `gl_FragDepthEXT` is an output variable that is used to establish the depth value for the current fragment.\n // If depth buffering is enabled and no shader writes to `gl_FragDepthEXT`, then the fixed function value for depth will be used (this value is contained\n // in the `z` component of `gl_FragCoord`) otherwise, the value written to `gl_FragDepthEXT` is used.\n //\n // If a shader statically assigns to `gl_FragDepthEXT`, then the value of the fragment's depth may be undefined for executions of the shader that take\n // that path. That is, if the set of linked fragment shaders statically contain a write to `gl_FragDepthEXT`, then it is responsible for always writing it.\n float gl_FragDepthEXT;\n }\n\n #extension GL_EXT_shader_texture_lod {\n vec4 texture2DGradEXT(sampler2D sampler, vec2 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DLodEXT(sampler2D sampler, vec2 coord, float lod);\n vec4 texture2DProjGradEXT(sampler2D sampler, vec3 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DProjGradEXT(sampler2D sampler, vec4 P, vec2 dPdx, vec2 dPdy);\n vec4 texture2DProjLodEXT(sampler2D sampler, vec3 coord, float lod);\n vec4 texture2DProjLodEXT(sampler2D sampler, vec4 coord, float lod);\n vec4 textureCubeGradEXT(samplerCube sampler, vec3 P, vec3 dPdx, vec3 dPdy);\n vec4 textureCubeLodEXT(samplerCube sampler, vec3 coord, float lod);\n }\n}\n")); -for(var Q=0,ia=b.length;Q',a,b,10);break;case 42:V(c,'>=',a,b,10);break;case 44:V(c,'<',a,b,10);break;case 45:V(c,'<=',a,b,10);break;case 46:V(c,'&&',a,b,5);break;case 47:V(c,'||',a,b,3);break;case 48:V(c,'^^',a,b,4);break;case 49:V(c,'*',a,b,13);break;case 50:V(c,'!=',a,b,10);break;case 51:V(c,'-',a,b,12); -break;case 52:V(c,'=',a,b,2);break;case 53:V(c,'+=',a,b,2);break;case 54:V(c,'/=',a,b,2);break;case 55:V(c,'*=',a,b,2);break;case 56:V(c,'-=',a,b,2);break;default:c.a+=Sg[a.b];break}}function _b(f,a,b,c){var d=b.g,e=d.b;f.a+=a,(a.charCodeAt(0)==45&&(e==31||e==34||Wf(d))||a.charCodeAt(0)==43&&(e==33||e==35))&&(f.a+=' '),I(f,d,14)}function Nd(d,a,b,c){I(d,b.g,15),d.a+=a}function V(f,a,b,c,d){var e=Bc(b.b);dZ});case 42:return tc(a,function($,ca){return $>=ca});case 44:return tc(a,function(ua,aa){return ua2&&(d=2),Yb(c,d)}function tf(a,b,c){switch(c){case 48:switch(b){case 65:return!0;case 96:return!1}break;case 47:switch(b){case 62:return!0;case 96:return!1}break;case 65:if(b==65)return!0;break;case 62:if(b==62)return!0;break;case 85:if(ud(b)||b==88)return!1;break;case 84:if(ud(b)||b==88)return!1;break;case 81:case 90:case 89:case 88:case 82:return!1;case 87:if(b==83)return!1;break}switch(b){case 85:case 84:case 82:case 49:case 46:return!1;case 65:case 62:switch(a){case 99:case 85:case 84:case 81:case 80:case 90:case 49:case 46:case 32:case 12:return!1}if(Fg(a))return!1;break;case 48:case 47:if(c==96)return!1;break}return!0}function uc(a){return a==10||a==13}function uf(a){for(var b=0,c=a.length;b0&&!uc(b.charCodeAt(g-1|0));)g=g-1|0;for(var i=b.slice(g),o=i,C=0,B=e.slice(1),U=B.length;C',a),h=Jc(e,f,1);if(e.c)return a;var m='',l=99,g=99,i=0,o=0,k=!0,r=0,s=null,w=function(p){return!vc(a.slice(h[p-1|0].a.c,h[p].a.b))},C=function(B,U){switch(B){case 90:case 87: -return!0;case 4:case 9:case 10:case 11:case 12:case 15:case 17:case 32:case 43:return!U}return!1},F=null,Q=function(){for(var ia=1,M=r;M0;s=s-1|0){for(var w=[],Va=0,wa=k,xa=wa.length;Va=s&&w.push(p)}if(w.length){k=w;break}}if(k.length>1){var C=k.slice();Ab(C,function(B){for(var U=l[B].i,F=0,eb=Math.min(U.length,h.length);F-1){c+=' {\n';for(var i=0,o=b.g,k=o.length;id&&c.charCodeAt(e-1|0)==32;)e=e-1|0;b!=''&&(b+='\n'), -b+=c.slice(d,e)}return b}function $d(a,b,c){if(!b)return a+': '+c+'\n';var d=ld(b,0);return kd(b)+': '+a+': '+c+'\n'+d.a+'\n'+d.b+'\n'}function Ff(c){for(var a=new nh,d=0,e=c.a,f=e.length;d1&&a.charCodeAt(0)==48&&a.charCodeAt(1)^120&&a.charCodeAt(1)^88?parseInt(a,8):a|0}function Yf(){var a=new Oh,b=function(c,d,e){return ae(c.a,d.a),v(t(new Jh(27),K),_a(d.a,e.c))},f=function(h,m,l,g){return ae(h.a,l.a),v(t(new Jh(27),K),_a(m.c,g.c))};return P(a,36,function(i,o){return v(t(Ba(new Jh(28),!0),Y),o.a)}),P(a,13,function(k,r){return v(t(Ba(new Jh(28),!1),Y),r.a)}),P(a,97,function(s,w){return v(t(_(new Jh(30),Xf(L(w.a))),ga),w.a)}),P(a,95,function(p,C){return v(t(ma(new Jh(29),+L(C.a)),da),C.a)}),P(a,3,ba(Y)),P(a,5,ba(Lb)),P(a,6,ba(Mb)),P(a,7,ba(Nb)),P(a,14,ba(da)),P(a,20,ba(ga)),P(a,22,ba(vb)),P(a,23,ba(wb)),P(a,24,ba(xb)),P(a,26,ba(ob)),P(a,27,ba(pb)),P(a,28,ba(qb)),P(a,39,ba(Fa)),P(a,40,ba(Ga)),P(a,41,ba(Ha)),P(a,42,ba(yd)),Ib(a,46,14,b),Ib(a,47,14,ec(34)), -Ib(a,48,14,ec(35)),Ib(a,62,14,ec(31)),Ib(a,49,14,ec(32)),Ib(a,65,14,ec(33)),ve(a,47,15,me(36)),ve(a,48,15,me(37)),R(a,53,13,W(39)),R(a,54,10,W(40)),R(a,55,10,W(41)),R(a,56,10,W(42)),R(a,57,10,W(44)),R(a,58,10,W(45)),R(a,62,12,W(51)),R(a,63,13,W(49)),R(a,64,10,W(50)),R(a,65,12,W(38)),R(a,66,13,f),R(a,67,11,f),R(a,68,11,f),R(a,60,3,W(47)),R(a,61,4,W(48)),R(a,59,5,W(46)),R(a,50,8,f),R(a,51,6,f),R(a,52,7,f),ta(a,69,2,W(52)),ta(a,70,2,W(53)),ta(a,71,2,f),ta(a,72,2,f),ta(a,73,2,f),ta(a,74,2,W(54)),ta(a,75,2,W(55)),ta(a,76,2,f),ta(a,77,2,f),ta(a,78,2,f),ta(a,79,2,W(56)),P(a,96,function(B,U){var F=L(U.a),Q=pd(B.l,F);return Q?(Q.m!=null&&ya(B.c.a,Q.m,0)==1&&u(B.a,U.a,'Cannot use "'+F+'" from disabled extension "'+Q.m+'"'),v(Q instanceof Tb?t(new Jh(26),J(Q)):Cc(new Jh(23),Q),U.a)):(Jf(B.a,U.a),v(t(new Jh(24),K),U.a))}),R(a,81,1,function(ia,M,ha,Z){return M.b^25&&(M=v(n(new Jh(25),M),M.c)),n(M,Z),v(M,A(ia,M.c))}),Da(a,82,16).c=function($,ca){var ua=y($).a;E($);var aa=y($).a;return z($,96)?Qa(v(cc(n(new Jh(21),ca),L(aa)), -A($,ca.c)),aa):Qa(v(cc(n(new Jh(21),ca),''),A($,ca.c)),xe(ua))},Da(a,85,0).b=function(ka){var va=E(ka),Ua=T(a,ka,0);return !Ua||!z(ka,89)?v(t(new Jh(24),K),A(ka,va.a)):v(Ua,A(ka,va.a))},Da(a,85,15).c=function(la,rb){var La=E(la),Va=n(new Jh(20),rb);return Zf(la,Va,89)?Qa(v(Va,A(la,rb.c)),A(la,La.a)):v(t(new Jh(24),K),A(la,La.a))},Da(a,84,16).c=function(wa,xa){var eb=E(wa);if(y(wa).b==88)return Gb(wa),E(wa),v(t(new Jh(24),K),A(wa,eb.a));var Ia=T(a,wa,0);return !Ia||!z(wa,88)?v(t(new Jh(24),K),A(wa,eb.a)):Qa(v(n(n(new Jh(43),xa),Ia),A(wa,xa.c)),A(wa,eb.a))},Da(a,86,2).c=function(Ja,fb){var sb=E(Ja),tb=T(a,Ja,1);if(!tb||!z(Ja,80))return v(t(new Jh(24),K),A(Ja,sb.a));var bb=T(a,Ja,1);return bb?v(n(n(n(new Jh(22),fb),tb),bb),A(Ja,fb.c)):v(t(new Jh(24),K),A(Ja,sb.a))},a}function Zf(a,b,c){for(var d=!0;!O(a,c);){d||z(a,81);var e=y(a),f=T(db,a,1);if(f)n(b,f);else if(n(b,v(t(new Jh(24),K),A(a,e.a))),y(a).b^81&&y(a).b^c)return!1;d=!1}return!0}function _f(a){var b=E(a);a.l=new Vh(3,a.l);var c=Za(a,2);if(!c||!z(a,43)||!z(a, -85))return null;var d=T(db,a,0);return !d||!z(a,89)?null:(Hb(a),Eb(a,b.a,n(n(new Jh(7),c),d)))}function $f(a){var b=E(a),c=a.h;if(a.h|=b.b^44?2048:1024,O(a,83)){var d=new Jh(13);return !fc(a,d,1)||!z(a,87)?null:(a.h=c,v(d,A(a,b.a)))}var e=Za(a,1);return e&&(a.h=c,e)}function bg(a){var b=E(a),c=y(a).a;if(!z(a,96))return null;var d=L(c);if(O(a,83)){a.c.a.has(d)||Na(a.c.a,d,0);var e=new Jh(13);if(!fc(a,e,1)||!z(a,87))return null;for(var f=e.g;f;f=f.k)if(f.b^17)f.e&&(f.e.m=d);else for(var h=f.g.k;h;h=h.k)h.e.m=d;return v(e,A(a,b.a))}if(!bh.has(d)&&!a.c.a.has(d)&&Gf(a.a,c,'The extension "'+d+'" is not in the known list of valid WebGL extensions'),!z(a,80))return null;var m=L(y(a).a);if(!ag.has(m))return Gb(a),null;E(a);var l=ag.get(m);return Na(a.c.a,d,l),Qa(v(_(cc(new Jh(9),d),l),A(a,b.a)),c)}function cg(a){var b=E(a);if(a.l=new Vh(3,a.l),!z(a,85))return null;var c=null;if(!O(a,90)){var d=pe(a),e=hd(a,2),f=null;if(e){if(f=Fb(a,1),!f)return null}else f=Fb(a,0);if(f){if(c=oe(a,b.a,e,f,0,d),!c)return null}else if((c=T(db, -a,0),!c)||!z(a,90))return null}var h=null;if(!O(a,90)&&((h=T(db,a,0),!h)||!z(a,90)))return null;var m=null;if(!O(a,89)&&((m=T(db,a,0),!m)||!z(a,89)))return null;var l=Za(a,2);return l&&(Hb(a),v(ke(c,h,m,l),A(a,b.a)))}function dg(a){var b=E(a);if(!z(a,85))return null;var c=y(a),d=T(db,a,0);if(d||(d=v(t(new Jh(24),K),A(a,c.a))),!z(a,89))return null;var e=Za(a,2);if(!e)return null;var f=null;return O(a,12)&&(f=Za(a,2),!f)?null:v(n(n(n(new Jh(12),d),e),f),A(a,b.a))}function eg(a){var b=E(a),c=y(a).a;return z(a,97)?v(_(new Jh(18),L(c)|0),A(a,b.a)):null}function fg(a){var b=E(a);if(a.l=new Vh(3,a.l),!z(a,85))return null;var c=y(a),d=T(db,a,0);if(d||(d=v(t(new Jh(24),K),A(a,c.a))),!z(a,89))return null;var e=Za(a,2);return e&&(Hb(a),v(n(n(new Jh(19),d),e),A(a,b.a)))}function gg(a){var b=E(a),c=null;if(!O(a,90)){var d=y(a);c=T(db,a,0),c||(c=v(t(new Jh(24),K),A(a,d.a))),z(a,90)}return v(n(new Jh(15),c),A(a,b.a))}function hg(a){var b=E(a),c=0;switch(y(a).b){case 25:c=32;break;case 29:c=64;break;case 16:c=4;break;default: -return Gb(a),null}E(a);var d=Fb(a,1);return d&&Eb(a,b.a,n(_(new Jh(14),c),d))}function ig(a,b,c){var d=y(a).a;if(!z(a,96))return null;var e=new Tb(sc(a.c),d,L(d),new Vh(4,a.l));if(e.e|=a.h|b,e.f=c,!id(a,e))return null;var f=y(a).a,h=new Jh(1),m=null;if(!z(a,83))return null;for(a.l=e.d;y(a).b^87&&y(a).b^99;){var l=Za(a,3);if(!l)return null;if(l.b^17)u(a.a,l.c,'This statement cannot be used inside a struct');else{n(h,l);for(var g=l.g.k;g;g=g.k){var i=g.e;e.g.push(i),N(i)&&u(a.a,N(i).c,'Cannot initialize struct variables')}}}if(Hb(a),!z(a,87))return null;if(v(h,A(a,f)),y(a).b^96)z(a,90);else if(m=te(0,t(new Jh(26),J(e)),E(a).a,a,c),!m)return null;return n(n(Cc(new Jh(16),e),h),m)}function ne(a,b,c){for(var d=!1,e=a.l;e;e=e.b)if(e.a==3){d=!0;break}return d||u(a.a,b,'This statement cannot be used outside a loop'),Eb(a,b,c)}function Eb(a,b,c){return z(a,90),v(c,A(a,b))}function oe(a,b,c,d,e,f){var h=y(a).a;if(!c&&y(a).b^96){var m=ue(db,a,0,d);return m&&Eb(a,b,n(new Jh(8),m))}if(!z(a,96))return null;if(O(a,85))return kg(c, -d,h,a,f);var l=te(c,d,h,a,f);return l&&v(l,A(a,b))}function pe(a){var b=y(a),c=b.c;if(!c)return null;for(var d=b.a.b,e=null,f=c.length-1|0;f>-1;f=f-1|0){for(var h=c[f],m=h.a.b.slice(h.c,d),l=0,g=0;g1)break;(e||(e=[])).push(L(h)),d=h.b}return e&&e.reverse(),e}function Za(a,b){var c=y(a);switch(c.b){case 4:return ne(a,E(a).a,new Jh(4));case 9:return ne(a,E(a).a,new Jh(5));case 10:return Eb(a,E(a).a,new Jh(6));case 11:return _f(a);case 44:case 45:return $f(a);case 91:return bg(a);case 15:return cg(a);case 17:return dg(a);case 83:return re(a);case 31:return hg(a);case 32:return gg(a);case 90:return v(new Jh(3),E(a).a);case 92:return eg(a);case 43:return fg(a)}var d=pe(a),e=hd(a,b),f=null;if(O(a,35)){var h=ig(a,e,d);return h&&v(h,A(a,c.a))}if(e){if(f=Fb(a,1),!f)return null}else f=Fb(a,0);if(f)return oe(a,c.a,e,f,1,d);var m=T(db,a,0);return m&&Eb(a,c.a,n(new Jh(8),m))}function qe(a,b){if(b.b^17&&b.b^16){ -var c=a.l.a==1||a.l.a==4,d=b.b==9||b.b==11||b.b==14||b.b==18;d&&!c?u(a.a,b.c,'This statement cannot be used inside a function'):!d&&c&&u(a.a,b.c,'This statement cannot be used outside a function')}}function jg(a,b){var c=y(a).a;if(!z(a,98))return!1;var d=null;try{d=JSON.parse(L(c))}catch(l){return u(a.a,c,'Invalid string literal'),!1}var e=a.c.b;if(!e)return u(a.a,c,'Cannot include files without access to a file system'),!1;var f=e(d,c.a.a);if(!f)return u(a.a,c,'Cannot read the file '+JSON.stringify(d)),!1;if(a.e.has(f.a))return!0;Na(a.e,f.a,!0),a.f.push(new Lh(c,Cg(f)));var h=Jc(a.a,f,0),m=new Mh(a.a,h,a.c,a.d,a.e);return m.l=a.l,!fc(m,b,1)||!z(m,99)?!1:!0}function re(a){var b=y(a),c=new Jh(3);return a.l=new Vh(2,a.l),!z(a,83)||!fc(a,c,2)||!z(a,87)?null:(Hb(a),v(c,A(a,b.a)))}function hd(a,b){for(var c=0;;){var d=y(a).b;switch(d){case 2:c|=1;break;case 8:c|=2;break;case 16:c|=4;break;case 18:c|=8;break;case 19:c|=16;break;case 25:c|=32;break;case 29:c|=64;break;case 30:c|=128;break;case 37:c|=256;break;case 38: -c|=512;break;default:return c}(!b&&(d==2||d==37||d==38)||b==3&&d^25&&d^29&&d^16||b&&(d==18||d==30||d==19))&&u(a.a,y(a).a,'Cannot use this qualifier here'),E(a)}}function Fb(a,b){var c=y(a),d=null;switch(c.b){case 3:d=Y;break;case 5:d=Lb;break;case 6:d=Mb;break;case 7:d=Nb;break;case 14:d=da;break;case 20:d=ga;break;case 22:d=vb;break;case 23:d=wb;break;case 24:d=xb;break;case 26:d=ob;break;case 27:d=pb;break;case 28:d=qb;break;case 33:d=Lg;break;case 34:d=Mg;break;case 39:d=Fa;break;case 40:d=Ga;break;case 41:d=Ha;break;case 42:d=yd;break;case 96:var e=pd(a.l,L(c.a));if(!e||!(e instanceof Tb))return b^1||Gb(a),null;d=J(e);break;default:return b^1||Gb(a),null}return E(a),v(t(new Jh(26),d),A(a,c.a))}function kg(a,b,c,d,e){var f=d.l,h=new oc(sc(d.c),c,L(c),new Vh(0,f));if(h.e|=d.h|a|(h.c=='main'?1024:0),h.f=e,h.o=b,d.l=h.d,O(d,42)){if(!z(d,89))return null}else if(!O(d,89)){for(;;){var m=hd(d,0),l=Fb(d,1);if(!l)return null;var g=y(d).a;if(!z(d,96))return null;var i=new Ge(sc(d.c),g,L(g),d.l,0);if(i.e|=m,i.p=l,h.i.push(i), -id(d,i),!se(d,i))return null;if(!O(d,81))break}if(!z(d,89))return null}var o=ya(f.c,L(c),null),k=!O(d,90);if(o){if(o instanceof oc){for(var r=o;r;r=r.r)if(Eg(r,h)){r.o.f!=h.o.f?Kf(d.a,h.o.c,h.c,h.o.f,r.o.f,r.o.c):r.k||!k?bd(d.a,h.b,r.b):(r.s=h,h.s=r,h.e|=r.e,r.e=h.e);break}h.r=o,Bg(f,h)}else return bd(d.a,c,o.b),null}else Fe(f,h);if(k){var s=d.h;if(d.h&=-3073,h.k=re(d),d.h&=s,!h.k)return null}return Hb(d),v(Cc(new Jh(11),h),A(d,b.c))}function se(a,b){var c=y(a);if(O(a,84)){if(O(a,88))return u(a.a,A(a,c.a),'All array sizes must be specified'),!0;if(b.B=T(db,a,0),!b.B||!z(a,88))return!1;var d=0;if(X(a.d,b.B),pa(a.d,b.B,ga),b.B.f!=K){var e=G(b.B);if(e){if(e.b==30){var f=e.h|0;f<1?u(a.a,b.B.c,'Cannot declare an array with a size of "'+f+'"'):d=f}}else u(a.a,b.B.c,'This value must be a compile-time constant')}for(;y(a).b==84;){if(c=E(a),y(a).b^88&&!T(db,a,0)||!z(a,88))return!1;u(a.a,A(a,c.a),'Multidimensional arrays are not a part of the language')}b.p=v(t(new Jh(26),Ig(b.p.f,d)),b.p.c)}return!0}function te(a,b,c,d,e){ -for(var f=n(_(new Jh(17),d.h|a),b);;){var h=new Ge(sc(d.c),c,L(c),d.l,d.l.a^1?d.l.a^4?2:3:1);if(h.e|=d.h|a,h.f=e,h.p=b,!se(d,h))return null;var m=y(d).a,l=null;if(O(d,69)){var g=y(d);l=T(db,d,1),l||(l=v(t(new Jh(24),K),A(d,g.a)))}else m=null;var i=Qa(v(n(Cc(new Jh(2),h),l),A(d,h.b)),m);if(h.C=i,h.e&2&&X(d.d,i),n(f,i),id(d,h),!O(d,81))return z(d,90),f;if(c=y(d).a,!z(d,96))return null}}function id(a,b){var c=ya(a.l.c,b.c,null);return c?(bd(a.a,b.b,c.b),!1):(Fe(a.l,b),!0)}function fc(a,b,c){for(;y(a).b^99&&y(a).b^87;){var d=y(a).a;if(O(a,93)){if(c^1)return u(a.a,d,'"#include" statements cannot be used here'),O(a,98),!1;if(!jg(a,b))return!1}else{var e=Za(a,c);if(!e)return!1;if(e.b^13)qe(a,e),n(b,e);else for(;e.g;){var f=q(e.g);qe(a,f),n(b,f)}}}return!0}function jd(a,b,c,d,e,f){db||(db=Yf());var h=new Map,m=new Mh(a,b,d,f,h);return m.l=e,fc(m,c,1)&&z(m,99),new Kh(m.f)}function y(a){return a.b[a.m]}function E(b){var a=y(b);return (b.m+1|0)0?c.m-1|0:0];return b.a.c0?e.b[e.m-1|0]:b).a;return a==90||we(d).a^we(c).a?u(e.a,xe(d),'Expected '+Oe[a]):u(e.a,c,'Expected '+Oe[a]+' but found '+Oe[b.b]),!1}function Gb(a){If(a.a,y(a))}function Hb(a){a.l=a.l.b}function Da(e,a,b){var c=ra(e.a,a,null);if(c)b>c.a&&(c.a=b);else{var d=new Nh(b);c=d,za(e.a,a,d)}return c}function T(f,a,b){var c=y(a),d=ra(f.a,c.b,null);if(!d||!d.b)return Gb(a),null;var e=ue(f,a,b,d.b(a));return e}function ue(f,a,b,c){for(;c;){var d=y(a).b,e=ra(f.a,d,null);if(!e||!e.c||e.a<=b)break;c=e.c(a,c)}return c}function P(d,a,b){Da(d,a,0).b=function(c){return b(c,E(c))}}function Ib(h,a,b,c){Da(h,a,0).b=function(d){var e=E(d),f=T(h,d,b);return f&&c(d,e,f)}}function ve(f,a,b,c){Da(f,a,b).c=function(d,e){return c(d,e,E(d))}}function R(m,a,b,c){Da(m,a,b).c=function(d,e){var f=E(d),h=T(m,d,b);return h&&c(d,e,f,h)}}function ta(m,a,b,c){Da(m,a,b).c=function(d,e){var f=E(d),h=T(m,d,b-1|0);return h&&c(d,e,f,h)}}function L(a){ -return a.a.b.slice(a.b,a.c)}function kd(b){var a=Jb(b.a,b.b);return b.a.a+':'+(a.a+1|0)+':'+(a.b+1|0)}function lg(b,a){return b.a==a.a&&b.b0&&k>a){var r=Math.min(g-l|0,a/2|0),s=Math.max((a-r|0)/2|0,3);if(l(a-3|0)&&(g=a-3|0);else if((k-l|0)<(a-s|0)){var w=k-a|0;d='...'+rc(m.slice(w+3|0,k)),l=l-w|0,g=g-w|0}else{var p=l-s|0;d='...'+rc(m.slice(p+3|0,(p+a|0)-3|0))+'...',l=l-p|0,g=g-p|0,g>(a-3|0)&&(g=a-3|0)}}else d=rc(m);return new Ph(d,Yb(' ',l)+((g-l|0)<2?'^':Yb('~',g-l|0)))}function mg(c,a,b){return new Qh(c.a,c.b+a|0,c.b+b|0)}function we(a){return Jb(a.a,a.b)}function xe(a){return new Qh(a.a,a.c,a.c)}function _a(a,b){return new Qh(a.a,a.b,b.c)}function ng(a){ -var b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'[a%53];for(a=a/53|0;a>0;)a=a-1|0,b+='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789'[a%63],a=a/63|0;return b}function og(o,a){for(var b=0,k=a.length;b=g)&&u(i.a,c.c,'Index "'+l+'" is out of bounds for type "'+D(d)+'"')}}break}a.f==K&&d!=K&&e!=K&&(a.b^43?Qf(i.a,a.d,L(a.d),d,e):u(i.a,a.d,'No index operator for type "'+D(d)+'" and type "'+D(e)+'"'))}function ug(m,a){var b=a.g;X(m,b);for(var c=b.f,d=c.a,e=[],f=!1,h=b.k;h;h=h.k)ja(m, -h),e.push(h),h.f==K&&(f=!0);if(!f){if(d){if(d instanceof oc){wg(m,d,a,e);return}if(d instanceof Tb){xg(m,c,a,e);return}}c!=K&&u(m.a,b.c,'Cannot call type "'+D(c)+'"')}}function vg(m,a){var b=a.g,c=a.m,d=a.d;if(ja(m,b),c!=''){var e=b.f,f=he(a);switch(e){case Lb:case vb:case Fa:case Mb:case wb:case Ga:case Nb:case xb:case Ha:a.f=yg(m,d,e,c,f);break;case K:break;default:if(e.a&&e.a instanceof Tb)for(var l=0,g=e.a.g,i=g.length;l=d&&Lf(w.a,h.c,a,d,f+l|0),ab(m)&&(e=!0),f=f+l|0}var g=ab(a)&&e;g&&c.length^1?u(w.a,b.d,'If a matrix argument is given to a matrix constructor, it is an error to have any other arguments'):f4)return u(l.a,a,'Invalid swizzle "'+c+'" on type "'+D(b)+'"'),K;for(var f=Ea(b),g=0,i=rd(f),o=i.length;g(jc.h|0)):ub.b==29&&jc.b==29&&S(x,a,ub.h>jc.h);break;case 42:var Ka=a.g,Wa=a.i;Ka.b^30?Wa.b^30?Ka.b==30&&Wa.b==30?S(x,a,(Ka.h|0)>=(Wa.h|0)):Ka.b==29&&Wa.b==29&&S(x,a,Ka.h>=Wa.h):(a.b=41,_(Wa,(Wa.h|0)-1|0),x.a=!0):(a.b=41,_(Ka,(Ka.h|0)+1|0),x.a=!0);break;case 43:var pc=a.g,kc=a.i,Oc=pc.f;if(kc.b==30){var Ob=kc.h|0,Pb=0;switch(Oc){case Lb:case vb:case Fa:Pb=2;break;case Mb:case wb:case Ga:Pb=3;break;case Nb:case xb:case Ha: -Pb=4;break}Ob>-1&&Ob=d.d.length)return'';var b=d.d[a],c=(a+1|0)0;){var d=b/2|0,e=c+d|0;h.d[e]<=a?(c=e+1|0,b=(b-d|0)-1|0):b=d}var f=c>0?a-h.d[c-1|0]|0:a;return new Wh(c-1|0,f)}function Kb(d,a,b){if(qd(d),a>-1&&a-1&&(c+b|0)<((a+1|0)64&&r<91||r>96&&r<123||r==95){var s=ya(Gg,g,99);s^99?e.push(new Zh(k, -s,f)):Hg.has(g)?Hf(a,k):e.push(new Zh(k,96,f))}else if(r>47&&r<58||r==46&&i>1)e.push(new Zh(k,gh.test(g)?97:95,f));else if(r^35){if(r^34){var p=ya(hh,g,99);p^99||(g.startsWith('//')?c^1?(f||(f=[])).push(k):p=0:g.startsWith('/*')&&(c^1?(f||(f=[])).push(k):p=1)),p^99&&e.push(new Zh(k,p,f))}else e.push(new Zh(k,98,f))}else{var w=94;switch(g){case'#version':w=92;break;case'#extension':w=91;break;case'#include':w=93;break}e.push(new Zh(k,w,f))}}else if(g!=''){u(a,k,'Syntax error "'+g+'"');break}e.length^h&&(f=null,h=e.length),m=o}return e.push(new Zh(new Qh(b,m,m),99,f)),e}function He(a){return a.b?He(a.b):a}function Ig(c,a){c.f||(c.f=new Map);var b=ra(c.f,a,null);return b||(za(c.f,a,b=new _h(null,c,a)),b.d=!0,b.e=c.e),b}function D(a){return a.b?a.c?D(a.b)+'['+a.c+']':D(a.b)+'[]':a.a.c}function Sa(a){switch(a){case Lb:case Fa:case vb:case ob:return 2;case Mb:case Ga:case wb:case pb:return 3;case Nb:case Ha:case xb:case qb:return 4}return a.c}function vd(a){switch(a){case Lb:case Mb:case Nb:return Y;case Fa:case Ga:case Ha: -return da;case vb:case wb:case xb:return ga;case ob:return Fa;case pb:return Ga;case qb:return Ha}return a.b}function Ea(a){switch(a){case Y:case da:case ga:return 1;case Lb:case Fa:case vb:return 2;case Mb:case Ga:case wb:return 3;case Nb:case Ha:case xb:case ob:return 4;case pb:return 9;case qb:return 16}return 0}function fa(a){switch(a){case Y:case Lb:case Mb:case Nb:return Y;case da:case Fa:case Ga:case Ha:case ob:case pb:case qb:return da;case ga:case vb:case wb:case xb:return ga}return null}function wd(a){switch(a){case Lb:case Mb:case Nb:case vb:case wb:case xb:case Fa:case Ga:case Ha:return!0}return!1}function ab(a){switch(a){case ob:case pb:case qb:return!0}return!1}function Kc(a){switch(a){case ga:case vb:case wb:case xb:return!0}return!1}function Lc(a){switch(a){case da:case Fa:case Ga:case Ha:return!0;case ob:case pb:case qb:return!0}return!1}function Jg(a){return Kc(a)||Lc(a)}function Kg(a){return !a.e&&!a.d}function Ie(a){return a.e=!0,a}function Je(b){var a=b.a.length;return b.a.push(a),a}function xd(c,a,b){ -c.a[Mc(c,a)]=Mc(c,b)}function Mc(c,a){var b=c.a[a];return b^a&&(b=Mc(c,b),c.a[a]=b),b}function qa(a,b){Ke(a),process.stdout.write(b),Ke(0)}function Og(a){qa(3,'error: '),qa(1,a+'\n')}function Pg(a){qa(2,'note: '),qa(1,a+'\n')}function Qg(a){qa(7,'warning: '),qa(1,a+'\n')}function Le(a){for(var b=process.stdout.columns,l=0,g=a.a,i=g.length;l',a)];if(a instanceof Array){for(var b=[],c=0,e=a.length;c27&&a<31}function dd(a){return a>30&&a<38}function Rf(a){return a>30&&a<36}function ed(a){return a>33&&a<38}function Ac(a){return a>37&&a<57}function Bc(a){return a>51&&a<57}function Sf(a){return a==4||a==5||a==6||a==15}function ce(a){return a==7||a==10||a==19}function $a(b){var a='';return b&1&&(a+='attribute '),b&2&&(a+='const '),b&256&&(a+='uniform '),b&512&&(a+='varying '),b&4&&(a+='highp '),b&32&&(a+='lowp '),b&64&&(a+='mediump '),b&8&&(a+='in '),b&16&&(a+='inout '),b&128&&(a+='out '),a}function Fg(a){return a>49&&a<80}function ud(a){switch(a){case 96:case 42:case 33:case 34:case 14:case 39:case 40:case 41:case 20:case 22:case 23:case 24:case 3:case 5:case 6:case 7:case 26:case 27:case 28:return!0}return!1}function Ke(a){process.stdout.isTTY&&process.stdout.write('\x1B[0;'+ih.get(a)+'m')} -function hb(b,a){return b[b.length-1|0]=a}function Rc(a){return a[a.length-1|0]}function Ze(c,a){for(var d=0,e=a.length;db|0)|0}function rc(a){for(var b=new nh,d=0,e=a.length;db|0)|0}function Yb(d,a){for(var b='',c=0;c>10)+55296|0)+String.fromCharCode((a-65536&1023)+56320|0)}function Nc(a){if(!a)return null;var b=a.a,c=Jb(b,a.b),d=Jb(b,a.c);return{source:b.a,start:{line:c.a,column:c.b}, -end:{line:d.a,column:d.b}}}function jh(a,b){b=b||{};var c=Me(a),d=new Ih,e=new th;e.c=ya(Re,b.renaming,0),b.disableRewriting&&(e.a=!1),b.prettyPrint&&(e.b=!1),b.keepSymbols&&(e.d=!1),b.fileAccess&&(e.e=Ne(b.fileAccess));var f=Gd(d,c,e);return{log:Ff(d),output:f?Sc(f,ya(Qe,b.format,0)):null}}function kh(a,b){b=b||{};var c=Me(a),d=new Ih,e=new th;b.fileAccess&&(e.e=Ne(b.fileAccess));var f=_e(d,c,e),h=function(m){for(var Xb,l=m.source+'',g=m.line|0,i=m.column|0,o=!!m.ignoreDiagnostics,k=null,r=null,s=null,zd=0,Ug=c.length;zd>=?|[()[\\]{}\\.,?:;]|[+\\-*/%=!<>&|^~]=?|[A-Za-z_][A-Za-z0-9_]*\\b|#\\w+\\b|"(?:[^"\\\\]|\\\\.)*")'),gh=new RegExp('^([1-9][0-9]*|0[0-7]*|0[xX][0-9A-Fa-f]+)$'),Gg=j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(new Map, -'attribute',2),'bool',3),'break',4),'bvec2',5),'bvec3',6),'bvec4',7),'const',8),'continue',9),'discard',10),'do',11),'else',12),'false',13),'float',14),'for',15),'highp',16),'if',17),'in',18),'inout',19),'int',20),'invariant',21),'ivec2',22),'ivec3',23),'ivec4',24),'lowp',25),'mat2',26),'mat3',27),'mat4',28),'mediump',29),'out',30),'precision',31),'return',32),'sampler2D',33),'samplerCube',34),'struct',35),'true',36),'uniform',37),'varying',38),'vec2',39),'vec3',40),'vec4',41),'void',42),'while',43),'export',44),'import',45),hh=j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(new Map,'~',46),'--',47),'++',48),'!',49),'&',50),'|',51),'^',52),'/',53),'==',54),'>',55),'>=',56),'<',57),'<=',58),'&&',59),'||',60),'^^',61),'-',62),'*',63),'!=',64),'+',65),'%',66),'<<',67),'>>',68),'=',69),'+=',70),'&=',71),'|=',72),'^=',73),'/=',74),'*=',75),'%=',76),'<<=',77),'>>=',78),'-=',79),':',80),',',81),'.',82),'{',83),'[',84),'(',85),'?',86),'}',87),']',88),')',89),';',90),Hg=j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(j(new Map, -'asm',0),'cast',0),'class',0),'default',0),'double',0),'dvec2',0),'dvec3',0),'dvec4',0),'enum',0),'extern',0),'external',0),'fixed',0),'flat',0),'fvec2',0),'fvec3',0),'fvec4',0),'goto',0),'half',0),'hvec2',0),'hvec3',0),'hvec4',0),'inline',0),'input',0),'interface',0),'long',0),'namespace',0),'noinline',0),'output',0),'packed',0),'public',0),'sampler1D',0),'sampler1DShadow',0),'sampler2DRect',0),'sampler2DRectShadow',0),'sampler2DShadow',0),'sampler3D',0),'sampler3DRect',0),'short',0),'sizeof',0),'static',0),'superp',0),'switch',0),'template',0),'this',0),'typedef',0),'union',0),'unsigned',0),'using',0),'volatile',0),Y=J(new Tb(-1,null,'bool',null)),Lb=J(new Tb(-2,null,'bvec2',null)),Mb=J(new Tb(-3,null,'bvec3',null)),Nb=J(new Tb(-4,null,'bvec4',null)),K=J(new Tb(-5,null,'',null)),da=J(new Tb(-6,null,'float',null)),ga=J(new Tb(-7,null,'int',null)),vb=J(new Tb(-8,null,'ivec2',null)),wb=J(new Tb(-9,null,'ivec3',null)),xb=J(new Tb(-10,null,'ivec4',null)),ob=J(new Tb(-11,null,'mat2',null)),pb=J(new Tb(-12,null, -'mat3',null)),qb=J(new Tb(-13,null,'mat4',null)),Lg=Ie(J(new Tb(-14,null,'sampler2D',null))),Mg=Ie(J(new Tb(-15,null,'samplerCube',null))),Fa=J(new Tb(-16,null,'vec2',null)),Ga=J(new Tb(-17,null,'vec3',null)),Ha=J(new Tb(-18,null,'vec4',null)),yd=J(new Tb(-19,null,'void',null)),Ng=[Y,Lb,Mb,Nb,da,ga,vb,wb,xb,ob,pb,qb,Lg,Mg,Fa,Ga,Ha],Qe=j(j(j(j(j(new Map,'json',0),'js',1),'c++',2),'skew',3),'rust',4),Re=j(j(j(new Map,'all',0),'internal-only',1),'none',2),mh=['ERROR','WARNING'],Sg=['GLOBAL','STRUCT_BLOCK','VARIABLE','BLOCK','BREAK','CONTINUE','DISCARD','DO_WHILE','EXPRESSION','EXTENSION','FOR','FUNCTION','IF','MODIFIER_BLOCK','PRECISION','RETURN','STRUCT','VARIABLES','VERSION','WHILE','CALL','DOT','HOOK','NAME','PARSE_ERROR','SEQUENCE','TYPE','UNKNOWN_CONSTANT','BOOL','FLOAT','INT','NEGATIVE','NOT','POSITIVE','PREFIX_DECREMENT','PREFIX_INCREMENT','POSTFIX_DECREMENT','POSTFIX_INCREMENT','ADD','DIVIDE','EQUAL','GREATER_THAN','GREATER_THAN_OR_EQUAL','INDEX','LESS_THAN','LESS_THAN_OR_EQUAL','LOGICAL_AND','LOGICAL_OR', -'LOGICAL_XOR','MULTIPLY','NOT_EQUAL','SUBTRACT','ASSIGN','ASSIGN_ADD','ASSIGN_DIVIDE','ASSIGN_MULTIPLY','ASSIGN_SUBTRACT'],Oe=['SINGLE_LINE_COMMENT','MULTI_LINE_COMMENT','ATTRIBUTE','BOOL','BREAK','BVEC2','BVEC3','BVEC4','CONST','CONTINUE','DISCARD','DO','ELSE','FALSE','FLOAT','FOR','HIGHP','IF','IN','INOUT','INT','INVARIANT','IVEC2','IVEC3','IVEC4','LOWP','MAT2','MAT3','MAT4','MEDIUMP','OUT','PRECISION','RETURN','SAMPLER2D','SAMPLERCUBE','STRUCT','TRUE','UNIFORM','VARYING','VEC2','VEC3','VEC4','VOID','WHILE','EXPORT','IMPORT','COMPLEMENT','DECREMENT','INCREMENT','NOT','BITWISE_AND','BITWISE_OR','BITWISE_XOR','DIVIDE','EQUAL','GREATER_THAN','GREATER_THAN_OR_EQUAL','LESS_THAN','LESS_THAN_OR_EQUAL','LOGICAL_AND','LOGICAL_OR','LOGICAL_XOR','MINUS','MULTIPLY','NOT_EQUAL','PLUS','REMAINDER','SHIFT_LEFT','SHIFT_RIGHT','ASSIGN','ASSIGN_ADD','ASSIGN_BITWISE_AND','ASSIGN_BITWISE_OR','ASSIGN_BITWISE_XOR','ASSIGN_DIVIDE','ASSIGN_MULTIPLY','ASSIGN_REMAINDER','ASSIGN_SHIFT_LEFT','ASSIGN_SHIFT_RIGHT','ASSIGN_SUBTRACT','COLON', -'COMMA','DOT','LEFT_BRACE','LEFT_BRACKET','LEFT_PARENTHESIS','QUESTION','RIGHT_BRACE','RIGHT_BRACKET','RIGHT_PARENTHESIS','SEMICOLON','EXTENSION','VERSION','INCLUDE','PRAGMA','FLOAT_LITERAL','IDENTIFIER','INT_LITERAL','STRING_LITERAL','END_OF_FILE'],ih=Oa(Oa(Oa(Oa(Oa(Oa(Oa(Oa(Oa(new Map,0,0),1,1),2,90),3,31),4,32),5,33),6,34),7,35),8,36);ai()})(); \ No newline at end of file diff --git a/ShaderPlayground/main.ts b/ShaderPlayground/main.ts index 2277e03..b3f1b20 100644 --- a/ShaderPlayground/main.ts +++ b/ShaderPlayground/main.ts @@ -39,7 +39,6 @@ namespace OS { export namespace application { declare var ace: any; declare var THREE: any; - declare var GLSLX:any; class AddTextureDialog extends GUI.BasicDialog { @@ -106,20 +105,32 @@ namespace OS { class ShaderEditor { + static frg_template: string; private ums: any[]; private glsl_values: string[]; private cursors: any[]; private editor: any; private current_idx: number; + private editormux:boolean; + private gl_compiling_ctx: WebGLRenderingContext; renderer: ShaderRenderer; + private tmp_canvas: HTMLCanvasElement; + private _filehandle: API.VFS.BaseFileHandle; + private _onfilechange: (t: string) => void; + private _ontextureadded: (data: GenericObject) => void; constructor(domel: HTMLElement, renderer: ShaderRenderer) { - const empty_main = "void main(){}"; + this.glsl_values = [ShaderEditor.frg_template, ""]; this.renderer = renderer; this.ums = [new ace.UndoManager(), new ace.UndoManager()]; this.current_idx = -1; - this.glsl_values = [empty_main, ""]; + this.tmp_canvas = $("")[0] as HTMLCanvasElement; + this.gl_compiling_ctx = this.tmp_canvas.getContext("webgl"); + this._filehandle = undefined; + this.editormux = false; ace.require("ace/ext/language_tools"); + this._onfilechange = (v) =>{}; + this._ontextureadded = (t) => {}; this.editor = ace.edit(domel); this.editor.setOptions({ enableBasicAutocompletion: true, @@ -136,19 +147,23 @@ namespace OS { this.editor.getCursorPosition(), this.editor.getCursorPosition() ]; + this.editor.on("input", (e) => { const value = this.editor.getValue(); - - const result = GLSLX.compile(value, { - format: "json" - }); - if (result.output) { - this.editor.getSession().setAnnotations([]); - this.glsl_values[this.current_idx] = value; - this.renderer.apply_mat(this.glsl_values[0],this.glsl_values[1]); - } else { - const reg_str = ":([0-9]+):([0-9]+):\\s*error:\\s*(.*)\\n"; - const matches = (result.log as string).match(new RegExp(reg_str, "g")); + const stype = this.current_idx == 0 ? this.gl_compiling_ctx.FRAGMENT_SHADER: this.gl_compiling_ctx.VERTEX_SHADER; + const errors = this.compile(value, stype); + if(this.filehandle.dirty === false && !this.editormux) + { + this.filehandle.dirty = true; + this._onfilechange(`${this.filehandle.path}*`); + } + if(this.editormux) + { + this.editormux = false; + } + if(errors) { + const reg_str = "ERROR:\\s*([0-9]+):([0-9]+):\\s*(.*)\\n"; + const matches = errors.match(new RegExp(reg_str, "g")); if(matches) { this.editor.getSession().setAnnotations( @@ -158,8 +173,8 @@ namespace OS { if(err_data) { ret = { - row: parseInt(err_data[1]) - 1, - column: parseInt(err_data[2]), + row: parseInt(err_data[2]) - 1, + column: 0, text: err_data[3], type: "error" }; @@ -169,9 +184,131 @@ namespace OS { ); } } + else + { + this.editor.getSession().setAnnotations([]); + this.glsl_values[this.current_idx] = value; + this.renderer.apply_mat(this.glsl_values[0], this.glsl_values[1]); + } }); } + public set onfilechange(fn:(v: string) => void) + { + this._onfilechange = fn; + } + + public set ontextureadded(fn:(v:GenericObject)=> void) + { + this._ontextureadded = fn; + } + + public set filehandle(v: API.VFS.BaseFileHandle) + { + this._filehandle = v; + this.read(); + } + + public get filehandle(): API.VFS.BaseFileHandle + { + return this._filehandle; + } + + read() { + return new Promise(async (resolve, reject) => { + if (this._filehandle === undefined) { + this.renderer.textures.length = 0; + this._filehandle = "Untitled".asFileHandle(); + this._onfilechange(this._filehandle.path); + this.glsl_values = [ShaderEditor.frg_template, ""]; + if(this.current_idx != 2 && this.current_idx != -1) + { + this.editormux = true; + this.editor.setValue(this.glsl_values[this.current_idx]); + } + this._ontextureadded(undefined); + return resolve(undefined); + } + try + { + const data = await this._filehandle.read("json"); + this.glsl_values[0] = data.source[0]; + this.glsl_values[1] = data.source[1]; + if(this.current_idx != 2 && this.current_idx != -1) + { + this.editormux = true; + this.editor.setValue(this.glsl_values[this.current_idx]); + } + this._ontextureadded(undefined); + for(const v of data.textures) + { + this._ontextureadded(v); + } + this._onfilechange(this._filehandle.path); + resolve(undefined); + } + catch(e) + { + reject(e); + } + }); + } + + write(p: string) { + return new Promise(async (resolve, reject) => { + let path = p; + const error = __("Unknown save path"); + if(!path) + { + if(this._filehandle === undefined) + return reject(error); + path = this._filehandle.path; + } + if(path === "Untitled") + { + return reject(error); + } + try{ + this._filehandle.setPath(path); + const data = {} as GenericObject; + if(this.current_idx != 2) + { + this.glsl_values[this.current_idx] = this.editor.getValue(); + } + data.source = this.glsl_values; + data.textures = this.renderer.textures.map((v) => { + return { + name: v.name, + path: v.path + }; + }); + this.filehandle.cache = data; + const ret = await this.filehandle.write("object"); + this._filehandle.dirty = false; + this._onfilechange(`${this.filehandle.path}`); + resolve(undefined); + } + catch(e) + { + reject(e); + } + }); + } + + private compile(code: string, type: number) + { + // Compiles either a shader of type gl.VERTEX_SHADER or gl.FRAGMENT_SHADER + let shader = this.gl_compiling_ctx.createShader( type ); + this.gl_compiling_ctx.shaderSource( shader, code ); + this.gl_compiling_ctx.compileShader( shader ); + let errors: string = undefined; + if ( !this.gl_compiling_ctx.getShaderParameter(shader, this.gl_compiling_ctx.COMPILE_STATUS) ) { + errors = this.gl_compiling_ctx.getShaderInfoLog( shader ); + } + this.gl_compiling_ctx.deleteShader(shader); + return errors; + } + edit(index:number): void { if(index < 0) @@ -185,7 +322,7 @@ namespace OS { this.glsl_values[1] = this.editor.getValue(); this.cursors[1] = this.editor.getCursorPosition(); } - else + else if(index === 1) { this.glsl_values[0] = this.editor.getValue(); this.cursors[0] = this.editor.getCursorPosition(); @@ -199,6 +336,7 @@ namespace OS { return; } this.current_idx = index; + this.editormux = true; this.editor.getSession().setUndoManager(new ace.UndoManager()); this.editor.setValue(this.glsl_values[index]); this.editor.getSession().setUndoManager(this.ums[index]); @@ -220,6 +358,7 @@ namespace OS { cleanup(): void { this.renderer.cleanup(); + $(this.tmp_canvas).remove(); } resize(): void { @@ -344,6 +483,19 @@ namespace OS { this.mesh.material = mat; } } + + ShaderEditor.frg_template = `\ +#ifdef GL_ES +precision mediump float; +#endif +// uniform vec2 u_resolution; +// uniform vec2 u_mouse; +uniform float u_time; + +void main() { + gl_FragColor = vec4(abs(sin(u_time)),0.0,0.0,1.0); +}\ + `; /** * * @class ShaderPlayground @@ -355,13 +507,21 @@ namespace OS { */ private tabbar: GUI.tag.TabBarTag; private editor: ShaderEditor; - constructor(args: AppArgumentsType[]) { super("ShaderPlayground", args); } main(): void { this.init_editor(); this.init_textures_list(); + this.bindKey("ALT-N", () => { + return this.newFile(); + }); + this.bindKey("ALT-O", () => { + return this.openFile(); + }); + this.bindKey("CTRL-S", () => { + return this.saveFile(); + }); } /** @@ -394,9 +554,38 @@ namespace OS { this.on("resize", (e) =>{ this.editor.resize(); }); + this.editor.onfilechange = (v: string) => { + (this.scheme as GUI.tag.WindowTag).apptitle = v; + }; + this.editor.ontextureadded = (v: GenericObject) => + { + this.add_texture(v); + } + this.editor.filehandle = undefined; this.tabbar.selected = 0; } + private add_texture(data: GenericObject): void + { + { + const listview = this.find("texture-list") as GUI.tag.ListViewTag; + if(!data) + { + this.editor.renderer.textures = []; + listview.data = this.editor.renderer.textures; + return; + } + const loader = new THREE.TextureLoader(); + const texture = loader.load(data.path.asFileHandle().getlink()); + texture.minFilter = THREE.NearestFilter; + texture.magFilter = THREE.NearestFilter; + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; + data.texture = texture; + listview.push(data); + this.editor.renderer.needupdateTexture = true; + } + } private init_textures_list(): void { const listview = this.find("texture-list") as GUI.tag.ListViewTag; @@ -404,24 +593,10 @@ namespace OS { { text: "__(Add texture)", iconclass: "bi bi-plus", - onbtclick: (e) => { + onbtclick: (_e: any) => { this .openDialog(new AddTextureDialog()) - .then((data) => { - if(!data) - { - return; - } - const loader = new THREE.TextureLoader(); - const texture = loader.load(data.path.asFileHandle().getlink()); - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - data.texture = texture; - listview.push(data); - this.editor.renderer.needupdateTexture = true; - }); + .then((data) => this.add_texture(data)); } } ]; @@ -430,7 +605,7 @@ namespace OS { this.editor.renderer.needupdateTexture = true; return true; }; - listview.data = this.editor.renderer.textures; + this.add_texture(undefined); } private selectTab(): void @@ -449,12 +624,124 @@ namespace OS { this.editor.edit(index); } - protected cleanup(_e: any): void + menu() { + return [ + { + text: "__(File)", + nodes: [ + { + text: "__(New)", + dataid: "new", + shortcut: 'A-N' + }, + { + text: "__(Open)", + dataid: "open", + shortcut: 'A-O' + }, + { + text: "__(Save)", + dataid: "save", + shortcut: 'C-S' + } + ], + onchildselect: (e) => { + switch (e.data.item.data.dataid) { + case "new": + return this.newFile(); + case "open": + return this.openFile(); + case "save": + return this.saveFile(); + } + } + } + ]; + } + + private ignore_unsaved(): Promise { + return new Promise( async (resolve, reject) =>{ + if(this.editor.filehandle.dirty === true) + { + const r = await this.ask({ + title: __("Unsaved shader"), + text: __("Ignore unsaved file?") + }); + if(!r) + { + return resolve(false); + } + return resolve(true); + } + return resolve(true); + }); + } + private async newFile() + { + const ignore = await this.ignore_unsaved(); + if(!ignore) + return; + this.editor.filehandle = undefined; + } + private async openFile() { + try{ + const ignore = await this.ignore_unsaved(); + if(!ignore) + return; + const d = await this.openDialog("FileDialog",{ + title: __("Open file"), + mimes: this.meta().mimes + }); + + this.editor.filehandle.setPath(d.file.path); + await this.editor.read(); + } + catch(e) + { + this.error(__(e.toString()), e); + } + } + + private async saveFile() { + if (this.editor.filehandle.path !== "Untitled") { + return this.editor.write(undefined); + } + const f = await this.openDialog("FileDialog",{ + title: __("Save as"), + file: this.editor.filehandle + }); + let handle = f.file.path.asFileHandle(); + if(f.file.type === "file") { + handle = handle.parent(); + } + try{ + await this.editor.write(`${handle.path}/${f.name}`); + } + catch(e) + { + this.error(__(e.toString()), e); + } + } + + protected cleanup(e: any): void + { + if(this.editor.filehandle.dirty) + { + this.ignore_unsaved() + .then((d) =>{ + if(d) + { + this.editor.filehandle.dirty = false; + this.quit(true); + } + }); + e.preventDefault(); + return; + } this.editor.cleanup(); } } - /** * Application dependenicies preload */ diff --git a/ShaderPlayground/package.json b/ShaderPlayground/package.json index 58426e4..e2b7871 100644 --- a/ShaderPlayground/package.json +++ b/ShaderPlayground/package.json @@ -1,16 +1,42 @@ { "pkgname": "ShaderPlayground", - "app":"ShaderPlayground", - "name":"OpenGL Shader Playground", - "description":"OpenGL Shader Playground", - "info":{ + "app": "ShaderPlayground", + "name": "OpenGL Shader Playground", + "description": "OpenGL Shader Playground", + "info": { "author": "Xuan Sang LE", "email": "mrsang@iohub.dev" }, - "version":"0.0.1-a", - "category":"Development", - "iconclass":"bi bi-lightbulb-fill", - "mimes":["none"], - "dependencies":["libthreejs@0.0.129-r"], - "locale": {} + "version": "0.0.2-a", + "category": "Development", + "iconclass": "bi bi-lightbulb-fill", + "mimes": [ + "application/json" + ], + "dependencies": [ + "libthreejs@0.0.129-r" + ], + "locale": {}, + "locales": { + "en_GB": { + "Name": "Name", + "Path/URL": "Path/URL", + "Ok": "Ok", + "Add texture": "Add texture", + "File": "File", + "New": "New", + "Open": "Open", + "Save": "Save", + "All fields should be filled": "All fields should be filled", + "Select image file": "Select image file", + "Unknown save path": "Unknown save path", + "Fragment": "Fragment", + "Vertex": "Vertex", + "Textures": "Textures", + "Unsaved shader": "Unsaved shader", + "Ignore unsaved file?": "Ignore unsaved file?", + "Open file": "Open file", + "Save as": "Save as" + } + } } \ No newline at end of file diff --git a/packages.json b/packages.json index 0ddfd8e..facb5f4 100644 --- a/packages.json +++ b/packages.json @@ -335,7 +335,7 @@ "description": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ShaderPlayground/README.md", "category": "Development", "author": "Xuan Sang LE", - "version": "0.0.1-a", + "version": "0.0.2-a", "dependencies": ["libthreejs@0.0.129-r"], "download": "https://raw.githubusercontent.com/lxsang/antosdk-apps/master/ShaderPlayground/build/release/ShaderPlayground.zip" },