PageSourceSearch

https://marbrasil.tv.br/site/wp-content/themes/levelup/assets/js/fx/glitch.js?ver=1.1.38

js marbrasil.tv.br collected 2026-10-04 06:02:54 UTC 41,152 bytes, 1,214 lines download raw bytes

1
2// A very lightweight layer on top of the WebGL API to make coding WebGL faster and much more fun.
3//
4// This isn't a 3D engine, but could be used as the foundation for one.
5
6/*!
7 @copyright 2016 Justin Windle
8 @license http://opensource.org/licenses/MIT
9 @author Justin Windle <[email protected]>
10 @see https://github.com/soulwire/gl.js
11 @see http://soulwire.co.uk
12 */
13
14var GL = (function() {
15
16    'use strict';
17
18    var GL = {
19
20        //
21        // Create
22        // --------------------------------------------------
23        //
24        // Creates a WebGL drawing context and augments it
25        // to add the functionality of the __gl.js__ library
26        //
27        // Parameters:
28        //  - `canvas` _(optional)_ The canvas element to use
29        //
30
31        create: function( canvas ) {
32
33            var gl;
34
35            if ( !canvas ) canvas = document.createElement( 'canvas' );
36
37            if ( !( gl = ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ) ) )
38
39                throw 'Error creating WebGL context';
40
41            var shader, bindings = {};
42
43            return extend( gl, {
44
45                bindings: bindings,
46
47                //
48                // Shader
49                // --------------------------------------------------
50                //
51                // Creates a shader object from a given type and source code
52                //
53                // Parameters:
54                //  - `source` Source string for the shader
55                //  - `type` The shader type (`VERTEX_SHADER` or `FRAGMENT_SHADER`)
56                //
57
58                shader: function( source, type ) {
59
60                    source = PRECISION + '\n' + source;
61
62                    gl.shaderSource( shader = gl.createShader( type ), source );
63                    gl.compileShader( shader );
64
65                    if ( !gl.getShaderParameter( shader, COMPILE_STATUS ) )
66
67                        logShaderError( gl.getShaderInfoLog( shader ), source );
68
69                    return shader;
70                },
71
72                //
73                // Program
74                // --------------------------------------------------
75                //
76                // Creates a shader program from _vertex_ and _fragment_
77                // shader source code
78                //
79                // Parameters:
80                //  - `vs` Source string for the vertex shader
81                //  - `fs` Source string for the fragment shader
82                //
83
84                program: function( vs, fs ) {
85
86                    var attribute, program, uniform, source, name, type, size, span,
87
88                        program = gl.createProgram();
89                    program.state = {};
90
91                    gl.attachShader( program, gl.shader( vs, VERTEX_SHADER ) );
92                    gl.attachShader( program, gl.shader( fs, FRAGMENT_SHADER ) );
93                    gl.linkProgram( program );
94
95                    if ( !gl.getProgramParameter( program, LINK_STATUS ) )
96
97                        throw gl.getProgramInfoLog( program );
98
99                    /*
100
101                     Concatenates vertex and fragment shader source code
102                     and strips out comments, ready to be parsed for
103                     attributes and uniforms
104
105                     */
106
107                    source = [ vs, fs ].join( '\n' ).replace( COMMENT, '' );
108
109                    /*
110
111                     Parse attributes in the shader code, create `attribute`
112                     objects for each and store them in the program
113
114                     */
115
116                    while ( attribute = ATTRIBUTE.exec( source ) ) {
117
118                        type = attribute[1];
119                        name = attribute[2];
120
121                        if ( !program[ name ] )
122
123                            program[ name ] = gl.attribute( program, name, type );
124                    }
125
126                    /*
127
128                     Parse uniforms in the shader code, create `uniform`
129                     objects for each and store them in the program
130
131                     */
132
133                    while ( uniform = UNIFORM.exec( source ) ) {
134
135                        type = uniform[1];
136                        name = uniform[2];
137                        span = uniform[5];
138
139                        if ( !program[ name ] )
140
141                            program[ name ] = gl.uniform( program, name, type, span );
142                    }
143
144                    /* Extends the core program functionalty */
145
146                    return extend( program, {
147
148                        // ##### on
149                        // Tells WebGL to start using this program
150
151                        on: function() {
152
153                            if ( gl.usedProgram !== program )
154
155                                gl.useProgram( gl.usedProgram = program );
156                        },
157
158                        // ##### draw
159                        // Draw a `mesh` object using this program
160                        //
161                        // Parameters
162                        //  - `mesh` The `mesh` object to draw
163                        //  - `mode` _(optional)_ The drawing mode to use (if not `mesh.mode`)
164                        //  - `first` _(optional)_ The index to start drawing from
165                        //  - `count` _(optional)_ How many items to draw
166
167                        draw: function( mesh, mode, first, count ) {
168
169                            program.on();
170
171                            var key, val, obj, unit = 0;
172
173                            /* Attributes */
174
175                            for ( key in obj = mesh.attributes )
176
177                                if ( program[ key ] )
178
179                                    obj[ key ].on( program[ key ] );
180
181                            /* Uniforms */
182
183                            for ( key in obj = mesh.uniforms )
184
185                                if ( program[ key ] )
186
187                                    program[ key ].set( obj[ key ] );
188
189                            /* Textures */
190
191                            for ( key in obj = mesh.textures )
192
193                                if ( program[ key ] )
194
195                                    obj[ key ].on( unit ), program[ key ].set( unit++ );
196
197                            /* Vertices */
198
199                            for ( key in obj = mesh.vertices )
200
201                                ( val = obj[ key ] ).on( program[ key ] );
202
203                            /* Draw */
204
205                            if ( mesh.indices ) {
206
207                                mesh.indices.on();
208                                gl.drawElements( TRIANGLES, mesh.indices.length, UNSIGNED_SHORT, 0 );
209
210                            } else {
211
212                                gl.drawArrays(
213                                    mode  || mesh.mode,
214                                    first || 0,
215                                    count || ( val.length / program[ key ].size )
216                                );
217                            }
218                        }
219                    });
220                },
221
222                //
223                // Attribute
224                // --------------------------------------------------
225                //
226                // Creates an object that encapsulates a vertex shader
227                // attribute and provides methods for using it
228                //
229                // Parameters:
230                //  - `program` The `program` object the attribute belongs to
231                //  - `name` The name of the attribute (usually prefixed with _a_)
232                //  - `type` The type of object used for this attribute (e.g. _vec3_)
233                //
234
235                attribute: function( program, name, type ) {
236
237                    var location = gl.getAttribLocation( program, name );
238                    var dataType = getType( type );
239                    var size = getSize( type );
240                    var on = false;
241
242                    return {
243
244                        name: name,
245                        type: type,
246                        size: size,
247                        dataType: dataType,
248                        location: location,
249
250                        // ##### on
251                        // Enable the attribute and setup pointers
252
253                        on: function() {
254
255                            if ( !on ) gl.enableVertexAttribArray( location );
256                            gl.vertexAttribPointer( location, size, dataType, false, 0, 0 );
257                            on = true;
258                        },
259
260                        // ##### off
261                        // Disable the attribute
262
263                        off: function() {
264
265                            gl.disableVertexAttribArray( location );
266                        }
267                    };
268                },
269
270                //
271                // Uniform
272                // --------------------------------------------------
273                //
274                // Creates an object that encapsulates a program
275                // uniform and provides methods for using it
276                //
277                // Parameters:
278                //  - `program` The `program` object the uniform belongs to
279                //  - `name` The name of the uniform (usually prefixed with _u_)
280                //  - `type` The type of object used for this uniform (e.g. _vec3_)
281                //  - `span` _(optional)_ The length of this uniform if it's an array
282                //
283
284                uniform: function( program, name, type, span ) {
285
286                    var location = gl.getUniformLocation( program, name );
287                    var setter = gl[ uniformMethod( type, span ) ];
288                    var state = program.state;
289
290                    return {
291
292                        name: name,
293                        type: type,
294                        span: span || 1,
295                        location: location,
296                        setter: setter,
297
298                        // ##### get
299                        // Returns the current value of the uniform
300
301                        get: function() {
302
303                            return gl.getUniform( program, location );
304                        },
305
306                        // ##### set
307                        // Sets the current value of the uniform
308
309                        set: function( value ) {
310
311                            if ( state[ name ] !== value ) {
312
313                                program.on();
314                                setter.apply( gl, [ location ].concat( state[ name ] = value ) );
315                            }
316                        }
317                    };
318                },
319
320                //
321                // Buffer
322                // --------------------------------------------------
323                //
324                // Creates a buffer object to use for attributes or indices
325                //
326                // Parameters:
327                //  - `type` The type of buffer (`ARRAY_BUFFER` or `ELEMENT_ARRAY_BUFFER`)
328                //  - `data` _(optional)_ The initial data to fill the buffer with
329                //
330
331                buffer: function( type, data ) {
332
333                    var ArrayType = type === ARRAY_BUFFER ? Float32Array : Uint16Array;
334                    var buffer = gl.createBuffer();
335
336                    extend( buffer, {
337
338                        // ##### length
339                        // The current length of the buffer
340
341                        length: 0,
342
343                        // ##### on
344                        // Binds the buffer to the appropriate bind point and
345                        // enables the attribute for the buffer
346                        //
347                        // Parameters
348                        //  - `attribute` The attribute that this buffer is for
349
350                        on: function( attribute ) {
351
352                            if ( bindings[ type ] !== buffer ) {
353
354                                gl.bindBuffer( type, bindings[ type ] = buffer );
355                                if ( attribute ) attribute.on();
356                            }
357                        },
358
359                        // ##### fill
360                        // Fills the buffer with data
361                        //
362                        // Parameters
363                        //  - `data` The data to fill the buffer with
364                        //  - `usage` _(optional)_ How the buffer will be used (defaults to `STATIC_DRAW`)
365
366                        fill: function( data, usage ) {
367
368                            if ( toType( data ) == 'array' ) data = new ArrayType( data );
369
370                            gl.bindBuffer( type, buffer );
371                            gl.bufferData( type, data, usage || STATIC_DRAW );
372
373                            buffer.length = data.length;
374                        },
375
376                        // ##### push
377                        // Pushes data into the buffer at a given offset
378                        //
379                        // Parameters
380                        //  - `data` The data to push into the buffer
381                        //  - `offset` The point at which to start pushing in data
382
383                        push: function( data, offset ) {
384
385                            if ( isArray( data ) ) data = new ArrayType( data );
386
387                            gl.bindBuffer( type, buffer );
388                            gl.bufferSubData( type, offset, data );
389                        }
390                    });
391
392                    if ( data ) buffer.fill( data );
393
394                    return buffer;
395                },
396
397                //
398                // VBO
399                // --------------------------------------------------
400                //
401                // Creates a vertex buffer for sending attributes to a vertex shader
402                // (internally this calls `gl.buffer` with type `ARRAY_BUFFER`)
403                //
404                // Parameters:
405                //  - `data` _(optional)_ The initial data to fill the buffer with
406                //
407
408                vbo: function( data ) {
409
410                    return gl.buffer( ARRAY_BUFFER, data );
411                },
412
413                //
414                // IBO
415                // --------------------------------------------------
416                //
417                // Creates a buffer for specifying vertex indices (internally
418                // this calls `gl.buffer` with type `ELEMENT_ARRAY_BUFFER`)
419                //
420                // Parameters:
421                //  - `data` _(optional)_ The initial data to fill the buffer with
422                //
423
424                ibo: function( data ) {
425
426                    return gl.buffer( ELEMENT_ARRAY_BUFFER, data );
427                },
428
429                //
430                // FBO
431                // --------------------------------------------------
432                //
433                // Creates a frame buffer object that can be used as an
434                // alternative rendering target
435                //
436                // Parameters:
437                //  - `width` _(optional)_ The initial width of the frame buffer
438                //  - `height` _(optional)_ The initial height of the frame buffer
439                //  - `data` _(optional)_ The initial texture data
440                //
441                // TODO:
442                //  - Add support for `renderBuffers`
443                //
444
445                fbo: function( width, height, data, options ) {
446
447                    var fbo = gl.createFramebuffer();
448                    var tex = gl.texture();
449
450                    extend( fbo, {
451
452                        // ##### texture
453                        // The texture object that the frame buffer renders to
454
455                        texture: tex,
456
457                        // ##### set
458                        // Sets up the frame buffer with optional data and dimensions
459                        //
460                        // Parameters:
461                        //  - `data` _(optional)_ Image data for the frame buffer
462                        //  - `width` _(optional)_ The initial width of the frame buffer
463                        //  - `height` _(optional)_ The initial height of the frame buffer
464
465                        set: function( data, width, height, options ) {
466
467                            fbo.on();
468                            tex.set( data, fbo.width = width, fbo.height = height, options );
469                            gl.framebufferTexture2D( FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_2D, tex, 0 );
470                            fbo.off();
471                        },
472
473                        // ##### on
474                        // Binds the frame buffer to use as an off screen rendering target
475
476                        on: function() {
477
478                            gl.bindFramebuffer( FRAMEBUFFER, fbo );
479                        },
480
481                        // ##### off
482                        // Unbinds the frame buffer, re-enabling the default render target
483
484                        off: function() {
485
486                            gl.bindFramebuffer( FRAMEBUFFER, null );
487                        }
488                    });
489
490                    fbo.set( data, width || 1, height || 1, options );
491
492                    return fbo;
493                },
494
495                //
496                // Texture
497                // --------------------------------------------------
498                //
499                // Creates a texture object
500                //
501                // Parameters:
502                //  - `source` _(optional)_ The initial source data for the texture.
503                //  Possible values are:
504                //   - `string` (path to an image file)
505                //   - `ArrayBufferView` _(pixels)_
506                //   - `ImageData` _(pixels)_
507                //   - `HTMLImageElement` _(May throw DOMException)_
508                //   - `HTMLCanvasElement` _(May throw DOMException)_
509                //   - `HTMLVideoElement` _(May throw DOMException)_
510                //  - `width` _(optional)_ Width of the texture, if not one of the above types
511                //  - `height` _(optional)_ Height of the texture, if not one of the above types
512                //  - `options` _(optional)_ Options to use during `setup`
513                //
514                // TODO:
515                //  - Auto convert arrays to typed
516                //
517
518                texture: function( source, width, height, options ) {
519
520                    var texture = gl.createTexture();
521                    var content;
522                    var pot;
523
524                    if ( typeof width == 'object' )
525
526                        options = width;
527
528                    extend( texture, {
529
530                        // ##### param
531                        // Sets a parameter for this texture (for example `TEXTURE_MIN_FILTER`)
532                        //
533                        // Parameters:
534                        //  - `name` The name of the parameter to set (e.g. `TEXTURE_MIN_FILTER`)
535                        //  - `value` The value for the parameter (e.g. `LINEAR`)
536
537                        param: function( name, value ) {
538
539                            gl.texParameteri( TEXTURE_2D, name, value );
540                        },
541
542                        // ##### setup
543                        // Sets up the texture by configuring several parameters and generates
544                        // mipmaps if appropriate
545                        //
546                        // Parameters:
547                        //  - `options` _(optional)_ An object c
547ontaining parameter names and their values
548                        //  Possible keys are:
549                        //   - `min` How to resample when shrinking
550                        //   - `mag` How to resample when stretching
551                        //   - `s` Whether to clamp or repeat on the _s_ (_x_) axis
552                        //   - `t` Whether to clamp or repeat on the _t_ (_y_) axis
553
554                        setup: function( options ) {
555
556                            options = extend( options || {}, {
557                                min: LINEAR,
558                                mag: LINEAR,
559                                s: CLAMP_TO_EDGE,
560                                t: CLAMP_TO_EDGE
561                            });
562
563                            texture.on();
564
565                            texture.param( TEXTURE_MAG_FILTER, options.mag );
566                            texture.param( TEXTURE_MIN_FILTER, options.min );
567                            texture.param( TEXTURE_WRAP_S, options.s );
568                            texture.param( TEXTURE_WRAP_T, options.t );
569
570                            if ( options.mipmap ) gl.generateMipmap( TEXTURE_2D );
571
572                            texture.off();
573                        },
574
575                        // ##### on
576                        // Binds the texture and if `unit` is specified, tells WebGL to
577                        // use this texture as the texture at the given unit, which will
578                        // correspond to a shader uniform
579                        //
580                        // Parameters:
581                        //  - `unit` _(optional)_ The unit to activate this texture for
582
583                        on: function( unit ) {
584
585                            if ( exists( unit ) ) gl.activeTexture( TEXTURE0 + unit );
586                            gl.bindTexture( TEXTURE_2D, texture );
587                        },
588
589                        // ##### off
590                        // Unbinds this texture
591
592                        off: function() {
593
594                            gl.bindTexture( TEXTURE_2D, null );
595                        },
596
597                        // ##### set
598                        // Populates this texture object with data of one of the supported
599                        // types (see the constructor's `source` parameter above)
600                        //
601                        // Parameters:
602                        //  - `data` _(optional)_ The data to populate the texture with
603                        //  - `width` _(optional)_ The width of the texture
604                        //  - `height` _(optional)_ The height of the texture
605
606                        set: function( data, width, height, options ) {
607
608                            options = extend( options || {}, {
609                                mipmap: pot = width > 1 && height > 1 && isPowerOf2( width ) && isPowerOf2( height ),
610                                format: RGBA,
611                                min: pot ? LINEAR_MIPMAP_LINEAR : LINEAR,
612                                flip: true
613                            });
614
615                            var path = typeof data === 'string';
616
617                            if ( path || !data && !width && !height ) {
618
619                                texture.set( EMPTY_PIXEL, 1, 1 );
620
621                                if ( path )
622
623                                    loadImage( data, texture.set );
624
625                                return;
626                            }
627
628                            var type = /^float/i.test( toType( data ) ) ? FLOAT : UNSIGNED_BYTE;
629
630                            texture.on();
631
632                            gl.pixelStorei( UNPACK_FLIP_Y_WEBGL, options.flip );
633
634                            if ( width && height )
635
636                                gl.texImage2D( TEXTURE_2D, 0, options.format, width, height, 0, options.format, type, data );
637
638                            else
639
640                                gl.texImage2D( TEXTURE_2D, 0, options.format, options.format, UNSIGNED_BYTE, data );
641
642                            if ( data !== content )
643
644                                texture.setup( options );
645
646                            content = data;
647
648                            texture.off();
649                        }
650                    });
651
652                    texture.set( source, width, height, options );
653
654                    return texture;
655                },
656
657                //
658                // Size
659                // --------------------------------------------------
660                //
661                // Resizes the canvas and viewport
662                //
663                // Parameters:
664                //  - `width` The desired width
665                //  - `height` The desired height
666                //
667
668                size: function( width, height ) {
669
670                    gl.viewport( 0, 0, width, height );
671                    gl.height = canvas.height = height;
672                    gl.width = canvas.width = width;
673                },
674
675                //
676                // Mesh
677                // --------------------------------------------------
678                //
679                // Creates a mesh object that encapsulates the properties
680                // needed to render a mesh and can be given to a `program`
681                // to draw
682                //
683                // Parameters:
684                //  - `options` The properties to initialise the mesh with
685                //   - `mode` The default drawing mode to use
686                //   - `attributes` Names attribute keys and buffer their values
687                //   - `uniforms` A hash of uniforms and their initial values
688                //   - `textures` Texture uniform keys and corresponding textures
689                //   - `textures` Texture uniform keys and corresponding textures
690                //   - `textures` Texture uniform keys and corresponding textures
691                //
692                // Example:
693                //
694                //     var quad = gl.mesh({
695                //         uniforms: {
696                //             uTime: 0
697                //         },
698                //         textures: {
699                //             uTexture: gl.texture( 'some-image.png' )
700                //         },
701                //         vertices: {
702                //             aPosition: gl.vbo([ -1, 1, 1, 1, -1, -1, 1, -1 ])
703                //         },
704                //         attributes: {
705                //             aTexCoord: gl.vbo([ 0, 1, 1, 1, 0, 0, 1, 0 ])
706                //         },
707                //         indices: gl.ibo([ 0, 1, 3, 3, 1, 2 ])
708                //     });
709                //
710                //     program.draw( quad );
711                //
712
713                mesh: function( options ) {
714
715                    var mesh = extend( options || {}, {
716
717                        mode: TRIANGLE_STRIP,
718                        attributes: {},
719                        uniforms: {},
720                        textures: {},
721                        indices: null,
722                        vertices: { /* programAttributeName: VBO */ }
723                    });
724
725                    return mesh;
726                }
727            });
728        }
729    };
730
731    //
732    // Internal
733    // --------------------------------------------------
734    //
735    // Constants and helper methods, not exposed via the API
736    //
737
738    var EMPTY_PIXEL = new Uint8Array([ 0, 0, 0, 0 ]);
739    var PRECISION = '#ifdef GL_ES\nprecision mediump float;\n#endif';
740    var ATTRIBUTE = /attribute\s+(\w+)\s+([\w_-]+)/gi;
741    var UNIFORM = /uniform\s+(\w+)\s+([\w_-]+)(\[(\s+)?([\w_-]+))?/gi;
742    var COMMENT = /(\/\/.+|\/\*[^(\*\/)]+\*\/)/i;
743
744    /*
745
746     Enumeration
747
748     */
749
750    var ELEMENT_ARRAY_BUFFER = 34963;
751    var LINEAR_MIPMAP_LINEAR = 9987;
752    var UNPACK_FLIP_Y_WEBGL = 37440;
753    var TEXTURE_MAG_FILTER = 10240;
754    var TEXTURE_MIN_FILTER = 10241;
755    var COLOR_ATTACHMENT0 = 36064;
756    var FRAGMENT_SHADER = 35632;
757    var COMPILE_STATUS = 35713;
758    var UNSIGNED_SHORT = 5123;
759    var TEXTURE_WRAP_S = 10242;
760    var TEXTURE_WRAP_T = 10243;
761    var TRIANGLE_STRIP = 5;
762    var CLAMP_TO_EDGE = 33071;
763    var UNSIGNED_BYTE = 5121;
764    var VERTEX_SHADER = 35633;
765    var ARRAY_BUFFER = 34962;
766    var FRAMEBUFFER = 36160;
767    var STATIC_DRAW = 35044;
768    var LINK_STATUS = 35714;
769    var TEXTURE_2D = 3553;
770    var TRIANGLES = 4;
771    var TEXTURE0 = 33984;
772    var NEAREST = 9728;
773    var LINEAR = 9729;
774    var FLOAT = 5126;
775    var RGBA = 6408;
776    var INT = 5124;
777
778    /*
779
780     Utils
781
782     */
783
784    var define = Object.defineProperty;
785
786    /*
787
788     Merge properties of `source` into `target`
789
790     */
791
792    function extend( target, source, overwrite ) {
793
794        for ( var key in source )
795
796            if ( overwrite || ( !( key in target ) || !exists( target[ key ] ) ) )
797
798                target[ key ] = source[ key ];
799
800        return target;
801    }
802
803    /*
804
805     Checks whether an object has been defined
806
807     */
808
809    function exists( object ) {
810
811        return object != null;
812    }
813
814    /*
815
816     Checks whether a number is power of two
817
818     */
819
820    function isPowerOf2( value ) {
821
822        return ( value & ( value - 1 ) ) === 0;
823    }
824
825    /*
826
827     Load an image from a given path and fire a callback when ready
828
829     */
830
831    function loadImage( path, callback ) {
832
833        var image = new Image();
834        image.onload = function() { callback( image ); };
835        image.src = path;
836    }
837
838    /*
839
840     Returns the name of the uniform setter method for a uniform type,
841     for example a type of `vec2` would yield `uniform2f`
842
843     */
844
845    function uniformMethod( type, span ) {
846
847        return 'uniform{m}{d}{t}{a}'
848
849            .replace( '{m}', /mat/i.test( type ) ? 'Matrix' : '' )
850            .replace( '{d}', /\d$/.test( type ) ? type.match( /\d$/ )[0] : 1 )
851            .replace( '{t}', /^[bis]/i.test( type ) ? 'i' : 'f' )
852            .replace( '{a}', span > 0 ? 'v' : '' );
853    }
854
855    /*
856
857     Returns the size (number of dimensions) of an object type
858
859     */
860
861    function getSize( type ) {
862
863        return /\d/.test( type ) ? parseInt( type.match( /\d$/ )[0], 10 ) : 1;
864    }
865
866    /*
867
868     Returns the WebGL datatype of an object type (e.g vec3 -> gl.FLOAT)
869
870     */
871
872    function getType( type ) {
873
874        return /^[bi]/i.test( type ) ? INT : FLOAT;
875    }
876
877    /*
878
879     Returns a string representing the type of object provided
880     @see http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
881
882     */
883
884    function toType( obj ) {
885
886        return ({}).toString.call( obj ).match( /\s([a-zA-Z0-9]+)/ )[1].toLowerCase();
887    }
888
889    /*
890
891     Highlights GLSL code and the location of an error therein
892
893     */
894
895    function logShaderError( error, source ) {
896
897        var line = /\d+:(\d+)/g.exec( error );
898
899        if ( line ) {
900
901            line = parseInt( line[1], 10 ) - 1;
902            source = source.split( '\n' );
903
904            console.log(
905
906                '%c' + source.splice( 0, line ).join( '\n' ) +
907                '%c' + '\n' + source[ 0 ] + '\n' +
908                '%c' + source.splice( 1 ).join( '\n' ),
909
910                'color: #ccc',
911                'color: red',
912                'color: #ccc'
913            );
914        }
915
916        throw error;
917    }
918
919    // ##### Finally, return the API
920
921    return GL;
922
923})();
924
925
926
927var Shaders = Shaders || {};
928Shaders.Glitch = {};
929
930Shaders.Glitch.VertexShader = [
931    'attribute vec2 aPosition;',
932    'attribute vec2 aTexCoord;',
933    'varying vec2 vTexCoord;',
934    'void main() {',
935    'gl_Position = vec4( aPosition, 0, 1 );',
936    'vTexCoord = aTexCoord;',
937    '}'
938].join('\n');
939
940Shaders.Glitch.FragmentShader = [
941    'uniform sampler2D uTexture;',
942    'uniform sampler2D uOffsets;',
943    'varying vec2 vTexCoord;',
944
945    'uniform int uSkip;',
946    'uniform float uAmount;',
947    'uniform float uAngle;',
948    'uniform float uSeed;',
949    'uniform float uSeedX;',
950    'uniform float uSeedY;',
951    'uniform float uDistortionX;',
952    'uniform float uDistortionY;',
953    'uniform float uColS;',
954
955    'float rand(vec2 co){',
956    'return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);',
957    '}',
958
959    'void main() {',
960    'vec4 texel = texture2D( uTexture, vTexCoord );',
961    'gl_FragColor = texel;',
962
963    'if (uSkip < 1) {',
964    'vec2 p = vTexCoord;',
965    'float xs = floor(gl_FragCoord.x / 0.5);',
966    'float ys = floor(gl_FragCoord.y / 0.5);',
967    '//based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch',
968    'vec4 normal = texture2D(uOffsets, p * uSeed * uSeed);',
969    'if (p.y < uDistortionX + uColS && p.y > uDistortionX - uColS * uSeed) {',
970    'if(uSeedX > 0.0){',
971    'p.y = 1.0 - (p.y + uDistortionY);',
972    '}',
973    'else {',
974    'p.y = uDistortionY;',
975    '}',
976    '}',
977    'if (p.x < uDistortionY + uColS && p.x > uDistortionY - uColS * uSeed) {',
978    'if (uSeedY > 0.0){',
979    'p.x = uDistortionX;',
980    '}',
981    'else {',
982    'p.x = 1. - (p.x + uDistortionX);',
983    '}',
984    '}',
985    'p.x += normal.x * uSeedX * (uSeed /5.0);',
986    'p.y += normal.y * uSeedY * (uSeed /5.0);',
987    '//base from RGB shift shader',
988    'vec2 offset = uAmount * vec2( cos(uAngle), sin(uAngle) );',
989    'vec4 cr = texture2D(uTexture, p + offset);',
990    'vec4 cga = texture2D(uTexture, p);',
991    'vec4 cb = texture2D(uTexture, p - offset);',
992    'gl_FragColor = vec4(cr.r, cga.g, cb.b, cga.a);',
993    '}',
994    'else {',
995    'gl_FragColor = texture2D(uTexture, vTexCoord);',
996    '}',
997    '}',
998].join('\n');
999
1000
1001
1002function GlitchFx() {
1003    this.domElement = document.createElement('div');
1004    this.domElement.className = 'glitch';
1005    this.bindMethods();
1006    this.setupContext();
1007    this.render();
1008    this.enabled = true;
1009    this.glitchFrames = 0;
1010    this.glitching = false;
1011    // GlitchFx settings...
1012    // Chance of switching glitch effect on when off.
1013    this.onProbability = 0.005;
1014    // Chance of switching glitch effect off when on.
1015    this.offProbability = 0.2;
1016    // Minimum frames to glitch for.
1017    this.minGlitchedFrames = 5;
1018    // Maximum frames to glitch for.
1019    this.maxGlitchedFrames = 30;
1020    // Chance of updating distortion values.
1021    this.distortionProbability = 0.35;
1022    // Maximum seed value (signed, e.g. between -n and n)
1023    this.maxSeedValue = 0.2;
1024    // Maximum distortion.
1025    this.maxDistortion = 0.2;
1026    // Smoothing applied to random values of `uAmount` uniform.
1027    this.strengthDivisor = 60;
1028}
1029
1030GlitchFx.prototype.enable = function() {
1031    this.enabled = true;
1032}
1033
1034GlitchFx.prototype.disable = function() {
1035    if (this.enabled) {
1036        this.enabled = false;
1037        this.updateProgramUniforms();
1038        this.program.draw(this.mesh);
1039    }
1040}
1041
1042GlitchFx.prototype.bindMethods = function() {
1043    this.onImageLoaded = this.onImageLoaded.bind(this);
1044    this.resize = this.resize.bind(this);
1045    this.render = this.render.bind(this);
1046}
1047
1048GlitchFx.prototype.setupContext = function() {
1049    try {
1050        // Attempt to create a GL context.
1051        this.canvas = document.createElement('canvas');
1052        this.context = GL.create(this.canvas);
1053        this.domElement.appendChild(this.canvas);
1054        this.hasWebGL = true;
1055    } catch (error) {
1056        this.hasWebGL = false;
1057    }
1058    if (this.hasWebGL) {
1059        // We can't use background cover, so compute manually on resize.
1060        window.addEventListener('resize', this.resize, false);
1061        // If WebGL is supported, set up the context.
1062        this.enableWebGLExtensions();
1063        this.program = this.context.program(
1064            Shaders.Glitch.VertexShader,
1065            Shaders.Glitch.FragmentShader
1066        );
1067        this.texture = this.context.texture();
1068        this.mesh = this.createQuadMesh();
1069        this.setupProgramUniforms();
1070        this.frame = 0;
1071    }
1072}
1073
1074GlitchFx.prototype.createQuadMesh = function() {
1075    return this.context.mesh({
1076        textures: {
1077            uTexture: this.texture,
1078            uOffsets: this.generateHeightMap(64)
1079        },
1080        vertices: { aPosition: this.createScreenSpaceQuad() },
1081        attributes: { aTexCoord: this.createUVCoordinates() }
1082    });
1083}
1084
1085GlitchFx.prototype.createScreenSpaceQuad = function() {
1086    return this.context.vbo([ -1, 1, 1, 1, -1, -1, 1, -1 ])
1087}
1088
1089GlitchFx.prototype.createUVCoordinates = function() {
1090    return this.context.vbo([ 0, 1, 1, 1, 0, 0, 1, 0 ]);
1091}
1092
1093GlitchFx.prototype.enableWebGLExtensions = function() {
1094    this.context.getExtension('OES_texture_float');
1095    this.context.getExtension('OES_half_float_linear');
1096    this.context.getExtension('OES_float_linear');
1097}
1098
1099GlitchFx.prototype.setupProgramUniforms = function(arguments) {
1100    this.program.uSkip.set(1);
1101    this.program.uAmount.set(0.01);
1102    this.program.uAngle.set(0.01);
1103    this.program.uSeed.set(0.01);
1104    this.program.uSeedX.set(0.01);
1105    this.program.uSeedY.set(0.01);
1106    this.program.uDistortionX.set(0.1);
1107    this.program.uDistortionY.set(0.1);
1108    this.program.uColS.set(0.1);
1109    this.generateTrigger();
1110}
1111
1112GlitchFx.prototype.updateProgramUniforms = function() {
1113    if (!this.enabled) {
1114        this.glitching = false;
1115        this.program.uSkip.set(1);
1116        return;
1117    }
1118    if (this.glitching) {
1119        this.program.uSeed.set(Math.random());
1120        this.program.uSkip.set(0);
1121        this.program.uAmount.set(Math.random() / this.strengthDivisor);
1122        this.program.uAngle.set(this.randomFloat(-Math.PI, Math.PI));
1123        this.program.uSeedX.set(this.randomFloat(-this.maxSeedValue, this.maxSeedValue));
1124        this.program.uSeedY.set(this.randomFloat(-this.maxSeedValue, this.maxSeedValue));
1125        if (Math.random() < this.distortionProbability) {
1126            this.program.uDistortionX.set(this.randomFloat(0, this.maxDistortion));
1127            this.program.uDistortionY.set(this.randomFloat(0, this.maxDistortion));
1128        }
1129        if (this.glitchFrames > this.minGlitchedFrames) {
1130            if (this.glitchFrames > this.maxGlitchedFrames || Math.random() < this.offProbability) {
1131                this.program.uSkip.set(1);
1132                this.glitching = false;
1133            }
1134        }
1135        this.glitchFrames++;
1136    } else {
1137        this.glitching = Math.random() < this.onProbability;
1138        this.glitchFrames = 0;
1139    }
1140    this.frame++;
1141}
1142
1143GlitchFx.prototype.generateHeightMap = function(size) {
1144    // Fill a Float buffer with 3 channels worth of data (RGB).
1145    var data = new Float32Array( size * size * 3 );
1146    var length = size * size;
1147    for ( var value, index, i = 0; i < length; i++ ) {
1148        index = i * 3;
1149        value = Math.random();
1150        data[ index     ] = value;
1151        data[ index + 1 ] = value;
1152        data[ index + 2 ] = value;
1153    }
1154    return this.context.texture(data, size, size, {
1155        format: this.context.RGB,
1156        mipmap: false,
1157        min: this.context.NEAREST,
1158        mag: this.context.NEAREST,
1159        s: this.context.REPEAT,
1160        t: this.context.REPEAT
1161    });
1162}
1163
1164GlitchFx.prototype.generateTrigger = function() {
1165    this.randX = Math.floor(this.randomFloat(120, 240));
1166}
1167
1168GlitchFx.prototype.randomFloat = function(min, max) {
1169    if (typeof max == 'undefined') {
1170        max = min;
1171        min = 0;
1172    }
1173    return min + Math.random() * (max - min);
1174}
1175
1176// TODO: This mimics contain and not cover.
1177// TODO: Call during view project tween.
1178GlitchFx.prototype.resize = function() {
1179    // var bounds = this.domElement.getBoundingClientRect();
1180    var ratio1 = this.domElement.offsetWidth / this.domElement.offsetHeight;
1181    var ratio2 = this.image.width / this.image.height;
1182    var landscape = ratio1 < ratio2;
1183    // this.canvas.style.height = landscape ? '100%' : 'auto';
1184    // this.canvas.style.width = landscape ? 'auto' : '100%';
1185}
1186
1187GlitchFx.prototype.render = function() {
1188    requestAnimationFrame(this.render);
1189    if (this.enabled) {
1190        this.updateProgramUniforms();
1191        this.program.draw(this.mesh);
1192    }
1193}
1194
1195GlitchFx.prototype.setImagePath = function(path, with_bg) {
1196    // Always set the background image as a fallback.
1197
1198    if ( with_bg == undefined ) {
1199        with_bg = true;
1200    }
1201
1202    if (with_bg) this.domElement.style.backgroundImage = 'url(' + path + ')';
1203    if (this.hasWebGL) {
1204        this.image = new Image();
1205        this.image.onload = this.onImageLoaded;
1206        this.image.src = path;
1207    }
1208}
1209
1210GlitchFx.prototype.onImageLoaded = function() {
1211    this.context.size(this.image.width, this.image.height);
1212    this.texture.set(this.image);
1213    this.resize();
1214}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.