Pixi.jsを使っていて詰まったところをメモ。
任意のアスペクト比の画像に対して同じようにwebglのエフェクトを掛けようとする時、一手間が必要になります。
具体的には mappedMatrix という変換行列を用意してあげて、これをfilterに適用します。
let cvs = document.getElementById('cvs')
cvs.width = 800
cvs.height = 600
let renderer = new PIXI.WebGLRenderer(cvs.width, cvs.height, {view: cvs, antialias: true} )
let container = new PIXI.Container()
let img = new Image()
img.src = "/images/detail/" + imgID + ".jpg";
img.onload = function(){
let sprite = new PIXI.Sprite(new PIXI.Texture(new PIXI.BaseTexture(img)))
sprite.width = cvs.width
sprite.height = cvs.height
container.addChild(sprite)
renderer.render(container)
}
let frag =
`precision mediump float;
uniform vec4 filterArea;
uniform sampler2D uSampler;
uniform mat3 mappedMatrix;
uniform float val;
varying vec2 vTextureCoord;
void main (void) {
vec3 map = vec3(vTextureCoord.xy, 1) * mappedMatrix;
vec4 col = texture2D(uSampler, vTextureCoord);
if(map.x > val)
gl_FragColor = texture2D(uSampler, vec2(val, vTextureCoord.y));
else
gl_FragColor = col;
}`
.split('\n').reduce((c, a) => c + a.trim() + '\n')
let uniforms = {
val: { type: 'float', value: 0 },
mappedMatrix : { type: 'mat3', value: new PIXI.Matrix() }
};
let filter = new PIXI.Filter(null, frag, uniforms);
filter.apply = function (filterManager, input, output){
filterManager.calculateNormalizedScreenSpaceMatrix(uniforms.mappedMatrix.value)
filterManager.applyFilter(this, input, output);
};
container.filters = [filter]
function update(){
uniforms = {
val: { type: 'float', value: 1 },
mappedMatrix : { type: 'mat3', value: new PIXI.Matrix() }
};
filter = new PIXI.Filter(null, frag, uniforms);
container.filters = [filter]
renderer.render(container)
requestAnimationFrame(update)
}
update();
ご参考までに!