body { margin: 0; background: black; color: silver; }
const fragShader = `
#define SHADER_NAME BLUR_FS
precision mediump float;
//"in" attributes from our vertex shader
varying vec2 outTexCoord;
//declare uniforms
uniform sampler2D uMainSampler;
uniform float uResolution;
uniform float radius;
uniform vec2 dir;
void main()
{
//this will be our RGBA sum
vec4 sum = vec4(0.0);
//our original texcoord for this fragment
vec2 tc = outTexCoord;
//the amount to blur, i.e. how far off center to sample from
//1.0 -> blur by one pixel
//2.0 -> blur by two pixels, etc.
float blur = radius/uResolution;
//the direction of our blur
//(1.0, 0.0) -> x-axis blur
//(0.0, 1.0) -> y-axis blur
float hstep = dir.x;
float vstep = dir.y;
//apply blurring, using a 9-tap filter with predefined gaussian weights",
sum += texture2D(uMainSampler, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
sum += texture2D(uMainSampler, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
sum += texture2D(uMainSampler, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
sum += texture2D(uMainSampler, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;
vec4 tex = texture2D(uMainSampler, vec2(tc.x, tc.y));
sum += tex * 0.2270270270;
sum += texture2D(uMainSampler, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
sum += texture2D(uMainSampler, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
sum += texture2D(uMainSampler, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
sum += texture2D(uMainSampler, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;
gl_FragColor = sum;
}
`;
class BlurPostFX extends Phaser.Renderer.WebGL.Pipelines.PostFXPipeline {
constructor(game) {
super({
game,
renderTarget: true,
fragShader,
uniforms: [
"uProjectionMatrix",
"uMainSampler",
"uResolution",
"radius",
"dir"
]
});
}
onPreRender() {
this.set1f("uResolution", this.renderer.width);
this.set1f("radius", 2);
this.set2f("dir", 1.0, 1.0);
}
}
const config = {
type: Phaser.WEBGL,
width: 800,
height: 600,
pipeline: { BlurPostFX },
physics: {
default: "arcade",
arcade: {
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
},
loader: {
baseURL: "https://labs.phaser.io",
crossOrigin: "anonymous"
},
plugins: {
scene: [
{
key: "PhaserRaycaster",
plugin: PhaserRaycaster,
mapping: "raycasterPlugin"
}
]
}
};
new Phaser.Game(config);
var raycaster;
var ray;
var graphics;
var obstacles;
var intersections = [];
var targets;
var slices;
var rt;
var RANGE = 1000;
function preload() {
this.load.image("grid", "assets/pics/debug-grid-1920x1920.png");
this.load.image("crate", "assets/sprites/crate.png");
}
function create() {
raycaster = this.raycasterPlugin.createRaycaster({ debug: false });
ray = raycaster.createRay({
autoSlice: true,
origin: { x: 400, y: 300 },
rayRange: RANGE
});
console.log("raycaster", raycaster);
console.log("ray", ray);
var bg = this.add.image(0, 0, "grid").setOrigin(0, 0);
obstacles = this.add.group();
createObstacles(this);
raycaster.mapGameObjects(obstacles.getChildren());
createTargets(this);
intersections = ray.castCircle();
graphics = this.add
.graphics({
fillStyle: { color: 0xffffff, alpha: 1.0 }
})
.setVisible(false);
rt = this.add.renderTexture(0, 0, 800, 600)
.setPostPipeline(BlurPostFX);
draw();
this.input.on("pointermove", function (pointer) {
ray.setOrigin(pointer.x, pointer.y);
intersections = ray.castCircle();
});
}
function update() {
draw();
}
function createTargets(scene) {
targets = scene.physics.add.group({
defaultKey: "crate",
bounceX: 1,
bounceY: 1,
collideWorldBounds: true,
velocityX: 60,
velocityY: 60
});
targets.create(400, 300);
targets.create(750, 500);
targets.create(450, 75);
}
function createObstacles(scene) {
let obstacle = scene.add.rectangle(100, 100, 75, 75, 0xaaaaaa, 0.5);
obstacles.add(obstacle, true);
obstacle = scene.add.line(400, 100, 0, 0, 200, 50);
obstacles.add(obstacle);
obstacle = scene.add.circle(650, 100, 50, 0xaaaaaa, 0.5);
obstacles.add(obstacle);
obstacle = scene.add.polygon(
650,
500,
[0, 0, 50, 50, 100, 0, 100, 75, 50, 100, 0, 50],
0xaaaaaa,
0.5
);
obstacles.add(obstacle);
for (let i = 0; i < 5; i++) {
obstacle = scene.add.rectangle(
350 + 30 * i,
550 - 30 * i,
50,
50,
0xaaaaaa,
0.5
);
obstacles.add(obstacle, true);
}
obstacle = scene.add.image(100, 500, "crate");
obstacles.add(obstacle, true);
}
function draw() {
graphics.clear();
if (intersections.length > 0) {
graphics.fillPoints(intersections);
}
//rt.clear();
//rt.draw(graphics);
rt.fill(0);
rt.erase(graphics);
}
This Pen doesn't use any external CSS resources.