question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

glitch post-processing shader broken in A-Frame 0.9.1

See original GitHub issue

Description: Using aframe-effects, glitch post-processing shader working on A-Frame 0.9.0: glitch_on_0 9 0

glitch post-processing shader broken on A-Frame 0.9.1: glitch_on_0 9 1

  • Platform / Device: Tested on OSX Chrome 73
  • Reproducible Code Snippet or URL:
AFRAME.registerComponent("glitch", {
	    schema: { default: true },

	    init: function () {
	        this.system = this.el.sceneEl.systems.effects;

	        this.uniforms = {
	            "tDisp":		{ type: "t", value: this.generateHeightmap( 64 ) },
	            "amount":		{ type: "f", value: 0.08 },
	            "angle":		{ type: "f", value: 0.02 },
	            "seed":			{ type: "f", value: 0.02 },
	            "seed_x":		{ type: "f", value: 0.02 },//-1,1
	            "seed_y":		{ type: "f", value: 0.02 },//-1,1
	            "distortion_x":	{ type: "f", value: 0.5 },
	            "distortion_y":	{ type: "f", value: 0.6 },
	            "col_s":		{ type: "f", value: 0.05 }
		    };
	        
			this.exports = {
				glitch: {
	                fragment: this.fragment,
	                uniforms: this.uniforms
	            }
			}
	        // by declaring a .material property we set this component to take a whole pass of it's own
	        this.material = this.system.fuse([this.exports.glitch]);

	        this.system.register(this);
	    },

	    vr: true,

	    update: function () {
	        this.bypass = !this.data;
	        this.curF = 0;
	        this.generateTrigger();
	    },

	    remove: function () {
	        this.system.unregister(this);
	    },

	    tock: function () {
	        this.uniforms[ 'seed' ].value = Math.random();//default seeding
			
			if ( this.curF % this.randX == 0) {

				this.uniforms[ 'amount' ].value = Math.random() / 30;
				this.uniforms[ 'angle' ].value = THREE.Math.randFloat( - Math.PI, Math.PI );
				this.uniforms[ 'seed_x' ].value = THREE.Math.randFloat( - 1, 1 );
				this.uniforms[ 'seed_y' ].value = THREE.Math.randFloat( - 1, 1 );
				this.uniforms[ 'distortion_x' ].value = THREE.Math.randFloat( 0, 1 );
				this.uniforms[ 'distortion_y' ].value = THREE.Math.randFloat( 0, 1 );
				this.curF = 0;
				this.generateTrigger();

			} else if ( this.curF % this.randX < this.randX / 5 ) {

				this.uniforms[ 'amount' ].value = Math.random() / 90;
				this.uniforms[ 'angle' ].value = THREE.Math.randFloat( - Math.PI, Math.PI );
				this.uniforms[ 'distortion_x' ].value = THREE.Math.randFloat( 0, 1 );
				this.uniforms[ 'distortion_y' ].value = THREE.Math.randFloat( 0, 1 );
				this.uniforms[ 'seed_x' ].value = THREE.Math.randFloat( - 0.3, 0.3 );
				this.uniforms[ 'seed_y' ].value = THREE.Math.randFloat( - 0.3, 0.3 );

			} 

			this.curF ++;
	    },

	    generateTrigger: function() {

			this.randX = THREE.Math.randInt( 120, 240 );

		},

		generateHeightmap: function( dt_size ) {

			var data_arr = new Float32Array( dt_size * dt_size * 3 );
			var length = dt_size * dt_size;

			for ( var i = 0; i < length; i ++ ) {

				var val = THREE.Math.randFloat( 0, 1 );
				data_arr[ i * 3 + 0 ] = val;
				data_arr[ i * 3 + 1 ] = val;
				data_arr[ i * 3 + 2 ] = val;

			}

			var texture = new THREE.DataTexture( data_arr, dt_size, dt_size, THREE.RGBFormat, THREE.FloatType );
			texture.needsUpdate = true;
			return texture;

		},

	    fragment: [
			"float $rand(vec2 co){",
				"return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);",
			"}",
					
			"void $main(inout vec4 color, vec4 origColor, vec2 uv, float depth) {",
					"vec2 p = uv;",
	                "vec2 p2 = vec2( smoothstep(uvClamp.x, uvClamp.y, p.x),p.y);",
					"float xs = floor(gl_FragCoord.x / 0.5);",
					"float ys = floor(gl_FragCoord.y / 0.5);",
					//based on staffantans glitch shader for unity https://github.com/staffantan/unityglitch
					"vec4 normal = texture2D ($tDisp, p2 * $seed * $seed);",
					"if(p2.y < $distortion_x + $col_s && p2.y > $distortion_x - $col_s * $seed) {",
						"if($seed_x>0.){",
							"p.y = 1. - (p.y + $distortion_y);",
						"}",
						"else {",
							"p.y = $distortion_y;",
						"}",
					"}",
					"if(p2.x < $distortion_y + $col_s && p2.x > $distortion_y - $col_s * $seed) {",
						"if( $seed_y > 0.){",
							"p.x = $distortion_x;",
						"}",
						"else {",
							"p.x = 1. - (p.x + $distortion_x);",
						"}",
					"}",
					"p.x+=normal.x* $seed_x * ($seed/5.);",
					"p.y+=normal.y* $seed_y * ($seed/5.);",
					//base from RGB shift shader
					"vec2 offset = $amount * vec2( cos($angle), sin($angle));",
					"vec4 cr = textureVR(tDiffuse, p + offset);",
					"vec4 cga = textureVR(tDiffuse, p);",
					"vec4 cb = textureVR(tDiffuse, p - offset);",
					"color = vec4(cr.r, cga.g, cb.b, cga.a);",
					//add noise
					"vec4 snow = 200.*$amount*vec4($rand(vec2(xs * $seed,ys * $seed*50.))*0.2);",
					"color = color+ snow;",
			"}"
		].join( "\n" )
	});

Here is the effects system:

	AFRAME.registerSystem("effects", {
	    schema: { type: "array", default: [] },

	    init: function () {
	        this.effects = {};
	        this.passes = [];
	        this._passes = [];
	        this.cameras = [];
	        this.setupPostState();
	        this.needsOverride = true;
	        this.lightComponents = [];
			this.LightState = {
				rows: 0,
				cols: 0,
				width: 0,
				height: 0,
				tileData: { value: null },
				tileTexture: { value: null },
				lightTexture: {
					value: new THREE.DataTexture( new Float32Array( 32 * 2 * 4 ), 32, 2, THREE.RGBAFormat, THREE.FloatType )
				},
			};
	    },

	    update: function () {
	        this.needsUpdate = true;
	    },
	    
	    addLight: function (behavior) {
			this.lightComponents.push(behavior);
		},
		
		removeLight: function (behavior) {
			var index = this.lightComponents.indexOf(behavior);
			this.lightComponents.splice(index);
	    },
	    
	    setupPostState: function () {
	        this.renderTarget = new THREE.WebGLRenderTarget(1, 1, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat });
	        this.renderTarget.texture.generateMipmaps = false;
	        this.renderTarget.depthBuffer = true;
	        this.renderTarget.depthTexture = new THREE.DepthTexture();
	        this.renderTarget.depthTexture.type = THREE.UnsignedShortType;
	        this.renderTarget.depthTexture.minFilter = THREE.LinearFilter;
	        this.renderTarget.stencilBuffer = false;
	        this.scene = new THREE.Scene();
	        this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
	        this.quad = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2), null);
	        this.quad.frustumCulled = false;
	        this.scene.add(this.quad);
	        this.sceneLeft = new THREE.Scene();
	        this.quadLeft = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2), null);
	        this.quadLeft.geometry.attributes.uv.array.set([0, 1, 0.5, 1, 0, 0, 0.5, 0]);
	        this.quadLeft.frustumCulled = false;
	        this.sceneLeft.add(this.quadLeft);
	        this.sceneRight = new THREE.Scene();
	        this.quadRight = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2), null);
	        this.quadRight.geometry.attributes.uv.array.set([0.5, 1, 1, 1, 0.5, 0, 1, 0]);
	        this.quadRight.frustumCulled = false;
	        this.sceneRight.add(this.quadRight);
	        this.targets = [
	            new THREE.WebGLRenderTarget(1, 1, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat }),
	            new THREE.WebGLRenderTarget(1, 1, { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat })
	        ];
	        
	        this.tDiffuse = {type: "t", value: null};
	        this.tDepth = {type: "t", value: this.renderTarget.depthTexture};
	        this.cameraFar = {type: "f", value: 0};
	        this.cameraNear = {type: "f", value: 0};
	        this.time = { type: "f", value: 0 };
	        this.timeDelta = { type: "f", value: 0 };
	        this.uvClamp = { type: "v2", value: this.uvBoth };
	        this.resolution = { type: "v4", value: new THREE.Vector4() };

	    },

	    vertexShader: [
	        '#include <common>',
	        'varying vec2 vUv;',
	        'void main() {',
	        '   vUv = uv;',
	        '   gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',
	        '}'
	    ].join('\n'),

	    uvLeft: new THREE.Vector2(0, 0.5),
	    uvRight: new THREE.Vector2(0.5, 1),
	    uvBoth: new THREE.Vector2(0, 1),

	    parseToken: /([#a-z0-9\-\_]+)\.{0,1}([#a-z0-9\-\_]*)\s*\({0,1}\s*([\$a-z0-9\-\_\.\s]*)\){0,1}([\!\?]{0,1})/i,

	    renderPass: function (material, renderTarget, viewCb, forceClear){
	        var renderer = this.sceneEl.renderer;
	        this.quad.material = material;
	        var isFn = typeof viewCb === "function";
	        var s = renderTarget || renderer.getSize();
	        this.resolution.value.set(s.width, s.height, 1/s.width, 1/s.height);
	        var oldClear = renderer.autoClear;
	        renderer.autoClear = false;
	        if (viewCb) {
	            if (this.cameras.length > 1){
	                this.quadLeft.material = material;
	                this.uvClamp.value = this.uvLeft;
	                setView(0, 0, Math.round(s.width * 0.5), s.height);
	                if (isFn) viewCb(material, this.cameras[0], -1);
				    renderer.render(this.sceneLeft, this.camera, renderTarget, oldClear || forceClear);        
	                
	                this.quadRight.material = material;
	                this.uvClamp.value = this.uvRight;
	                setView(Math.round(s.width * 0.5), 0, Math.round(s.width * 0.5), s.height);
	                if (isFn) viewCb(material, this.cameras[1], 1);
	                renderer.render( this.sceneRight, this.camera, renderTarget);

	                this.uvClamp.value = this.uvBoth;
	                setView(0, 0, s.width, s.height);
	            } else {
	                setView(0, 0, s.width, s.height);
	                if (isFn) viewCb(material, this.sceneEl.camera, 0);
	                renderer.render( this.scene, this.camera, renderTarget, oldClear || forceClear);
	            }
	        } else {
	            setView(0, 0, s.width, s.height);
	            renderer.render(this.scene, this.camera, renderTarget, oldClear || forceClear);
	        }
	        renderer.autoClear = oldClear;
	        function setView(x,y,w,h) {
	            if (renderTarget) {
	                renderTarget.viewport.set( x, y, w, h );
					renderTarget.scissor.set( x, y, w, h );
	            } else {
	                renderer.setViewport( x, y, w, h );
					renderer.setScissor( x, y, w, h );
	            }
	        }
	    },

	    materialize: function (m) {
	        var fs = [
	            "uniform vec2 uvClamp;",
	            "vec4 textureVR( sampler2D sampler, vec2 uv ) {",
	            " return texture2D(sampler, vec2(clamp(uv.x, uvClamp.x, uvClamp.y), uv.y));",
	            "} ",
	            m.fragmentShader            
	        ].join("\n");
	        
	        m.uniforms.uvClamp = this.uvClamp;
	        
	        return new THREE.ShaderMaterial({
	            uniforms: m.uniforms,
	            vertexShader: m.vertexShader || this.vertexShader,
	            fragmentShader: fs,
	            depthWrite: false,
	            depthTest: false,
	            blending: THREE.NoBlending,
	            fog: false,
	            extensions: {
	                derivatives: true
	            },
	            defines: m.defines || {}
	        });
	    },

	    fuse: function (temp, alpha) {
	        if (!temp.length) return;
	        var self = this, count=0;
	        var chunks = [], head = [], main = [], includes = {}, 
	            needsDepth = false, needsDiffuse = false, k;
	 
	        var uniforms = {
	            time: this.time,
	            timeDelta: this.timeDelta,
	            resolution: this.resolution
	        };

	        temp.forEach(function (obj) {
	            var callMain = true, swapMain = false, args=[];
	            if (typeof obj === "string") {
	                var tok = self.parseToken.exec(obj);
	                if(!tok) return;
	                
	                callMain = tok[4] !== "!";
	                swapMain = tok[4] === "?";
	                obj = tok[1];
	                var prop = tok[2];
	                var temp = {};
	                
	                if(obj[0] === "#") {
	                    var el = document.querySelector(obj);
	                    if(!el) return;
	                    
	                    obj = {
	                        attrName: [obj.replace("#", "script_"), "_", (count++), "_"].join(""),
	                        fragment: prop ? 
	                            (el[prop] instanceof Document ? el[prop].body.textContent : el[prop]) 
	                            : el.textContent,
	                        depth: el.dataset.depth !== undefined,
	                        diffuse: el.dataset.diffuse !== undefined,
	                        includes: el.dataset.includes ? el.dataset.includes.trim().split(" ") : null,
	                        defaults: el.dataset.defaults ? el.dataset.defaults.trim().split(" ") : null
	                    };
	                } else {
	                    obj = self.effects[obj];
	                    if (!obj) return;
	                    if (prop) {
	                        obj = obj.exports ? obj.exports[prop] : null;
	                        if (!obj) return;
	                        obj.attrName = tok[1] + "_" + prop + "_";
	                    }
	                }
	                if (tok[3]) {
	                    args = tok[3].trim().split(" ");
	                }
	            }
	            var prefix = (obj.attrName ? obj.attrName : "undefined_" + (count++)) + "_";
	            prefix = prefix.replace("__","_");
	            if (obj.defaults) {
	                obj.defaults.forEach(function (d, i) {
	                    var v = args[i];
	                    chunks.push(["#define $", i, " ", v  && v !== "$" ? v : d ].join("").replace(/\$/g, prefix).replace("__","_"));
	                });
	            }
	            if (obj.diffuse) { needsDiffuse = true; }
	            if (obj.depth) { needsDepth = true; }
	            if (obj.fragment) { chunks.push(obj.fragment.replace(/\$/g, prefix)); }
	            if (obj.uniforms) {
	                for (var u in obj.uniforms) {
	                    uniforms[prefix + u] = obj.uniforms[u];
	                }
	            };
	            if (obj.includes) {
	                obj.includes.forEach(function (inc) {
	                    includes[inc] = true;
	                });
	            }
	            if (callMain) {
	                main.push(["  ", prefix, "main(", ( swapMain ? "origColor, color": "color, origColor"), ", vUv, depth);"].join(""));
	            }
	        });
	        var t2u = { "i": "int", "f": "float", "t": "sampler2D",
	            "v2": "vec2", "v3": "vec3", "c": "vec3","v4": "vec4", 
	            "m2": "mat2", "m3":"mat3", "m4": "mat4", "b": "bool" };

	        for(k in includes) { head.push("#include <" + k + ">"); }
	        
	        var premain = [
	            "void main () {" 
	        ];
	        uniforms["tDiffuse"] = this.tDiffuse;
	             
	        if (needsDiffuse){
	             premain.push("  vec4 color = texture2D(tDiffuse, vUv);"); 
	        } else {
	             premain.push("  vec4 color = vec4(0.0);"); 
	        }
	        premain.push("  vec4 origColor = color;"); 
	        
	        uniforms["tDepth"] = this.tDepth;
	        uniforms["cameraFar"] = this.cameraFar;
	        uniforms["cameraNear"] = this.cameraNear;
	            
	        if (needsDepth){
	            premain.push("  float depth = texture2D(tDepth, vUv).x;");
	        } else {
	            premain.push("  float depth = 0.0;");
	        }
	        
	        for(k in uniforms) {
	            var u = uniforms[k];
	            head.push(["uniform", t2u[u.type], k, ";"].join(" "));
	        }
	        
	        head.push("varying vec2 vUv;");
	        var source = [
	            head.join("\n"), chunks.join("\n"), "\n",
	                premain.join("\n"), main.join("\n"), 
	                alpha ? "  gl_FragColor = color;" : "  gl_FragColor = vec4(color.rgb, 1.0);", "}"
	        ].join("\n");

	        var material = this.materialize({
	            fragmentShader: source, 
	            uniforms: uniforms
	        });

	        if(this.sceneEl.components.debug) console.log(source, material);
	        return material;
	    },

	    rebuild: function () {
	        var self = this, passes = [], temp = [];
	        this.passes.forEach(function(pass){
	            if (pass.dispose) pass.dispose();
	        });
	        this.data.forEach(function (k) {
	            if(!k){
	                pickup();
	                return;
	            }
	            var obj, name;
	            var tok = self.parseToken.exec(k);
	            if(!tok || !tok[1]) return;
	            name = tok[1];
	            obj = self.effects[name];
	            if (!obj){
	                temp.push(k);
	                return;
	            }
	            if (obj.pass) {
	                pickup();
	                passes.push({ pass: obj.pass, behavior: obj } );
	            } else if (obj.material){
	                pickup();
	                passes.push({ pass: makepass(obj.material, false, obj.vr), behavior: obj });
	            } else {
	                temp.push(k);
	            }          
	        });

	        function pickup () {
	            if (!temp.length) return;
	            passes.push({ pass: makepass(self.fuse(temp), true)});
	            temp = [];
	        }

	        function makepass (material, dispose, viewCb) {
	            return {
	                render: function(renderer, writeBuffer, readBuffer){
	                    self.renderPass(material, writeBuffer, viewCb);
	                },

	                dispose: function () {
	                    if (dispose) material.dispose();
	                }
	            }
	        }
	        pickup();
	        this.needsUpdate = false;
	        this.passes = passes;
	    },

	    isActive: function (behavior, resize) {
	        var scene = this.sceneEl;
	        if (behavior.bypass) return false;
	        var isEnabled = scene.renderTarget ? true : false;
	        if (!isEnabled) return false;
	        if (resize && (this.needsResize || behavior.needsResize) && behavior.setSize) {
	            var size = scene.renderer.getSize();
	            behavior.setSize(size.width, size.height);
	            delete behavior.needsResize;
	        }
	        return true;
	    },

	    register: function (behavior) {
	        this.effects[behavior.attrName] = behavior;
	        this.needsUpdate = true;
	    },

	    unregister: function (behavior) {
	        delete this.effects[behavior.attrName];
	        this.needsUpdate = true;
	    },

	    tick: function (time, timeDelta) {
	        var self = this, sceneEl = this.sceneEl, renderer = sceneEl.renderer, effect = sceneEl.effect, 
	            rt = this.renderTarget, rts = this.targets, scene = sceneEl.object3D;
	        if(!rt || !renderer) { return; }
	        if (this.needsOverride) {
	            if(scene.onBeforeRender) {
	                scene.onBeforeRender = function (renderer, scene, camera) {
	                    var size = renderer.getSize();
	                    if (size.width !== rt.width || size.height !== rt.height) {
	                        rt.setSize(size.width, size.height);
	                        rts[0].setSize(size.width, size.height);
	                        rts[1].setSize(size.width, size.height);
	                        self.resolution.value.set(size.width, size.height, 1/size.width, 1/size.height);
	                        self.needsResize = true;
	                        self.resizeTiles();
	                    }
	                    if(camera instanceof THREE.ArrayCamera) {
	                        self.cameras = camera.cameras;
	                    } else {
	                        self.cameras.push(camera);
	                    }
	                    self.tileLights(renderer, scene, camera);
	                }
	            } else {
	                var rendererRender = renderer.render;
	                renderer.render = function (scene, camera, renderTarget, forceClear) {
	                    if (renderTarget === rt) {
	                        var size = renderer.getSize();
	                        if (size.width !== rt.width || size.height !== rt.height) {
	                            rt.setSize(size.width, size.height);
	                            rts[0].setSize(size.width, size.height);
	                            rts[1].setSize(size.width, size.height);
	                            self.resolution.value.set(size.width, size.height, 1/size.width, 1/size.height);
	                            self.needsResize = true;
	                        }
	                        self.cameras.push(camera);
	                    }
	                    rendererRender.call(renderer, scene, camera, renderTarget, forceClear);
	                }
	            }        
	            this.needsOverride = false;
	        }
	        this.cameras = [];
	        this.time.value = time / 1000;
	        this.timeDelta.value = timeDelta / 1000;

	        if (this.needsUpdate === true) { this.rebuild(); }

	       this.setupPasses();

	        this.tDiffuse.value = this.renderTarget.texture;
	        this.tDepth.value = this.renderTarget.depthTexture;
	        var camera = this.sceneEl.camera;
	        this.cameraFar.value = camera.far;
	        this.cameraNear.value = camera.near;                
	    },

	    setupPasses : function () {
	        var arr = [], rt = this.renderTarget;
	        this.passes.forEach(function (p) {
	            if (p.behavior && p.behavior.bypass === true) return;
	            arr.push(p);
	        });
	        this.sceneEl.renderTarget = arr.length && this.sceneEl.isPlaying ? rt : null;
	        this._passes = arr;
	    },
	    tock: function () {
	        var scene = this.sceneEl, renderer = scene.renderer, self = this;
	        if(!scene.renderTarget) { return; }
	        var rt = scene.renderTarget, rts = this.targets;
	        this._passes.forEach(function (pass, i) {
	            var r = i ? rts[i & 1] : rt;
	            self.tDiffuse.value = r.texture;   
	            if (pass.behavior && pass.behavior.resize) self.isActive(pass.behavior, true);
	            pass.pass.render(renderer, i < self._passes.length - 1 ? rts[(i+1) & 1] : null, r);
	        });
	        this.needsResize = false;
	    },

	    resizeTiles: function () {
	        var LightState = this.LightState;
	        var width = LightState.width;
	        var height = LightState.height;
	        LightState.cols = Math.ceil( width / 32 );
	        LightState.rows = Math.ceil( LightState.height / 32 );
	        LightState.tileData.value = [ width, height, 0.5 / Math.ceil( width / 32 ), 0.5 / Math.ceil( height / 32 ) ];
	        LightState.tileTexture.value = new THREE.DataTexture( new Uint8Array( LightState.cols * LightState.rows * 4 ), LightState.cols, LightState.rows );
	    },
	    
	    tileLights: function ( renderer, scene, camera ) {
	        if ( ! camera.projectionMatrix ) return;
	        var LightState = this.LightState, lights = this.lightComponents;
	        var size = renderer.getSize();
	        var d = LightState.tileTexture.value.image.data;
	        var ld = LightState.lightTexture.value.image.data;
	        var viewMatrix = camera.matrixWorldInverse;
	        d.fill( 0 );
	        var vector = new THREE.Vector3();

	        var passes;
	        if(camera instanceof THREE.ArrayCamera) {
	            passes = [ [0.5, 0, camera.cameras[0]], [0.5, 0.5, camera.cameras[1]]];
	        } else {
	            passes = [1.0, 0, camera];
	        }
	        passes.forEach(function(pass){
	            lights.forEach( function ( light, index ) {
	                vector.setFromMatrixPosition( light.el.object3D.matrixWorld );
	                var pw = LightState.width * pass[0];
	                var pm = LightState.width * pass[1];
	                var bs = self.lightBounds( pass[2], vector, light.data.radius, pw );
	                vector.applyMatrix4( viewMatrix );
	                vector.toArray( ld, 4 * index );
	                ld[ 4 * index + 3 ] = light.data.radius;
	                light.data.color.toArray( ld, 32 * 4 + 4 * index );
	                ld[ 32 * 4 + 4 * index + 3 ] = light.data.decay;
	                if ( bs[ 1 ] < 0 || bs[ 0 ] > pw || bs[ 3 ] < 0 || bs[ 2 ] > LightState.height ) return;
	                if ( bs[ 0 ] < 0 ) bs[ 0 ] = 0;
	                if ( bs[ 1 ] > pw ) bs[ 1 ] = pw;
	                if ( bs[ 2 ] < 0 ) bs[ 2 ] = 0;
	                if ( bs[ 3 ] > LightState.height ) bs[ 3 ] = LightState.height;
	                var i4 = Math.floor( index / 8 ), i8 = 7 - ( index % 8 );
	                for ( var i = Math.floor( bs[ 2 ] / 32 ); i <= Math.ceil( bs[ 3 ] / 32 ); i ++ ) {
	                    for ( var j = Math.floor( (bs[ 0 ] + pm) / 32  ); j <= Math.ceil( (bs[ 1 ] + pm) / 32 ); j ++ ) {
	                        d[ ( LightState.cols * i + j ) * 4 + i4 ] |= 1 << i8;
	                    }
	                }
	            } );
	        });
	        LightState.tileTexture.value.needsUpdate = true;
	        LightState.lightTexture.value.needsUpdate = true;
	    },
	    
	    lightBounds: function () {  
	        let v = new THREE.Vector3();
	        return function ( camera, pos, r, w ) {
	            var LightState = this.LightState;
	            var minX = w, maxX = 0, minY = LightState.height, maxY = 0, hw = w / 2, hh = LightState.height / 2;
	            for ( var i = 0; i < 8; i ++ ) {
	                v.copy( pos );
	                v.x += i & 1 ? r : - r;
	                v.y += i & 2 ? r : - r;
	                v.z += i & 4 ? r : - r;
	                var vector = v.project( camera );
	                var x = ( vector.x * hw ) + hw;
	                var y = ( vector.y * hh ) + hh;
	                minX = Math.min( minX, x );
	                maxX = Math.max( maxX, x );
	                minY = Math.min( minY, y );
	                maxY = Math.max( maxY, y );
	            }
	            return [ minX, maxX, minY, maxY ];
	    };
	    }()
	});

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
kfarrcommented, Jun 5, 2019
0reactions
EricEisamancommented, May 19, 2019
Read more comments on GitHub >

github_iconTop Results From Across the Web

Aframe Shader Glitch
Example of using custom shaders in A-Frame.
Read more >
aframe/CHANGELOG.md - UNPKG
aframe /CHANGELOG.md ; 400 ; 401, ### Bug Fixes ; 402 ; 403, - Place touch model to match real physical position of...
Read more >
Shader with threejs material not working in aframe
The issue here is that your shader in the applied material does not provide the map uniform / texture value.
Read more >
RELEASE NOTES - House Party
In the Original Story: Fixed a bug where Patrick would leave when the female player was already in the master bedroom with him...
Read more >
14th Central European Seminar on Computer Graphics - cescg
This book contains the proceedings of the 14th Central European Seminar on. Computer Graphics, short CESCG, which continues a history of ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found