diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 83e427f..4aafd1e 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -459,8 +459,16 @@ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + if (!texture.isPowerOfTwo) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } } }; diff --git a/src/core/renderers/webgl/shaders/Shader.js b/src/core/renderers/webgl/shaders/Shader.js index 83e427f..4aafd1e 100644 --- a/src/core/renderers/webgl/shaders/Shader.js +++ b/src/core/renderers/webgl/shaders/Shader.js @@ -459,8 +459,16 @@ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === CONST.SCALE_MODES.LINEAR ? gl.LINEAR : gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + if (!texture.isPowerOfTwo) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } } }; diff --git a/src/filters/displacement/DisplacementFilter.js b/src/filters/displacement/DisplacementFilter.js index f6ccd3a..2eafc6d 100644 --- a/src/filters/displacement/DisplacementFilter.js +++ b/src/filters/displacement/DisplacementFilter.js @@ -3,60 +3,102 @@ /** * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object. * You can use this filter to apply all manor of crazy warping effects - * Currently the r property of the texture is used offset the x and the g property of the texture is used to offset the y. + * Currently the r property of the texture is used to offset the x and the g property of the texture is used to offset the y. * * @class * @extends AbstractFilter - * @namespace PIXI.filters - * @param texture {Texture} The texture used for the displacement map, must be power of 2 texture at the moment + * @namespace PIXI + * @param texture {Texture} The texture used for the displacement map * must be power of 2 texture at the moment */ -function DisplacementFilter(texture) +function DisplacementFilter(sprite) { + var maskMatrix = new core.math.Matrix(); + sprite.renderable = false; + + //TODO move this code out to a frag and vert file. core.AbstractFilter.call(this, // vertex shader - null, + [ + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute vec4 aColor;', + + 'uniform mat3 projectionMatrix;', + 'uniform mat3 otherMatrix;', + + 'varying vec2 vMapCoord;', + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'void main(void)', + '{', + ' gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vMapCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;', + ' vColor = vec4(aColor.rgb * aColor.a, aColor.a);', + '}' + ].join('\n'), // fragment shader - require('fs').readFileSync(__dirname + '/displacement.frag', 'utf8'), - // custom uniforms + [ + 'precision lowp float;', + + 'varying vec2 vMapCoord;', + 'varying vec2 vTextureCoord;', + 'varying vec4 vColor;', + + 'uniform vec2 scale;', + + 'uniform sampler2D uSampler;', + 'uniform sampler2D mapSampler;', + + 'void main(void)', + '{', + ' vec4 original = texture2D(uSampler, vTextureCoord);', + ' vec4 map = texture2D(mapSampler, vMapCoord);', + ' map -= 0.5;', + ' map.xy *= scale;', + ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + map.x, vTextureCoord.y + map.y));', + '}' + ].join('\n'), + // uniforms { - displacementMap: { type: 'sampler2D', value: texture }, - scale: { type: 'v2', value: { x: 30, y: 30 } }, - offset: { type: 'v2', value: { x: 0, y: 0 } }, - mapDimensions: { type: 'v2', value: { x: 1, y: 5112 } }, - dimensions: { type: '4fv', value: [0, 0, 0, 0] } + mapSampler: { type: 'sampler2D', value: sprite.texture }, + otherMatrix: { type: 'mat3', value: maskMatrix.toArray(true) }, + scale: { type: 'v2', value: { x: 0.01, y: 0.01 } } } ); - texture.baseTexture._powerOf2 = true; + this.maskSprite = sprite; + this.maskMatrix = maskMatrix; - if (texture.baseTexture.hasLoaded) - { - this.onTextureLoaded(); - } - else - { - texture.baseTexture.once('loaded', this.onTextureLoaded.bind(this)); - } + + this.scale = new PIXI.Point(0,0); + } DisplacementFilter.prototype = Object.create(core.AbstractFilter.prototype); DisplacementFilter.prototype.constructor = DisplacementFilter; module.exports = DisplacementFilter; -/** - * Sets the map dimensions uniforms when the texture becomes available. - * - * @private - */ -DisplacementFilter.prototype.onTextureLoaded = function () +DisplacementFilter.prototype.applyFilter = function (renderer, input, output) { - this.uniforms.mapDimensions.value.x = this.uniforms.displacementMap.value.width; - this.uniforms.mapDimensions.value.y = this.uniforms.displacementMap.value.height; + var filterManager = renderer.filterManager; + + filterManager.calculateMappedMatrix(input.frame, this.maskSprite, this.maskMatrix); + + this.uniforms.otherMatrix.value = this.maskMatrix.toArray(true); + this.uniforms.scale.value.x = this.scale.x * (1/input.frame.width); + this.uniforms.scale.value.y = this.scale.y * (1/input.frame.height); + + var shader = this.getShader(renderer); + // draw the filter... + filterManager.applyFilter(shader, input, output); }; + Object.defineProperties(DisplacementFilter.prototype, { /** - * The texture used for the displacement map. Must be power of 2 texture. + * The texture used for the displacement map. Must be power of 2 sized texture. * * @member {Texture} * @memberof DisplacementFilter# @@ -64,45 +106,12 @@ map: { get: function () { - return this.uniforms.displacementMap.value; + return this.uniforms.mapSampler.value; }, set: function (value) { - this.uniforms.displacementMap.value = value; - } - }, + this.uniforms.mapSampler.value = value; - /** - * The multiplier used to scale the displacement result from the map calculation. - * - * @member {Point} - * @memberof DisplacementFilter# - */ - scale: { - get: function () - { - return this.uniforms.scale.value; - }, - set: function (value) - { - this.uniforms.scale.value = value; - } - }, - - /** - * The offset used to move the displacement map. - * - * @member {Point} - * @memberof DisplacementFilter# - */ - offset: { - get: function () - { - return this.uniforms.offset.value; - }, - set: function (value) - { - this.uniforms.offset.value = value; } } });