UPDATE 01/07 :
I finally find out the problem with the problem of same shader but different result in processing and webgl, it’s because i didn’t set the blend function right, once i got it right the result is identical, you can check the link above. Besides, i use video as a texture instead of image of sequence, the mask which was done with global composite operation is now replace by another fragment shader, therefore reduce a lot of loadings.
Global Composite Operation
the first problem I have is how to mask a video, I find some articles but they are not working for me, the main reason is the graphics of the flower are from images, and they have alpha gradient inside. It is very important for me to keep these alpha gradients, it looks much better on the visual side. So at the end i use image sequence instead of video, and using context2d.globalCompositeOperation to mask it.
this.ctx.clearRect(0, 0, W, H); this.ctx.globalCompositeOperation = "source-over"; // Draw Flowers and Particles this.ctx.globalCompositeOperation = "source-in"; this.ctx.drawImage(this.bgs[this.currentFrame], 0, 0, W, H); // Draw the image sequence of the background video
In fact it’s very easy to create this effect, the only thing to be careful is don’t forget to reset the globalCompositeOperation every time you render :
this.ctx.globalCompositeOperation = "source-over";
or it will keep rendering in “source-in” then you won’t be able to see anything.
Drawing Images with different transparency on the same canvas
When trying to create the particles effect i encounter this problem : each of my particles have its own transparency, and I’m using image for my particles. The way to draw image with transparency on a canvas is using globalAlpha, but this will change the alpha of the canvas, not just one single particle. Luckily i found the solution : context2d.save() / context2s.restore(); I am very surprised when i realise this, i thought these 2 methods are for transformations, but apparently they are doing more then that :
var pp = this.particles[i]; this.ctx.save(); this.ctx.globalAlpha = pp.alpha; this.ctx.drawImage(flamming.imgParticle, pp.position.x, pp.position.y, pp.scale, pp.scale); this.ctx.restore();
so before you setting the globalAlpha, call the context.save(), and call context.restore() after you done drawing, simple as that !
GLTexture / GLTextureFilter
When i was building this in Processing, i am using the GLGraphic library, it’s very easy to use. These are the 2 classes inside, the GLTextureFilter take a source from a GLSL fragment shader, all you need to do is write your fragment shader , then call :
1. render the flowers ( the original render)
2. using the original render and apply a vertical blur to get the first blur version
3. using this first blur version and apply a horizontal blur to get the full blur version
4. combine the original render and this full blur version, mix it with each pixel’s distance to the center.
So i need to create 3 different Filter : Vertical Blur Filter, Horizontal Blur Filter and the last one Mix Filter, in the code it’s like this :
// Init this.glTexture = new GLTexture(this.gl, this.canvas); this.outputHBlur = new GLTexture(this.gl, null, 1024, 1024); this.outputBlur = new GLTexture(this.gl, null, 1024, 1024); this.outputEdgeBlur = new GLTexture(this.gl, null, 1024, 1024); this.glFilterHBlur = new GLTextureFilter(this.gl, "shader-vs", "shader-fs-hblur"); this.glFilterHBlur.setParameter("h", "float", 1/1024); this.glFilterVBlur = new GLTextureFilter(this.gl, "shader-vs", "shader-fs-vblur"); this.glFilterVBlur.setParameter("v", "float", 1/1024); this.glFilterEdgeBlur = new GLTextureFilter(this.gl, "shader-vs", "shader-fs-edgeblur"); // Render this.glTexture.updateTexture(this.canvas); this.glFilterHBlur.apply([this.glTexture], this.outputHBlur); this.glFilterVBlur.apply([this.outputHBlur], this.outputBlur); this.glFilterEdgeBlur.apply([this.outputBlur, this.glTexture], this.outputEdgeBlur); renderImage(this.gl, this.outputEdgeBlur);
It’s really simple and easy, however these 2 classes are not done yet, still some work to do, i’ll put them on my github when i finish these tasks, and will keep on working for more features.
Another thing I love with WebGL is that it’s using the GLSL for shaders, and it’s the same with GLGraphics, this means i can basically use the same shader program for both, it’s amazing! Compare to AGAL of flash, AGAL more difficult to program and can be only used in flash, that’s pity.
Same Shader, Different result
Anyway that’s about it for right now, hope you enjoy it and stay tuned for the bigger version on Processing !