diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 04fb5c2..37a910b 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -80,7 +80,12 @@ bounds.height = bounds.height | 0; - + // padding! + var padding = filters[0].padding; + bounds.x -= padding; + bounds.y -= padding; + bounds.width += padding * 2; + bounds.height += padding * 2 if(this.renderer.currentRenderTarget.transform) diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 04fb5c2..37a910b 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -80,7 +80,12 @@ bounds.height = bounds.height | 0; - + // padding! + var padding = filters[0].padding; + bounds.x -= padding; + bounds.y -= padding; + bounds.width += padding * 2; + bounds.height += padding * 2 if(this.renderer.currentRenderTarget.transform) diff --git a/src/filters/dropshadow/BlurYTintFilter.js b/src/filters/dropshadow/BlurYTintFilter.js new file mode 100644 index 0000000..aa5195d --- /dev/null +++ b/src/filters/dropshadow/BlurYTintFilter.js @@ -0,0 +1,50 @@ +var core = require('../../core'), + blurFactor = 1 / 7000; + +/** + * The BlurYTintFilter applies a vertical Gaussian blur to an object. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function BlurYTintFilter() +{ + core.AbstractFilter.call(this, + // vertex shader + require('fs').readFileSync(__dirname + '/blurYTint.vert', 'utf8'), + // fragment shader + require('fs').readFileSync(__dirname + '/blurYTint.frag', 'utf8'), + // set the uniforms + { + blur: { type: '1f', value: 1 / 512 }, + color: { type: 'c', value: [0,0,0]}, + alpha: { type: '1f', value: 0.7 }, + offset: { type: '2f', value:[5, 5]} + } + ); +} + +BlurYTintFilter.prototype = Object.create(core.AbstractFilter.prototype); +BlurYTintFilter.prototype.constructor = BlurYTintFilter; +module.exports = BlurYTintFilter; + +Object.defineProperties(BlurYTintFilter.prototype, { + /** + * Sets the strength of both the blur. + * + * @member {number} + * @memberof BlurYTintFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.uniforms.blur.value / blurFactor; + }, + set: function (value) + { + this.uniforms.blur.value = blurFactor * value; + } + } +}); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 04fb5c2..37a910b 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -80,7 +80,12 @@ bounds.height = bounds.height | 0; - + // padding! + var padding = filters[0].padding; + bounds.x -= padding; + bounds.y -= padding; + bounds.width += padding * 2; + bounds.height += padding * 2 if(this.renderer.currentRenderTarget.transform) diff --git a/src/filters/dropshadow/BlurYTintFilter.js b/src/filters/dropshadow/BlurYTintFilter.js new file mode 100644 index 0000000..aa5195d --- /dev/null +++ b/src/filters/dropshadow/BlurYTintFilter.js @@ -0,0 +1,50 @@ +var core = require('../../core'), + blurFactor = 1 / 7000; + +/** + * The BlurYTintFilter applies a vertical Gaussian blur to an object. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function BlurYTintFilter() +{ + core.AbstractFilter.call(this, + // vertex shader + require('fs').readFileSync(__dirname + '/blurYTint.vert', 'utf8'), + // fragment shader + require('fs').readFileSync(__dirname + '/blurYTint.frag', 'utf8'), + // set the uniforms + { + blur: { type: '1f', value: 1 / 512 }, + color: { type: 'c', value: [0,0,0]}, + alpha: { type: '1f', value: 0.7 }, + offset: { type: '2f', value:[5, 5]} + } + ); +} + +BlurYTintFilter.prototype = Object.create(core.AbstractFilter.prototype); +BlurYTintFilter.prototype.constructor = BlurYTintFilter; +module.exports = BlurYTintFilter; + +Object.defineProperties(BlurYTintFilter.prototype, { + /** + * Sets the strength of both the blur. + * + * @member {number} + * @memberof BlurYTintFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.uniforms.blur.value / blurFactor; + }, + set: function (value) + { + this.uniforms.blur.value = blurFactor * value; + } + } +}); diff --git a/src/filters/dropshadow/DropShadowFilter.js b/src/filters/dropshadow/DropShadowFilter.js new file mode 100644 index 0000000..b01856f --- /dev/null +++ b/src/filters/dropshadow/DropShadowFilter.js @@ -0,0 +1,167 @@ +var core = require('../../core'), + BlurXFilter = require('../blur/BlurXFilter'), + BlurYTintFilter = require('./BlurYTintFilter'); + +/** + * The DropShadowFilter applies a Gaussian blur to an object. + * The strength of the blur can be set for x- and y-axis separately. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function DropShadowFilter() +{ + core.AbstractFilter.call(this); + + this.blurXFilter = new BlurXFilter(); + this.blurYTintFilter = new BlurYTintFilter(); + + this.defaultFilter = new core.AbstractFilter(); + + this.padding = 30; + + this._dirtyPosition = true; + this._angle = 45 * Math.PI / 180; + this._distance = 10; + this.alpha = 0.75; + this.hideObject = false; + this.blendMode = core.CONST.BLEND_MODES.MULTIPLY; +} + +DropShadowFilter.prototype = Object.create(core.AbstractFilter.prototype); +DropShadowFilter.prototype.constructor = DropShadowFilter; +module.exports = DropShadowFilter; + +DropShadowFilter.prototype.applyFilter = function (renderer, input, output) +{ + var renderTarget = renderer.filterManager.getRenderTarget(true); + + //TODO - copyTexSubImage2D could be used here? + if(this._dirtyPosition) + { + this._dirtyPosition = false; + + this.blurYTintFilter.uniforms.offset.value[0] = Math.sin(this._angle) * this._distance; + this.blurYTintFilter.uniforms.offset.value[1] = Math.cos(this._angle) * this._distance; + } + + this.blurXFilter.applyFilter(renderer, input, renderTarget); + + renderer.blendModeManager.setBlendMode(this.blendMode); + + this.blurYTintFilter.applyFilter(renderer, renderTarget, output); + + renderer.blendModeManager.setBlendMode(core.CONST.BLEND_MODES.NORMAL); + + if(!this.hideObject) + { + + this.defaultFilter.applyFilter(renderer, input, output); + } + + + renderer.filterManager.returnRenderTarget(renderTarget); +}; + +Object.defineProperties(DropShadowFilter.prototype, { + /** + * Sets the strength of both the blurX and blurY properties simultaneously + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.blurXFilter.blur; + }, + set: function (value) + { + this.blurXFilter.blur = this.blurYTintFilter.blur = value; + } + }, + + /** + * Sets the strength of the blurX property + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blurX: { + get: function () + { + return this.blurXFilter.blur; + }, + set: function (value) + { + this.blurXFilter.blur = value; + } + }, + + /** + * Sets the strength of the blurY property + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blurY: { + get: function () + { + return this.blurYTintFilter.blur; + }, + set: function (value) + { + this.blurYTintFilter.blur = value; + } + }, + + color: { + get: function () + { + return core.utils.rgb2hex( this.blurYTintFilter.uniforms.color.value ); + }, + set: function (value) + { + this.blurYTintFilter.uniforms.color.value = core.utils.hex2rgb(value); + } + }, + + alpha: { + get: function () + { + return this.blurYTintFilter.uniforms.alpha.value; + }, + set: function (value) + { + this.blurYTintFilter.uniforms.alpha.value = value; + } + }, + + distance: { + get: function () + { + return this._distance + }, + set: function (value) + { + this._dirtyPosition = true; + this._distance = value; + } + }, + + angle: { + get: function () + { + return this._angle + }, + set: function (value) + { + this._dirtyPosition = true; + this._angle = value; + } + } +}); diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 04fb5c2..37a910b 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -80,7 +80,12 @@ bounds.height = bounds.height | 0; - + // padding! + var padding = filters[0].padding; + bounds.x -= padding; + bounds.y -= padding; + bounds.width += padding * 2; + bounds.height += padding * 2 if(this.renderer.currentRenderTarget.transform) diff --git a/src/filters/dropshadow/BlurYTintFilter.js b/src/filters/dropshadow/BlurYTintFilter.js new file mode 100644 index 0000000..aa5195d --- /dev/null +++ b/src/filters/dropshadow/BlurYTintFilter.js @@ -0,0 +1,50 @@ +var core = require('../../core'), + blurFactor = 1 / 7000; + +/** + * The BlurYTintFilter applies a vertical Gaussian blur to an object. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function BlurYTintFilter() +{ + core.AbstractFilter.call(this, + // vertex shader + require('fs').readFileSync(__dirname + '/blurYTint.vert', 'utf8'), + // fragment shader + require('fs').readFileSync(__dirname + '/blurYTint.frag', 'utf8'), + // set the uniforms + { + blur: { type: '1f', value: 1 / 512 }, + color: { type: 'c', value: [0,0,0]}, + alpha: { type: '1f', value: 0.7 }, + offset: { type: '2f', value:[5, 5]} + } + ); +} + +BlurYTintFilter.prototype = Object.create(core.AbstractFilter.prototype); +BlurYTintFilter.prototype.constructor = BlurYTintFilter; +module.exports = BlurYTintFilter; + +Object.defineProperties(BlurYTintFilter.prototype, { + /** + * Sets the strength of both the blur. + * + * @member {number} + * @memberof BlurYTintFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.uniforms.blur.value / blurFactor; + }, + set: function (value) + { + this.uniforms.blur.value = blurFactor * value; + } + } +}); diff --git a/src/filters/dropshadow/DropShadowFilter.js b/src/filters/dropshadow/DropShadowFilter.js new file mode 100644 index 0000000..b01856f --- /dev/null +++ b/src/filters/dropshadow/DropShadowFilter.js @@ -0,0 +1,167 @@ +var core = require('../../core'), + BlurXFilter = require('../blur/BlurXFilter'), + BlurYTintFilter = require('./BlurYTintFilter'); + +/** + * The DropShadowFilter applies a Gaussian blur to an object. + * The strength of the blur can be set for x- and y-axis separately. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function DropShadowFilter() +{ + core.AbstractFilter.call(this); + + this.blurXFilter = new BlurXFilter(); + this.blurYTintFilter = new BlurYTintFilter(); + + this.defaultFilter = new core.AbstractFilter(); + + this.padding = 30; + + this._dirtyPosition = true; + this._angle = 45 * Math.PI / 180; + this._distance = 10; + this.alpha = 0.75; + this.hideObject = false; + this.blendMode = core.CONST.BLEND_MODES.MULTIPLY; +} + +DropShadowFilter.prototype = Object.create(core.AbstractFilter.prototype); +DropShadowFilter.prototype.constructor = DropShadowFilter; +module.exports = DropShadowFilter; + +DropShadowFilter.prototype.applyFilter = function (renderer, input, output) +{ + var renderTarget = renderer.filterManager.getRenderTarget(true); + + //TODO - copyTexSubImage2D could be used here? + if(this._dirtyPosition) + { + this._dirtyPosition = false; + + this.blurYTintFilter.uniforms.offset.value[0] = Math.sin(this._angle) * this._distance; + this.blurYTintFilter.uniforms.offset.value[1] = Math.cos(this._angle) * this._distance; + } + + this.blurXFilter.applyFilter(renderer, input, renderTarget); + + renderer.blendModeManager.setBlendMode(this.blendMode); + + this.blurYTintFilter.applyFilter(renderer, renderTarget, output); + + renderer.blendModeManager.setBlendMode(core.CONST.BLEND_MODES.NORMAL); + + if(!this.hideObject) + { + + this.defaultFilter.applyFilter(renderer, input, output); + } + + + renderer.filterManager.returnRenderTarget(renderTarget); +}; + +Object.defineProperties(DropShadowFilter.prototype, { + /** + * Sets the strength of both the blurX and blurY properties simultaneously + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.blurXFilter.blur; + }, + set: function (value) + { + this.blurXFilter.blur = this.blurYTintFilter.blur = value; + } + }, + + /** + * Sets the strength of the blurX property + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blurX: { + get: function () + { + return this.blurXFilter.blur; + }, + set: function (value) + { + this.blurXFilter.blur = value; + } + }, + + /** + * Sets the strength of the blurY property + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blurY: { + get: function () + { + return this.blurYTintFilter.blur; + }, + set: function (value) + { + this.blurYTintFilter.blur = value; + } + }, + + color: { + get: function () + { + return core.utils.rgb2hex( this.blurYTintFilter.uniforms.color.value ); + }, + set: function (value) + { + this.blurYTintFilter.uniforms.color.value = core.utils.hex2rgb(value); + } + }, + + alpha: { + get: function () + { + return this.blurYTintFilter.uniforms.alpha.value; + }, + set: function (value) + { + this.blurYTintFilter.uniforms.alpha.value = value; + } + }, + + distance: { + get: function () + { + return this._distance + }, + set: function (value) + { + this._dirtyPosition = true; + this._distance = value; + } + }, + + angle: { + get: function () + { + return this._angle + }, + set: function (value) + { + this._dirtyPosition = true; + this._angle = value; + } + } +}); diff --git a/src/filters/dropshadow/blurYTint.frag b/src/filters/dropshadow/blurYTint.frag new file mode 100644 index 0000000..5701a3d --- /dev/null +++ b/src/filters/dropshadow/blurYTint.frag @@ -0,0 +1,27 @@ +precision lowp float; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +uniform float blur; +uniform vec3 color; +uniform float alpha; + +uniform sampler2D uSampler; + +void main(void) +{ + vec4 sum = vec4(0.0); + + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05; + + gl_FragColor =vec4( color.rgb * sum.a * alpha, sum.a * alpha ); +} diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 04fb5c2..37a910b 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -80,7 +80,12 @@ bounds.height = bounds.height | 0; - + // padding! + var padding = filters[0].padding; + bounds.x -= padding; + bounds.y -= padding; + bounds.width += padding * 2; + bounds.height += padding * 2 if(this.renderer.currentRenderTarget.transform) diff --git a/src/filters/dropshadow/BlurYTintFilter.js b/src/filters/dropshadow/BlurYTintFilter.js new file mode 100644 index 0000000..aa5195d --- /dev/null +++ b/src/filters/dropshadow/BlurYTintFilter.js @@ -0,0 +1,50 @@ +var core = require('../../core'), + blurFactor = 1 / 7000; + +/** + * The BlurYTintFilter applies a vertical Gaussian blur to an object. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function BlurYTintFilter() +{ + core.AbstractFilter.call(this, + // vertex shader + require('fs').readFileSync(__dirname + '/blurYTint.vert', 'utf8'), + // fragment shader + require('fs').readFileSync(__dirname + '/blurYTint.frag', 'utf8'), + // set the uniforms + { + blur: { type: '1f', value: 1 / 512 }, + color: { type: 'c', value: [0,0,0]}, + alpha: { type: '1f', value: 0.7 }, + offset: { type: '2f', value:[5, 5]} + } + ); +} + +BlurYTintFilter.prototype = Object.create(core.AbstractFilter.prototype); +BlurYTintFilter.prototype.constructor = BlurYTintFilter; +module.exports = BlurYTintFilter; + +Object.defineProperties(BlurYTintFilter.prototype, { + /** + * Sets the strength of both the blur. + * + * @member {number} + * @memberof BlurYTintFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.uniforms.blur.value / blurFactor; + }, + set: function (value) + { + this.uniforms.blur.value = blurFactor * value; + } + } +}); diff --git a/src/filters/dropshadow/DropShadowFilter.js b/src/filters/dropshadow/DropShadowFilter.js new file mode 100644 index 0000000..b01856f --- /dev/null +++ b/src/filters/dropshadow/DropShadowFilter.js @@ -0,0 +1,167 @@ +var core = require('../../core'), + BlurXFilter = require('../blur/BlurXFilter'), + BlurYTintFilter = require('./BlurYTintFilter'); + +/** + * The DropShadowFilter applies a Gaussian blur to an object. + * The strength of the blur can be set for x- and y-axis separately. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function DropShadowFilter() +{ + core.AbstractFilter.call(this); + + this.blurXFilter = new BlurXFilter(); + this.blurYTintFilter = new BlurYTintFilter(); + + this.defaultFilter = new core.AbstractFilter(); + + this.padding = 30; + + this._dirtyPosition = true; + this._angle = 45 * Math.PI / 180; + this._distance = 10; + this.alpha = 0.75; + this.hideObject = false; + this.blendMode = core.CONST.BLEND_MODES.MULTIPLY; +} + +DropShadowFilter.prototype = Object.create(core.AbstractFilter.prototype); +DropShadowFilter.prototype.constructor = DropShadowFilter; +module.exports = DropShadowFilter; + +DropShadowFilter.prototype.applyFilter = function (renderer, input, output) +{ + var renderTarget = renderer.filterManager.getRenderTarget(true); + + //TODO - copyTexSubImage2D could be used here? + if(this._dirtyPosition) + { + this._dirtyPosition = false; + + this.blurYTintFilter.uniforms.offset.value[0] = Math.sin(this._angle) * this._distance; + this.blurYTintFilter.uniforms.offset.value[1] = Math.cos(this._angle) * this._distance; + } + + this.blurXFilter.applyFilter(renderer, input, renderTarget); + + renderer.blendModeManager.setBlendMode(this.blendMode); + + this.blurYTintFilter.applyFilter(renderer, renderTarget, output); + + renderer.blendModeManager.setBlendMode(core.CONST.BLEND_MODES.NORMAL); + + if(!this.hideObject) + { + + this.defaultFilter.applyFilter(renderer, input, output); + } + + + renderer.filterManager.returnRenderTarget(renderTarget); +}; + +Object.defineProperties(DropShadowFilter.prototype, { + /** + * Sets the strength of both the blurX and blurY properties simultaneously + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.blurXFilter.blur; + }, + set: function (value) + { + this.blurXFilter.blur = this.blurYTintFilter.blur = value; + } + }, + + /** + * Sets the strength of the blurX property + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blurX: { + get: function () + { + return this.blurXFilter.blur; + }, + set: function (value) + { + this.blurXFilter.blur = value; + } + }, + + /** + * Sets the strength of the blurY property + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blurY: { + get: function () + { + return this.blurYTintFilter.blur; + }, + set: function (value) + { + this.blurYTintFilter.blur = value; + } + }, + + color: { + get: function () + { + return core.utils.rgb2hex( this.blurYTintFilter.uniforms.color.value ); + }, + set: function (value) + { + this.blurYTintFilter.uniforms.color.value = core.utils.hex2rgb(value); + } + }, + + alpha: { + get: function () + { + return this.blurYTintFilter.uniforms.alpha.value; + }, + set: function (value) + { + this.blurYTintFilter.uniforms.alpha.value = value; + } + }, + + distance: { + get: function () + { + return this._distance + }, + set: function (value) + { + this._dirtyPosition = true; + this._distance = value; + } + }, + + angle: { + get: function () + { + return this._angle + }, + set: function (value) + { + this._dirtyPosition = true; + this._angle = value; + } + } +}); diff --git a/src/filters/dropshadow/blurYTint.frag b/src/filters/dropshadow/blurYTint.frag new file mode 100644 index 0000000..5701a3d --- /dev/null +++ b/src/filters/dropshadow/blurYTint.frag @@ -0,0 +1,27 @@ +precision lowp float; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +uniform float blur; +uniform vec3 color; +uniform float alpha; + +uniform sampler2D uSampler; + +void main(void) +{ + vec4 sum = vec4(0.0); + + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05; + + gl_FragColor =vec4( color.rgb * sum.a * alpha, sum.a * alpha ); +} diff --git a/src/filters/dropshadow/blurYTint.vert b/src/filters/dropshadow/blurYTint.vert new file mode 100644 index 0000000..a7bae1a --- /dev/null +++ b/src/filters/dropshadow/blurYTint.vert @@ -0,0 +1,16 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; +uniform vec2 offset; + +uniform mat3 projectionMatrix; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3((aVertexPosition+offset), 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); +} diff --git a/src/core/renderers/webgl/managers/FilterManager.js b/src/core/renderers/webgl/managers/FilterManager.js index 04fb5c2..37a910b 100644 --- a/src/core/renderers/webgl/managers/FilterManager.js +++ b/src/core/renderers/webgl/managers/FilterManager.js @@ -80,7 +80,12 @@ bounds.height = bounds.height | 0; - + // padding! + var padding = filters[0].padding; + bounds.x -= padding; + bounds.y -= padding; + bounds.width += padding * 2; + bounds.height += padding * 2 if(this.renderer.currentRenderTarget.transform) diff --git a/src/filters/dropshadow/BlurYTintFilter.js b/src/filters/dropshadow/BlurYTintFilter.js new file mode 100644 index 0000000..aa5195d --- /dev/null +++ b/src/filters/dropshadow/BlurYTintFilter.js @@ -0,0 +1,50 @@ +var core = require('../../core'), + blurFactor = 1 / 7000; + +/** + * The BlurYTintFilter applies a vertical Gaussian blur to an object. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function BlurYTintFilter() +{ + core.AbstractFilter.call(this, + // vertex shader + require('fs').readFileSync(__dirname + '/blurYTint.vert', 'utf8'), + // fragment shader + require('fs').readFileSync(__dirname + '/blurYTint.frag', 'utf8'), + // set the uniforms + { + blur: { type: '1f', value: 1 / 512 }, + color: { type: 'c', value: [0,0,0]}, + alpha: { type: '1f', value: 0.7 }, + offset: { type: '2f', value:[5, 5]} + } + ); +} + +BlurYTintFilter.prototype = Object.create(core.AbstractFilter.prototype); +BlurYTintFilter.prototype.constructor = BlurYTintFilter; +module.exports = BlurYTintFilter; + +Object.defineProperties(BlurYTintFilter.prototype, { + /** + * Sets the strength of both the blur. + * + * @member {number} + * @memberof BlurYTintFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.uniforms.blur.value / blurFactor; + }, + set: function (value) + { + this.uniforms.blur.value = blurFactor * value; + } + } +}); diff --git a/src/filters/dropshadow/DropShadowFilter.js b/src/filters/dropshadow/DropShadowFilter.js new file mode 100644 index 0000000..b01856f --- /dev/null +++ b/src/filters/dropshadow/DropShadowFilter.js @@ -0,0 +1,167 @@ +var core = require('../../core'), + BlurXFilter = require('../blur/BlurXFilter'), + BlurYTintFilter = require('./BlurYTintFilter'); + +/** + * The DropShadowFilter applies a Gaussian blur to an object. + * The strength of the blur can be set for x- and y-axis separately. + * + * @class + * @extends AbstractFilter + * @memberof PIXI.filters + */ +function DropShadowFilter() +{ + core.AbstractFilter.call(this); + + this.blurXFilter = new BlurXFilter(); + this.blurYTintFilter = new BlurYTintFilter(); + + this.defaultFilter = new core.AbstractFilter(); + + this.padding = 30; + + this._dirtyPosition = true; + this._angle = 45 * Math.PI / 180; + this._distance = 10; + this.alpha = 0.75; + this.hideObject = false; + this.blendMode = core.CONST.BLEND_MODES.MULTIPLY; +} + +DropShadowFilter.prototype = Object.create(core.AbstractFilter.prototype); +DropShadowFilter.prototype.constructor = DropShadowFilter; +module.exports = DropShadowFilter; + +DropShadowFilter.prototype.applyFilter = function (renderer, input, output) +{ + var renderTarget = renderer.filterManager.getRenderTarget(true); + + //TODO - copyTexSubImage2D could be used here? + if(this._dirtyPosition) + { + this._dirtyPosition = false; + + this.blurYTintFilter.uniforms.offset.value[0] = Math.sin(this._angle) * this._distance; + this.blurYTintFilter.uniforms.offset.value[1] = Math.cos(this._angle) * this._distance; + } + + this.blurXFilter.applyFilter(renderer, input, renderTarget); + + renderer.blendModeManager.setBlendMode(this.blendMode); + + this.blurYTintFilter.applyFilter(renderer, renderTarget, output); + + renderer.blendModeManager.setBlendMode(core.CONST.BLEND_MODES.NORMAL); + + if(!this.hideObject) + { + + this.defaultFilter.applyFilter(renderer, input, output); + } + + + renderer.filterManager.returnRenderTarget(renderTarget); +}; + +Object.defineProperties(DropShadowFilter.prototype, { + /** + * Sets the strength of both the blurX and blurY properties simultaneously + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blur: { + get: function () + { + return this.blurXFilter.blur; + }, + set: function (value) + { + this.blurXFilter.blur = this.blurYTintFilter.blur = value; + } + }, + + /** + * Sets the strength of the blurX property + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blurX: { + get: function () + { + return this.blurXFilter.blur; + }, + set: function (value) + { + this.blurXFilter.blur = value; + } + }, + + /** + * Sets the strength of the blurY property + * + * @member {number} + * @memberOf DropShadowFilter# + * @default 2 + */ + blurY: { + get: function () + { + return this.blurYTintFilter.blur; + }, + set: function (value) + { + this.blurYTintFilter.blur = value; + } + }, + + color: { + get: function () + { + return core.utils.rgb2hex( this.blurYTintFilter.uniforms.color.value ); + }, + set: function (value) + { + this.blurYTintFilter.uniforms.color.value = core.utils.hex2rgb(value); + } + }, + + alpha: { + get: function () + { + return this.blurYTintFilter.uniforms.alpha.value; + }, + set: function (value) + { + this.blurYTintFilter.uniforms.alpha.value = value; + } + }, + + distance: { + get: function () + { + return this._distance + }, + set: function (value) + { + this._dirtyPosition = true; + this._distance = value; + } + }, + + angle: { + get: function () + { + return this._angle + }, + set: function (value) + { + this._dirtyPosition = true; + this._angle = value; + } + } +}); diff --git a/src/filters/dropshadow/blurYTint.frag b/src/filters/dropshadow/blurYTint.frag new file mode 100644 index 0000000..5701a3d --- /dev/null +++ b/src/filters/dropshadow/blurYTint.frag @@ -0,0 +1,27 @@ +precision lowp float; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +uniform float blur; +uniform vec3 color; +uniform float alpha; + +uniform sampler2D uSampler; + +void main(void) +{ + vec4 sum = vec4(0.0); + + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09; + sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05; + + gl_FragColor =vec4( color.rgb * sum.a * alpha, sum.a * alpha ); +} diff --git a/src/filters/dropshadow/blurYTint.vert b/src/filters/dropshadow/blurYTint.vert new file mode 100644 index 0000000..a7bae1a --- /dev/null +++ b/src/filters/dropshadow/blurYTint.vert @@ -0,0 +1,16 @@ +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; +attribute vec4 aColor; +uniform vec2 offset; + +uniform mat3 projectionMatrix; + +varying vec2 vTextureCoord; +varying vec4 vColor; + +void main(void) +{ + gl_Position = vec4((projectionMatrix * vec3((aVertexPosition+offset), 1.0)).xy, 0.0, 1.0); + vTextureCoord = aTextureCoord; + vColor = vec4(aColor.rgb * aColor.a, aColor.a); +} diff --git a/src/filters/index.js b/src/filters/index.js index f427bc4..674a244 100644 --- a/src/filters/index.js +++ b/src/filters/index.js @@ -26,6 +26,7 @@ DisplacementFilter: require('./displacement/DisplacementFilter'), DotScreenFilter: require('./dot/DotScreenFilter'), GrayFilter: require('./gray/GrayFilter'), + DropShadowFilter: require('./dropshadow/DropShadowFilter'), InvertFilter: require('./invert/InvertFilter'), NoiseFilter: require('./noise/NoiseFilter'), NormalMapFilter: require('./normal/NormalMapFilter'),