Search the Community

Showing results for tags 'filter'.

More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • HTML5 Game Coding
    • News
    • Game Showcase
    • Facebook Instant Games
    • Web Gaming Standards
    • Coding and Game Design
  • Frameworks
    • Phaser 3
    • Phaser 2
    • Pixi.js
    • Babylon.js
    • Panda 2
    • melonJS
  • General
    • General Talk
  • Business
    • Collaborations (un-paid)
    • Jobs (Hiring and Freelance)
    • Services Offered

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start



Website URL





Found 88 results

  1. Seemingly simple task, yet so unclear and confusing in Pixi. After searching for a while, found this and that is exactly what I need And that is for Pixi 4. Once I copied the code into pixi examples window and fixed the method names, I saw this (Attachment) const shaderVert = ` attribute vec2 aVertexPosition; attribute vec2 aTextureCoord; uniform mat3 projectionMatrix; varying vec2 vTextureCoord; varying vec2 vFilterCoord; void main(void) { gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0); vTextureCoord = aTextureCoord; } `; const shaderFrag = ` varying vec2 vTextureCoord; uniform vec2 scale; uniform sampler2D uSampler; uniform sampler2D backdropSampler; uniform vec4 filterArea; uniform vec4 filterClamp; void main(void) { vec4 map = texture2D(uSampler, vTextureCoord); map -= 0.5; map.xy *= scale / filterArea.xy; vec2 dis = clamp(vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y), filterClamp.xy,; gl_FragColor = texture2D(backdropSampler, dis); } `; class DisplacementFilter extends PIXI.Filter { constructor(scale) { super( shaderVert, shaderFrag ); this.uniforms.scale = {x: 1, y: 1}; if (scale === null || scale === undefined) { scale = 20; } this.scale = new PIXI.Point(scale, scale); this.backdropUniformName = 'backdropSampler'; } apply(filterManager, input, output) { this.uniforms.scale.x = this.scale.x; this.uniforms.scale.y = this.scale.y; // draw the filter... filterManager.applyFilter(this, input, output); this.clearColor = [0.5, 0.5, 0.5, 1.0]; } } const app = new PIXI.Application(800, 600); document.body.appendChild(app.view); app.stage.interactive = true; app.stage.filters = [new PIXI.filters.AlphaFilter()]; app.stage.filterArea = app.screen; const container = new PIXI.Container(); app.stage.addChild(container); const padding = 100; const bounds = new PIXI.Rectangle( -padding, -padding, app.screen.width + padding * 2, app.screen.height + padding * 2 ); const maggots = []; for (let i = 0; i < 20; i++) { const maggot = PIXI.Sprite.from(''); maggot.anchor.set(0.5); container.addChild(maggot); maggot.direction = Math.random() * Math.PI * 2; maggot.speed = 1; maggot.turnSpeed = Math.random() - 0.8; maggot.x = Math.random() * bounds.width; maggot.y = Math.random() * bounds.height; maggot.scale.set(1 + Math.random() * 0.3); maggot.original = new PIXI.Point(); maggot.original.copyFrom(maggot.scale); maggots.push(maggot); } const displacementContainer = new PIXI.Container(); const displacementTexture = PIXI.Texture.from(''); for (let i = -1; i <= 1; i += 2) { let sprite1 = new PIXI.Sprite(displacementTexture); sprite1.position.set(100*i, 0); sprite1.anchor.set(0.5); displacementContainer.addChild(sprite1); } app.stage.addChild(displacementContainer); const displacementFilter = new DisplacementFilter(); displacementContainer.filters = [displacementFilter]; displacementFilter.scale.x = 110; displacementFilter.scale.y = 110; //displacementFilter.padding = 0; const ringTexture = PIXI.Texture.from(''); const rings = new PIXI.Container(); for (let i = -1; i <= 1; i += 2) { let sprite1 = new PIXI.Sprite(ringTexture); sprite1.position.set(100*i, 0); sprite1.anchor.set(0.5); rings.addChild(sprite1); } rings.visible = false; app.stage.addChild(rings); const bg = PIXI.Sprite.from(''); bg.width = app.screen.width; bg.height = app.screen.height; bg.alpha = 1; app.stage.addChildAt(bg, 0); app.stage .on('mousemove', onPointerMove) .on('touchmove', onPointerMove); function onPointerMove(eventData) { rings.visible = true; displacementContainer.position.set(,; rings.position.copyFrom(displacementContainer.position); } let count = 0; app.ticker.add(function () { count += 0.05; for (let i = 0; i < maggots.length; i++) { const maggot = maggots[i]; maggot.direction += maggot.turnSpeed * 0.01; maggot.x += Math.sin(maggot.direction) * maggot.speed; maggot.y += Math.cos(maggot.direction) * maggot.speed; maggot.rotation = -maggot.direction - Math.PI / 2; maggot.scale.x = maggot.original.x + Math.sin(count) * 0.2; // wrap the maggots around as the crawl if (maggot.x < bounds.x) { maggot.x += bounds.width; } else if (maggot.x > bounds.x + bounds.width) { maggot.x -= bounds.width; } if (maggot.y < bounds.y) { maggot.y += bounds.height; } else if (maggot.y > bounds.y + bounds.height) { maggot.y -= bounds.height; } } }); Obviously, something isn't working as in Pixi 4. CIED6wShf9.mp4
  2. I'm looking to generate a basic grid using a shader, and I've came across this Codepen which fits what I'm looking for. Only issue is: it's using Pixi v3, I've been looking into the documentation to port this code to work for a v5 filter, with no success so far. I'm still in the process of learning about shaders and filters, and the original code is already 2 versions outdated. Any help would be greatly appreciated. Cheers!
  3. I made a playground example to illustrate my issue. When setting the output values of the fragment, the alpha seems to be ignored when I use a constant value instead of the sampled one. If you uncomment the last line of the shader you will see my issue - how can I avoid showing the colour where alpha is zero ?
  4. I have a displacement filter using an radial map you can find attached to the post. This filter is bound to a sprite which is following the cursor. In addition to this displacement filter, I'm trying to also include an RGB split at the cursor's position. To do so I installed the type `RGBSplitFilter` and tried to use it the way I use the displacement filter: initDisplacement = () => { this.displace = true; new PIXI.Loader().add("/dis.png").load(((loader, resources) => { this.posX = window.innerWidth / 2; this.posY = window.innerHeight / 2; this.displacementSprite = new PIXI.Sprite(resources["/dis.png"].texture); this.displacementFilter = new PIXI.filters.DisplacementFilter(this.displacementSprite); this.displacementSprite.anchor.set(0.5); this.displacementSprite.x = window.innerWidth / 2; this.displacementSprite.y = window.innerHeight / 2; this.displacementSprite.scale.set(2); this.displacementFilter.scale.set(2); this.stage.addChild(this.displacementSprite); this.stage.filters.push(this.displacementFilter); document.querySelector(".detail__image").addEventListener("mousemove", (e) => { this.posX = e.clientX; this.posY = e.clientY; }) })) }; loopDisplacement = () => { this.displacementSprite.x = this.posX; this.displacementSprite.y = this.posY; }; As you can see I get the map's texture, define it as a sprite and kind of attach a displacement filter to it. Likewise I tried to use `this.rgbFilter = new PIXI.filters.RGBSplitFilter(this.displacementSprite)` - but this didn't work. What's the correct approach to implement such an rgb split at the cursor's position?
  5. I have a `PIXI.Container()` I apply a shader/filter to using `container.filters = [filter]`. Documentations says, to remove a filter, just set `container.filters = null`. This works, but it's kind of a hard cut, when the image/sprite inside of the container is still visible, hence my question: Can I remove a filter with a kind of fade/transition?
  6. Hi, so currently i'm working on personal game with RPG Maker MV and i'm trying to recreate vision limitation with shader, some thing like this This example is created with PIXI 5.2 and working with mouse position After this i'm went back to RPG Maker MV(Using Pixi 4.5.4) and use the shader code, alter it a bit and got it's kinda working with position (0,0) But when I change to position (0.5,0.5) - hopefully the light will go to center of the screen it got offset like this: This is what I come up with shader code for this effect precision mediump float; const float PI = 3.1415926535; varying vec2 vTextureCoord; uniform sampler2D uSampler; uniform vec2 iResolution; uniform float iTime; uniform vec2 pos; vec4 limitVision(vec2 st, vec2 pos, float radius){ float pct = 1. - smoothstep(0., radius ,distance(st,vec2(pos))); return vec4(pct); } vec4 norctunalVision(vec2 st, vec2 pos){ vec4 col = limitVision(st, pos, .2); vec4 tex = texture2D(uSampler,st); vec4 result = mix(col,tex,col.a); vec4 tex2 = texture2D(uSampler,st); //sampler texture again for out of vision effect tex2.rgb /= 5.; // Alter color result = mix(result,tex2,1. - col.a); //Mix them together return result; } void main(){ vec2 uv = vTextureCoord; vec4 col = norctunalVision(uv, pos); gl_FragColor = col; } Are there any difference between filter of PIXI(4.5.4) inside RMMV and standalone PIXI(5.2) or some kind of matrix calculation for them? EDIT: Just downgrade my standalone PIXI 5.2 down to 4.5.4 and have same issue, so this maybe a PIXI issues not by rpg maker mv -------- So what difference between the vTextureCoord or some matrix calculation between PIXI 4.5.4 and 5.2?
  7. ZebraRoy

    Filter Buffer

    How can I use the buffer function in filters? I want to do something like this
  8. Hello. I'm making example filter with custom fragment shader. This is what I have in terms of shader code so far: //fragShader struct SomeInfo { vec4 color; }; uniform SomeInfo c; void main() { gl_FragColor = c.color; } The idea is to (eventually) make c into an array of Infos, which would be then operated on by the shader. What I'm struggling with is the definition of filter: how do I declare the uniform to be of type SomeInfo in Js code? I assume in plain WebGL, I'd have to bind uniform location (of c's property) by calling gl.getUniformLocation(program, "c.color") and create a uniform with appropriate gl.uniform4f(location, /* bunch of values*/), but can I do something similar via the existing filters means? Relevant part of my Js code looks like this: //Define base filter class for our future shaders/filters PIXI.filters.CustomFilterBase = class CustomFilterBase extends PIXI.Filter { constructor({ vertexSrc = null, fragmentSrc = null, uniforms = {}, enabled = true, debug = false, name = null } = {}) { if(debug && fragmentSrc !== null) { fragmentSrc = "#define DEBUG \r\n" + fragmentSrc; } //Add dimensions for scaling uniforms.dimensions = { type: 'vec2', value: { x: 0.0, y: 0.0 } }; super(vertexSrc, fragmentSrc, uniforms); name ? this._name = name : this._name = "CustomFilterBase"; this.autoFit = false; this.enabled = enabled; } apply(filterManager, input, output) { this.uniforms.dimensions.x = input.sourceFrame.width; this.uniforms.dimensions.y = input.sourceFrame.height; // draw the filter... filterManager.applyFilter(this, input, output); } } //Shader for prototyping and testing PIXI.filters.TestFilter = class TestFilter extends PIXI.filters.CustomFilterBase { constructor() { let fragmentSrc = document.getElementById('fragShader').innerHTML; let uniforms = { //What do I do here?! c: { type: 'vec4', //Judging by GLSL_SINGLE_SETTERS, only GLSL's primitives are recognized value: new Float32Array([0.0, 1.0, 0.0, 1.0]) } }; super({ vertexSrc: null, fragmentSrc: fragmentSrc, uniforms: uniforms, name: 'testfilter' }); } } (using pixijs v4.8.7) The expected result is green screen, as it is if I declare c as vec4 in shader code, but alas the screen is black, hinting on c's value being default constructed / not properly assigned Any help is appreciated, cheers! P.S. I tried to find similar cases from this forum and stackoverflow, but it seems that few people use structs in GLSL code. P.P.S. If it is of any help, I found that PIXI.glCore.shader removes specific characters from uniform's name (which looks like a hotfix rather than a feature) and that in fact one of iterations uniformData's name is 'c.color'. /** * Extracts the uniforms * @class * @memberof PIXI.glCore.shader * @param gl {WebGLRenderingContext} The current WebGL rendering context * @param program {WebGLProgram} The shader program to get the uniforms from * @return uniforms {Object} */ var extractUniforms = function(gl, program) { var uniforms = {}; var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); for (var i = 0; i < totalUniforms; i++) { var uniformData = gl.getActiveUniform(program, i); var name =\[.*?\]/, ""); //<----- Here it is!! var type = mapType(gl, uniformData.type ); uniforms[name] = { type:type, size:uniformData.size, location:gl.getUniformLocation(program, name), value:defaultValue(type, uniformData.size) }; } return uniforms; };
  9. I have a huge sprite that contains many sub sprites, I want to add mosaic to a specific area of this sprite. I have tried the PixelateFilter but it takes effect on the whole sprite. The attachment is what I want (see top-right corner)
  10. In phaser 2, I applied to an image two filters to make a blurred image (Blur X and Blur Y, with the two of them a complete Blur). I wanted to use the same filter system to apply this two shaders, but I don't find the filter class anywhere. But I found the Pipeline system, so I combined both blurs and made this complete blur shader. Everything fine now. My questions are... There is some way to apply two pipelines in one image/sprite? and, There is an alternative for filters in phaser 3?
  11. Hello, I'm trying to create a custom Filter in Phaser to make dithering. I used this great resource as a reference: Here is my code (I modified the DotScreenFilter code): PIXI.DotScreenFilter = function() { this ); this.passes = [this]; // set the uniforms this.uniforms = { scale: {type: '1f', value:1}, angle: {type: '1f', value:5}, dimensions: {type: '4fv', value:[0,0,0,0]}, indexMatrix4x4: {type: '16i',value:[0, 8, 2, 10, 12, 4, 14, 6,3, 11, 1, 9,15, 7, 13, 5]} }; this.fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', 'varying vec4 vColor;', 'uniform vec4 dimensions;', 'uniform sampler2D uSampler;', 'uniform float angle;', 'uniform float scale;', 'uniform int indexMatrix4x4[16];', 'float indexValue() {', 'int x = int(mod(gl_FragCoord.x, 4));', 'int y = int(mod(gl_FragCoord.y, 4));', 'return float(indexMatrix4x4[(x + y * 4)]) / 16.0;', '}', 'float dither(float color) {', 'float closestColor = (color < 0.5) ? 0.0 : 1.0;', 'float secondClosestColor = 1.0 - closestColor;', 'float d = indexValue();', 'float distance = abs(closestColor - color);', 'return (distance < d) ? closestColor : secondClosestColor;', '}', 'void main() {', 'gl_FragColor = vec4(vec3(dither(vColor.a)), 1);', '}' ]; }; PIXI.DotScreenFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.DotScreenFilter.prototype.constructor = PIXI.DotScreenFilter; /** * The scale of the effect. * @property scale * @type Number */ Object.defineProperty(PIXI.DotScreenFilter.prototype, 'scale', { get: function() { return this.uniforms.scale.value; }, set: function(value) { this.dirty = true; this.uniforms.scale.value = value; } }); /** * The radius of the effect. * @property angle * @type Number */ Object.defineProperty(PIXI.DotScreenFilter.prototype, 'angle', { get: function() { return this.uniforms.angle.value; }, set: function(value) { this.dirty = true; this.uniforms.angle.value = value; } }); When I run it, i got these errors: Any ideas what is wrong ?
  12. Is there already a way to make a displacement filter in p3? something like that: would like to use it for explosions (shockwave effect) any idears on implementing this effect into p3.? regards
  13. I have simple Filter and need to make access in shader to data: - position of sprite / mesh of Stage - textureRegion rectangle info How to do this? var fragSrc = ` precision mediump float; varying vec2 vTextureCoord; uniform sampler2D uSampler; uniform vec2 dimensions; uniform vec4 filterArea; uniform vec4 texRegion; vec2 mapCoord( vec2 coord ) { return coord * filterArea.xy; } vec2 unmapCoord( vec2 coord ) { return coord / filterArea.xy; } void main() { vec2 coord = vTextureCoord; coord = mapCoord(coord) / dimensions; coord = unmapCoord(coord * dimensions); vec4 color = texture2D( uSampler, coord ); gl_FragColor = color; } `.split('\n').reduce( (c, a) => c + a.trim() + '\n' ); module.exports = RepeatRegionFilter = function RepeatRegionFilter() {, null, fragSrc); } Util.inherits(RepeatRegionFilter, PIXI.Filter); RepeatRegionFilter.prototype.apply = function(filterManager, input, output) { this.uniforms.dimensions[0] = input.sourceFrame.width; this.uniforms.dimensions[1] = input.sourceFrame.height; filterManager.applyFilter(this, input, output); }
  14. I played a ludem dare game a few years ago and finally re-found the game I loved this beveled pixel effect and have been trying to use it in phaser. Deepnight referenced this one Reddit post on how to implement the style, but I have not been able to successfully do anything with it yet. I've tried desperately to use the following shader example by Rybar but always seem to fall a little bit short. I wanted to render the effect on the entire instead of having to add everything manually to a group like Rybar did in his examples. I tried to use his shader and capture the world, scale it up, and render it to a sprite on top everything. Using this method causes all of the camera, and physics to be off. I've made a simple example of my closest attempt using Phaser CE and some boilerplate. I've added some debug boxes to show where the original sprites are located in the background. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Phaser - Making your first game, part 7</title> <script type="text/javascript" src="js/phaser.min.js"></script> <style type="text/css"> body { margin: 0; } </style> </head> <body> <script type="text/javascript"> var w = 800 var h = 600; var player; var platforms; var cursors; var renderTexture; var renderTexture2; var stageSprite; var outputSprite; var gameMatrix; var gameGroup; var game = new Phaser.Game(w, h, Phaser.WEBGL, '', { preload: preload, create: create, update: update, render: render, preRender: preRender }); function preload() { game.load.image('sky', 'assets/sky.png'); game.load.image('ground', 'assets/platform.png'); game.load.spritesheet('dude', 'assets/dude.png', 32, 48); } function create() { game.physics.startSystem(Phaser.Physics.ARCADE); game.add.sprite(0, 0, 'sky'); platforms =; platforms.enableBody = true; var ground = platforms.create(0, - 64, 'ground'); ground.scale.setTo(2, 2); ground.body.immovable = true; var ledge = platforms.create(0, 110, 'ground'); ledge.body.immovable = true; ledge = platforms.create(250, 255, 'ground'); ledge.body.immovable = true; // player = game.make.sprite(32, - 150, 'dude'); // move the player to the top platform player = game.make.sprite(0, 0, 'dude'); game.physics.arcade.enable(player); player.body.gravity.y = 300; player.body.collideWorldBounds = true; player.animations.add('left', [0, 1, 2, 3], 10, true); player.animations.add('right', [5, 6, 7, 8], 10, true); cursors = game.input.keyboard.createCursorKeys(); var fragmentSrc = [ 'precision mediump float;', 'varying vec2 vTextureCoord;', 'varying vec4 vColor;', 'uniform sampler2D uSampler;', 'uniform vec2 resolution;', 'uniform float time;', 'uniform vec2 mouse;', 'void main( void ) {', 'vec2 st = vTextureCoord.xy;', 'st *= resolution;', // this makes the box defined below tiny and repeat across the screen 'st = fract(st);', 'vec2 bl = step(vec2(0.25, 0.75) , st);', 'float pct = bl.x * bl.y;', 'vec2 tr = step(vec2(0.5, 0.00),1.0-st);', 'pct *= tr.x * tr.y;', 'pct *= 0.15;', // knock it down to gray 'vec3 src = texture2D(uSampler, vTextureCoord).xyz;', // game art 'vec3 dst = vec3(pct) + vec3(0.4);', // the overlay pattern 'vec3 color = vec3((dst.x <= 0.5) ? (2.0 * src.x * dst.x) : (1.0 - 2.0 * (1.0 - dst.x) * (1.0 - src.x)),' + '(dst.y <= 0.5) ? (2.0 * src.y * dst.y) : (1.0 - 2.0 * (1.0 - dst.y) * (1.0 - src.y)),' + '(dst.z <= 0.5) ? (2.0 * src.z * dst.z) : (1.0 - 2.0 * (1.0 - dst.z) * (1.0 - src.z)));', 'gl_FragColor.rgb = clamp(color, 0.0, 1.0);', 'gl_FragColor.w = 1.0;', '}' ] gameGroup =; gameGroup.add(platforms) gameGroup.add(player) gameGroup.add(ledge) scanlineFilter = new Phaser.Filter(game, null, fragmentSrc); scanlineFilter.setResolution(w/4,h/4);, 0, 2000, 2000); game.stage.smoothed = false; renderTexture = game.make.renderTexture(w/4, h/4, 'texture1'); renderTexture2 = game.make.renderTexture(w, h, 'texture2'); renderTexture2.renderer.renderSession.roundPixels = true; renderTexture2.baseTexture.scaleMode = PIXI.scaleModes.NEAREST; stageSprite = game.make.sprite(0,0, renderTexture); stageSprite.smoothed = false; outputSprite = game.add.sprite(0,0, renderTexture2); outputSprite.smoothed = false; outputSprite.filters = [scanlineFilter]; gameMatrix = new Phaser.Matrix(4,0,0,4,0,0); } function preRender(){ // gameGroup.visible = false; } function render(){ // gameGroup.visible = true; // renderTexture.render(player, game.stage.worldTransform, true); // renderTexture2.render(stageSprite, gameMatrix, true); // Debug game.debug.spriteBounds(player, 'pink', false) game.debug.body(player, 'red', false) game.debug.spriteBounds(stageSprite, 'yellow', false) game.debug.body(stageSprite, 'orange', false) game.debug.spriteBounds(outputSprite, 'cyan', false) game.debug.body(outputSprite, 'blue', false) } function update() { game.physics.arcade.collide(player, platforms); // renderTexture.clear() // renderTexture2.clear() outputSprite.sendToBack() renderTexture.render(, null, true); renderTexture2.render(stageSprite, gameMatrix, true); outputSprite.bringToTop() player.body.velocity.x = 0; if (cursors.left.isDown) { player.body.velocity.x = -150;'left'); } else if (cursors.right.isDown) { player.body.velocity.x = 150;'right'); } else { player.animations.stop(); player.frame = 4; } if (cursors.up.isDown && player.body.touching.down) { player.body.velocity.y = -350; } } </script> </body> </html> I've also tried scaling the game up then set the filter to the world but the filter is applied before it is scaled. game.scale.scaleMode = Phaser.ScaleManager.USER_SCALE game.scale.setUserScale(4, 4) game.renderer.renderSession.roundPixels = true Phaser.Canvas.setImageRenderingCrisp(game.canvas) var scanlineFilter = new Phaser.Filter(game, null, fragmentSrc); scanlineFilter.setResolution(game.width / 4, game.height / 4) = [scanlineFilter]; Can anyone help me get this working or suggest a better approach?
  15. Hi, i have a problem with a custom filter. I notice that the result of this simple custom filter change when the sprite are moved from js. Seems to be that vTextureCoord are affected by the position.x value: when i change its value, the filter render a different image. precision mediump float; uniform float frequency; uniform float amplitude; varying vec2 vTextureCoord; uniform sampler2D uSampler; float upDown(float v) { return sin(v) * .5 + .5; } void main (void) { vec2 uv = vTextureCoord; float t1 = frequency * 0.2; float t2 = frequency * 0.35; float v = uv.y; float h = uv.x; float off1 = sin((h + 0.4) * mix(1., 6., upDown(t1))) * amplitude * 0.5; float off2 = sin((h + 0.8) * mix(3., 8., upDown(t2))) * amplitude * 1.5; float off3 = sin((h) * mix(1., 2., upDown(t1))) * amplitude * 0.5; uv = vec2( h + off1 + off2 + off3, v ); gl_FragColor = texture2D(uSampler, uv); } How can I get the same image, even moving or scaling the sprite? Thanks in advance
  16. Hi there - I'm going down a rabbit hole trying to implement a color grading / LUT shader for PIXI. Color grading is where you can you use a sprite as a lookup table to quickly transform one set of colors to another - this is handy for applying realtime contrast and color adjustments. I'm using this as a reference: I've created a filter/shader using the code in the link above: var ColorGradingShader = function(LUTSprite) { var my = this; var code = ` precision lowp float; uniform vec4 filterArea; varying vec2 vTextureCoord; uniform sampler2D uSampler; uniform sampler2D lut; #define MAXCOLOR 15.0 #define COLORS 16.0 #define WIDTH 256.0 #define HEIGHT 16.0 void main() { vec4 px = texture2D(uSampler, vTextureCoord.xy); float cell = px.b * MAXCOLOR; float cell_l = floor(cell); float cell_h = ceil(cell); float half_px_x = 0.5 / WIDTH; float half_px_y = 0.5 / HEIGHT; float r_offset = half_px_x + px.r / COLORS * (MAXCOLOR / COLORS); float g_offset = half_px_y + px.g * (MAXCOLOR / COLORS); vec2 lut_pos_l = vec2(cell_l / COLORS + r_offset, g_offset); vec2 lut_pos_h = vec2(cell_h / COLORS + r_offset, g_offset); vec4 graded_color_l = texture2D(lut, lut_pos_l); vec4 graded_color_h = texture2D(lut, lut_pos_h); vec4 graded_color = mix(graded_color_l, graded_color_h, fract(cell)); gl_FragColor = graded_color; } `;, null, code); my.uniforms.lut = LUTSprite.texture; } ColorGradingShader.prototype = Object.create(PIXI.Filter.prototype); ColorGradingShader.prototype.constructor = ColorGradingShader; export default ColorGradingShader; I then add this to my top level container: //relevant code from a wrapping class this.colorGradingSprite = new PIXI.Sprite.fromImage('/img/lut16.png'); this.pixiContainer.filters = [ this.colorGradingFilter ]; When using any LUT image, including the default without any color adjustments: I go from this: to this: I'm assuming there are some adjustments necessary to either the shader code, or how the lut sprite itself is being loaded - I have no clue.. Any help would be greatly appreciated! And for those curious, here's my end goal: Thanks, Sean
  17. I've been working with PIXI filters recently. If I apply the filter to a sprite with alpha, I've noticed that somewhere along the line the alpha gets premultiplied. For example, I have a test texture with a pixel saved as [255, 255, 255, 128]. When I sample the texture, in a filter Instead of [1.0, 1.0, 1.0, 0.5] the result is [0.5, 0.5, 0.5, 0.5]. How can I turn off this premultiplying behaviour? I've tried 'transparent: false' and 'transparent: "notMultiplied" ' in the webGL renderer settings, but neither of those seemed to make any difference?
  18. I'm experimenting with GLSL shaders in Pixi 4.4, and was trying to make some that would take in two images, the base and an overlay. The shaders would then replace either the Hue, Saturation, or Value of the pixels in the base image with the H/S/V of the corresponding pixel in the overlay image. Transparency on the overlay means "no change." For my tests, I used a 100x100 red square, and the following 100x100 "striped" overlays: That's the Hue overlay, Saturation overlay, and Value overlay respectively. Results were only partially consistent, and all wrong. Here are the results of the Hue and Saturation shaders against a black background. Okay, so the stripes are twice as tall as they should be and the bottom-most stripe is outright missing, as though either the overlay or base were resized as some point in the process. But Value takes the cake: Not only do we have the same problem as above, but there are "teeth" that have appeared off the edge of the 100x100 image (4px in each direction, making a 108x100 image), and there are outlines around every stripe, and if you zoom in especially close you can see that some of the outlines are actually 2 pixels tall, one of near-black, and one of another dark colour, none of which is in the original Value overlay! I'm at a loss to tell if the problem(s) originates in my shader code or in Pixi, especially since tutorials around the net are mum about how to create a second shader2D uniform in any other setup but Pixi. I do want to work with Pixi for this project, however, so a fix for Pixi would be appreciated if the problem really is from there. Here's the HTML/GLSL code. Please don't mind the If statement, I've already had a few ideas on how to get rid of it: <html> <head> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta content="utf-8" http-equiv="encoding"> <style> body { background-color: black; margin: 0; overflow: hidden; } p { color: white; } </style> </head> <body> <script type="text/javascript" src="libs/pixi.js"></script> <script id="shader" type="shader"> #ifdef GL_ES precision mediump float; #endif varying vec2 vTextureCoord; uniform sampler2D uSampler; //The base image uniform sampler2D overlay; //The overlay vec3 rgb2hsv(vec3 c) { vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); vec4 p = mix(vec4(, K.wz), vec4(, K.xy), step(c.b, c.g)); vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); float e = 1.0e-10; return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } vec3 hsv2rgb(vec3 c) { vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract( + * 6.0 - K.www); return c.z * mix(, clamp(p -, 0.0, 1.0), c.y); } void main(void) { vec4 baseRGB = texture2D(uSampler, vTextureCoord); vec4 overlayRGB = texture2D(overlay, vTextureCoord); if(overlayRGB.a > 0.0) { vec3 baseHSV = rgb2hsv(baseRGB.rgb); vec3 overlayHSV = rgb2hsv(overlayRGB.rgb); // Hue // vec3 resultHSV = vec3(overlayHSV.x, baseHSV.y, baseHSV.z); // Saturation // vec3 resultHSV = vec3(baseHSV.x, overlayHSV.y, baseHSV.z); // Value vec3 resultHSV = vec3(baseHSV.x, baseHSV.y, overlayHSV.z); vec3 resultRGB = hsv2rgb(resultHSV); gl_FragColor = vec4(resultRGB.rgb, baseRGB.a); } else { gl_FragColor = baseRGB; } } </script> <script type="text/javascript" src="replaceTest.js"></script> </body> </html> And here's the JS: var width = window.innerWidth; var height = window.innerHeight; var renderer = new PIXI.WebGLRenderer(width, height); document.body.appendChild(renderer.view); var stage = new PIXI.Container(); var sprite = PIXI.Sprite.fromImage('flat.png'); sprite.x = width / 2;//Set it at the center of the screen sprite.y = height / 2; sprite.anchor.set(0.5);//Make sure the center point of the image is at its center, instead of the default top left stage.addChild(sprite); //Create a uniforms object to send to the shader var uniforms = {} uniforms.overlay = { type:'sampler2D', value: PIXI.Texture.fromImage('stripesVal.png') // or stripesSat, stripesHue, etc } //Get shader code as a string var shaderCode = document.getElementById("shader").innerHTML; //Create our Pixi filter using our custom shader code var rasShader = new PIXI.Filter(null,shaderCode,uniforms); console.log(rasShader.uniforms); sprite.filters = [rasShader]; function update() { requestAnimationFrame(update); renderer.render(stage); } update(); Any help would be appreciated!
  19. I use a custom filter in pixi.js for blur but when I use the filter on different objects, the texture of my biggest object overlaps on smaller objects. After some research, I think it's linked to the temporary RenderTarget I use to apply my filter on the 2 axis. First, it seems that the clear parameter of the function filterManager.getRenderTarget() is ignored when I read the source code of the method. But anyway, even if I manually call the clear() method of the RenderTarget at the end of the filter application the result is the same. But if my 3 objects have different dimensions (let say 100x100, 200x200 and 400x400) in order to get a different RenderTarget for each, the rendering is OK. Any idea ? Thanks
  20. Hello everyone, is there any special limitation for using filters? I can see from example on Phaser web site that this code should work but in my app it does not work'logo', 'assets/images/preload_bg.png');'gray', ''); var logo =,, 'logo'); logo.anchor.setTo(0.5, 0.5); var gray ='Gray'); logo.filters = [gray]; The sprite is added but it's not affected by filter at all... I checked: that Phaser.Filter.Gray exists, gray object is really filer object and logo has it within filters property. What else I can do to find issue? Thanks in advance
  21. I am trying to do the following: draw some shapes to a Graphics object render those shapes to a RenderTexture without clearing it first, so that the shapes are "painted onto the texture" apply a filter (a blur, for example) to the RenderTexture without ever clearing it so the current blur is processing an already blurred texture from the previous frame render to the screen repeat, never clearing the previously rendered display This is basically continuously blurring the display so that the longer something has been displayed, the more blurred it gets. Here is where I am at so far: class Project { constructor() { this.renderer = new PIXI.WebGLRenderer(window.innerWidth, window.innerHeight, { antialias: true }); this.renderTexture = PIXI.RenderTexture.create(this.renderer.width, this.renderer.height); document.body.appendChild(this.renderer.view); this.stage = new PIXI.Container(); this.canvas = new PIXI.Graphics(); this.sprite = new PIXI.Sprite(this.renderTexture); this.blurFilter = new PIXI.filters.BlurFilter(); this.stage.addChild(this.sprite); this.draw(); } draw() { var mousePosition =; this.canvas.clear(); this.canvas.lineStyle(0); this.canvas.beginFill(0x666666); this.canvas.drawCircle(mousePosition.x, mousePosition.y, 50); // Somehow apply a blur to this.renderTexture without clearing it so the next line renders the // canvas on top of already blurred elements. This display will be fed into the next render // cycle without being cleared so that the blurs are "additive". this.renderer.render(this.canvas, this.renderTexture, false); this.renderer.render(this.stage); requestAnimationFrame(this.draw.bind(this)); } } Does this make sense? Am I on the right track?
  22. I'm struggling with an approach to add a water effect to an area of container. I'd like to have the area in green distort the area below it via a shader, but also have the ability for this water area to "rise/fall". The rise/fall is of no problem when it's just a sprite I can move up and down as necessary - but being able to apply a shader to just that specific area is throwing me for a loop. Adding a filter directly to the sprite won't distort anything since it's not accounting for the pixels behind it.. Is there are way to capture this particular area, save it to a buffer, and apply a filter, and put it back in place? RenderTexture seems like it might be in the right direction, but I can't see where I can grab an area of an existing container... Any help would be much appreciated!
  23. Dear community: We are learning about phaser and we have a doubt for this forum. We are trying to develop a simple shoot game with a plane and enemies. The goal is that when a enemy is killed, a fire animation will be showed. We did this with a spritesheet and the result is good but we want to improve the quality with this filter: The problem is that we can't move the fireball effect over each enemy. The fire is always in the same position (left-bottom corner), and we can not change it. Probably the problem is the opengl code but we are not sure. Anyone can add this fireball effect to be showed when the enemy is killed? I thing that this code will be useful for the developers as us.
  24. Hi, I've long wanted to implement a neat looking invisibility effect for my game, tried using DisplacementFilter, but stumbled upon an issue with scale property. While it works correctly to displace areas under the displacement sprite I created, it also displaces entire container on which the filter is applied. I presume its from non existent knowledge about the subject and how those filters work, but I'm still hoping for either a fix or a reasonable explanation if anyone can help me with this please. Everything in my code follows DisplacementMap example on (one with the grass and magnifying glass). What is different is my stage tree. I have 3 containers for each layer and inside those there are separate containers for chunks that hold the map data, since it comes from the server. const playerSprite = new PIXI.Sprite(new PIXI.Texture(PIXI.utils.TextureCache['player.eyes'])); const displacementSprite = new PIXI.Sprite( new PIXI.Texture(PIXI.utils.TextureCache['player.normal']) ); let displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite); playerSprite.position.set(16 / globalScale * fs, (8 - globalScale) / globalScale * fs); playerSprite.scale.set(globalScale, globalScale) this.scene.addChild(playerSprite); this.scene.addChild(displacementSprite); displacementFilter.scale.x = 20; displacementFilter.scale.y = 20; displacementFilter.enabled = true; displacementSprite.position.set(16 / globalScale * fs, (8 - globalScale) / globalScale * fs); displacementSprite.scale.set(globalScale, globalScale) return { scene: this.scene, filter: displacementFilter }; the return value from this block is added to the main stage container, and filters are applied to bottom 2 layers. Should i perhaps look into filterArea? Here is the undesired effect on the edges. You can also see the slanted top layer on the trees. so 2 layers are moved by the filters scale property.
  25. The docs say that Sprite.shader "will be used to render the sprite", but this doesn't work for Pixi V4 so I'm using Sprite.filters instead. I set filterArea.width and filterArea.height once and then each frame I set filterArea.x and filterArea.y to sprite.x and sprite.y. But IDK if this is good practice or is there a better performing way? Here's example code that shows what I mean: var app = new PIXI.Application({width: window.innerWidth, height: window.innerHeight}); document.body.appendChild(app.view); // Create sprite var sprite = new PIXI.Sprite(); sprite.filterArea = new PIXI.Rectangle( sprite.position.x, sprite.position.y, 100, 100 ); app.stage.addChild(sprite); // Stop application wait for load to finish app.stop(); PIXI.loader.add('shader', 'shader.frag') .load(onLoaded); var filter; // Handle the load completed function onLoaded (loader,res) { // Create the new filter, arguments: (vertexShader, fragmentSource) filter = new PIXI.Filter(null,; // Add the filter sprite.filters = [filter]; // Resume application update app.start(); } // Animate app.ticker.add(function(delta) { sprite.x += 1.5 * delta; sprite.filterArea.x = sprite.x; filter.uniforms.customUniform += 0.04 * delta; });