Tree Glow Shader

by roomyrooms

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/5.2.2/pixi.min.js"></script>

<script type="x-data-url" id="tree-url">
  data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAABACAYAAAB7jnWuAAAEdElEQVRoQ72YS09UQRCFe4xPEIUxwSca4oKFMbpgY6IrjStXJrrwn/kXNHFtjK7YutD4SDQaAig+EkcCCArGMefKmdTUrequuQTvhuHSXfXVqUf30ErbeMavn+5i+9dH862mZhpvhPNrV35Ufh/PDDeGGBiAUZ899SdNTq73AKjAoGoMBCCjnp09UAHg5/sPuxKA8ODzIDBhADiXUeucA4QAEqakSAjAitwDkO+hxo4DMHINFHGOPUUFWHRYTGlZfDnn0TrIAmjpm/R6SYkdB3j+ZDitzb1x/RRTMHRmqntwar0nf04F3Y6rbw5knRdrACmAEQkgnViFp9+VIFwF2Pd6uMhi9AaQhGgMAOkvXP036yOOrNR0Pv6qXu9dHXVT4SoAgI2DS6l9cl9lxBq1eCdH7/flVho7VB2QCZ/ls+fTfhPCBGDhNWk77Zg2uis/TSV2BAAqSBA4b43sr1i0EjUATj5Wf1QFL3K9XyvRB6AnX6n4cjm3wOGcNcXucAFgQM56WWzSeDRy7mGR9gFQdl6xNH0EhHsiQLIOWlJ26Zg3nqgSEkC3ovy9poB32fCOWjryUpIrWlkzZgrklYsAvPdpw00AOKCQAjw4JasUcMpFW047l1PS+2zZhgphALakFbmlXESxCgAL5V1fbizNAeuWnKsdCd+rgVwKSnmORm4dZAi0UkAeu16F61OP67zaKSnH/b0U6GtXyYDlOLdHK4B25DCqFMCVSz+ebFiXi1yro8H0LHAB9LznBCs5YLq8AGoAMAgVNo//rGxrRxwe8r1UoFSo3hnRSwEXyFR4x6wFkQMoHdeA6B3HGsCaXJY6el3Jqb4d9d0HeBHl9YnG5RXLOtlKTqUdfMZtmTflGgBrIXIueDDWXus2hHUugJQqAhNZY92Ma5dSLw0RB17k3o24poDsCKZCSofc6frwwJge5hvrrG/J2W9GNM5JKQFyKfLybcEWv55zUFmb8dXNUoS59qKWtkIAcsP0iXb39JE91auHy6NJpiqXay9VjQCunNub5j5305ljrXT37eGa7dx/RPTibQMABM/8t830dLEzsL2BNyAFd26Mp3cv19K+4Y1Kif8FcAuOpk+07wHg9fPVNHLotwa4vSXx/ejciCpQOZcAC7NL1e9KAQLgTyGIEkDPMQFunj967/KlsRQA4JYsiAdQc8zo0QETk6O1FIg6kCrITJggIQDkHZbQ/2g9PCvLu/tqgAD0+HSxo0HCALXoAXBxYih11jaLAFj3bGENLWkpUYOwFMjKzwihAB5A4WkP/ZuOGedmYWqAYu5ZfFYKkB50xdZQCtVCCMCqfNaCbEV8xvuZVxteCmoqSAA3egwePIgekUN22YpwyAOKKYqqkAVA8aHt+FBeONMAXCNBMhC9YiwCyEZmZWswKTlbNtOOfWkI1YCEkAOJ7ws519v7WjHchtoKCpNV/+DFF6/is87xx9Ak1FakCgNEH56E9Gd2hYRBvp2JV4ycC0qnIdYVQSyFtt4Vj+QIgLQfgSk6lQb/Ag59fOZXcqFDAAAAAElFTkSuQmCC
</script>

JavaScript

var treeUrl = document.getElementById('tree-url').textContent;

var fragmentShader = `
precision mediump float;

varying vec2 vTextureCoord;

uniform sampler2D uSampler;
uniform float time;

void main() {
  vec4 newcol = texture2D(uSampler, vTextureCoord);
	float wavewidth = 1.0;
  float waveintensity = 0.;
  vec3 wave = vec3(0.05,0.5,0.25);
  
  float coordval = vTextureCoord.y;
  float timeval = fract(time*0.001-coordval)*0.75-0.25;
  float step = smoothstep(timeval+0.01, timeval+wavewidth+0.05, vTextureCoord.y);
  waveintensity = step;
  gl_FragColor = newcol + vec4(wave * waveintensity * newcol.a, newcol.a);
}`

function defaultValue(inputValue, defaultValue) {
    inputValue = typeof inputValue !== 'undefined' ? inputValue : defaultValue;
    return inputValue;
}

function WindFilter(uPolar, uGlowWidth, uGlowColor) {
    PIXI.Filter.call(this,undefined,fragmentShader);
    this.uniforms.time = performance.now();
}

WindFilter.prototype = Object.create(PIXI.Filter.prototype);
WindFilter.prototype.constructor = WindFilter;

WindFilter.prototype.apply = function (filterManager, input, output, clear) {
		clear = PIXI.CLEAR_MODES;
    this.padding = 5;
    this.uniforms.time = performance.now();
    // draw the filter...
    filterManager.applyFilter(this, input, output);
}

PIXI.settings.MIPMAP_TEXTURES = PIXI.MIPMAP_MODES.ON;
var stage = new PIXI.Container();

// create a renderer instance.
var renderer = PIXI.autoDetectRenderer(512, 512);
renderer.roundPixels = true;
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;

// tex creation
var treeBaseTexture = new PIXI.BaseTexture(treeUrl);
var treeTexture = new PIXI.Texture(treeBaseTexture);
var treeSprite = new PIXI.Sprite(treeTexture);

var baseTexture = new PIXI.Texture(PIXI.Texture.WHITE);
var baseSprite = new PIXI.Sprite(baseTexture);
var bgSprite = new PIXI.Sprite(baseTexture);

baseSprite.width = 128
baseSprite.height = 128

bgSprite.width = 512
bgSprite.height = 512
bgSprite.tint = 0x555555

// ADDITIVE...