mcpField
F
filters-and-postfx

filters-and-postfx

github.com/phaserjs开发40.6k794 次安装10 周前更新
代码仓库

关于 filters-and-postfx

面向 Phaser 4 开发者的滤镜与后期特效技能指南,介绍 WebGL 上的对象和摄像机滤镜、内部与外部处理及常见效果配置。

主要功能

  1. 01为游戏对象启用滤镜
  2. 02配置摄像机滤镜
  3. 03区分内部与外部滤镜
  4. 04按顺序组合多种效果
  5. 05使用遮罩与转场效果

适用场景

  1. 01为角色添加发光或模糊
  2. 02对摄像机画面进行调色
  3. 03制作遮罩与显露转场
  4. 04组合滤镜实现自定义合成

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/phaserjs/phaser --skill filters-and-postfx

安装后在 Claude Code 中输入/filters-and-postfx确认已加载。

详细介绍

Phaser 4 滤镜与后期特效

快速开始

为精灵添加辉光效果:

// In your Scene's create() method:
const sprite = this.add.sprite(400, 300, 'player');

// Step 1: Enable the filter system on the game object (WebGL only)
sprite.enableFilters();

// Step 2: Add filters via .filters.internal or .filters.external
sprite.filters.internal.addGlow(0xff00ff, 4, 0, 1);

为相机添加模糊:

// Cameras have filters enabled by default - no enableFilters() needed
const camera = this.cameras.main;
camera.filters.internal.addBlur(0, 2, 2, 1);

核心概念

v4 中滤镜的工作方式

滤镜是基于 GPU 的后期处理效果,在对象或相机渲染到纹理后应用。每个滤镜都会对该纹理运行一次着色器通道,生成最终的视觉输出。滤镜仅支持 WebGL。

带滤镜的相机的渲染管线:

  1. 对象渲染到与相机尺寸相同的纹理。
  2. 内部滤镜处理该纹理,在对象/相机局部空间中应用效果。
  3. 纹理绘制到与上下文尺寸相同的纹理,应用相机变换(位置、旋转、缩放)。
  4. 外部滤镜处理该上下文纹理,在屏幕空间中应用效果。
  5. 最终纹理合成到输出中。
内部滤镜与外部滤镜

每个 FilterList 都暴露两个子列表:filters.internal 和 filters.external。这一区别控制滤镜相对于相机/对象变换的运行时机:

  • 内部——在相机变换之前应用。效果在对象的局部坐标空间中运行。对旋转对象施加水平模糊时,模糊会随对象一起旋转。内部滤镜仅覆盖对象/相机区域,因此开销更低。
  • 外部——在相机变换之后应用。效果在屏幕空间中运行。对旋转对象施加水平模糊时,在屏幕上始终水平模糊。外部滤镜是全屏的,开销更高。

尽可能使用内部滤镜以获得更好的性能。

FilterList

FilterList(Phaser.GameObjects.Components.FilterList)是存放滤镜控制器的容器。它提供:

  • add(filter, index)——在可选索引处添加 Controller 实例
  • remove(filter, forceDestroy)——移除并销毁滤镜
  • clear()——移除并销毁所有滤镜
  • getActive()——返回所有 active === true 的滤镜
  • list——Controller 的原始数组(可安全重排序)
  • 便捷工厂方法:addBlur()、addGlow()、addMask() 等。
滤镜控制器

每个滤镜都是 Phaser.Filters.Controller 的子类。常见 Controller 属性:

属性类型描述
activeboolean在不移除滤镜的情况下开启/关闭它
cameraCamera拥有此滤镜的相机
renderNodestring着色器的渲染节点 ID
paddingOverrideRectangle覆盖自动内边距计算
ignoreDestroyboolean如果为 true,则当其 FilterList 被销毁时滤镜仍保留(用于复用)

关键方法:setActive(bool)、setPaddingOverride(left, top, right, bottom)、getPadding()、destroy()。

在游戏对象上启用滤镜

相机默认可用滤镜。游戏对象则不行——必须先调用 enableFilters():

const sprite = this.add.sprite(400, 300, 'hero');
sprite.enableFilters();

// Now sprite.filters is available
sprite.filters.internal.addGlow();
sprite.filters.external.addVignette();

enableFilters() 会在游戏对象上创建一个内部 filterCamera,负责将对象渲染到纹理以供滤镜处理。它返回 this 以支持链式调用。

启用后游戏对象上的相关属性:

属性默认值描述
filterCameranull -> Camera用于滤镜渲染的内部相机
filtersnull -> {internal, external}访问 FilterList 对
renderFilterstrue所有滤镜渲染的总开关
filtersAutoFocustrue自动调整相机以跟随对象
filtersFocusContextfalse聚焦于渲染上下文而非对象边界
filtersForceCompositefalse即使没有活动滤镜也始终绘制到帧缓冲
maxFilterSizenull -> Vector2滤镜帧缓冲的最大纹理尺寸

使用 willRenderFilters() 检查是否有任何活动滤镜会实际渲染。


常见模式

为游戏对象添加滤镜
const sprite = this.add.sprite(400, 300, 'enemy');
sprite.enableFilters();

// Add a glow
const glow = sprite.filters.internal.addGlow(0x00ff00, 4);

// Modify at runtime
glow.outerStrength = 8;
glow.color = 0xff0000;

// Temporarily disable
glow.setActive(false);

// Remove and destroy
sprite.filters.internal.remove(glow);
相机滤镜
const camera = this.cameras.main;

// Internal: effect in camera-local space
const blur = camera.filters.internal.addBlur(0, 2, 2, 1);

// External: effect in screen space
const vignette = camera.filters.external.addVignette(0.5, 0.5, 0.5, 0.5);

// Color grading via ColorMatrix
const cm = camera.filters.internal.addColorMatrix();
cm.colorMatrix.sepia();
串联多个滤镜

滤镜按列表顺序执行。每个滤镜接收前一个滤镜的输出:

const cam = this.cameras.main;

// First: apply color grading
const cm = cam.filters.internal.addColorMatrix();
cm.colorMatrix.brightness(0.2);

// Second: apply blur to the color-graded result
cam.filters.internal.addBlur(1, 2, 2, 1);

// Third: add a vignette on top
cam.filters.external.addVignette(0.5, 0.5, 0.5, 0.8);
通过滤镜实现遮罩

v4 中的遮罩以滤镜形式实现。它们使用纹理或游戏对象的 alpha 通道来控制可见性:

// Mask with a static texture
sprite.enableFilters();
sprite.filters.internal.addMask('maskTexture');

// Mask with a game object (renders to DynamicTexture automatically)
const maskShape = this.add.circle(0, 0, 100, 0xffffff);
sprite.enableFilters();
const mask = sprite.filters.internal.addMask(maskShape);

// Invert the mask
mask.invert = true;

// Control auto-updating for game object masks
mask.autoUpdate = true;  // default: re-renders each frame
mask.needsUpdate = true; // force a one-time update

// Use a specific camera for viewing the mask object
sprite.filters.external.addMask(maskShape, false, this.cameras.main);

内部遮罩匹配被过滤的对象。外部遮罩匹配相机上下文。使用 viewCamera 参数来控制由哪个相机渲染遮罩游戏对象。

擦除 / 揭示过渡
const camera = this.cameras.main;
const wipe = camera.filters.external.addWipe(0.1, 0, 0);

// Animate via tween
this.tweens.add({
    targets: wipe,
    progress: 1,
    duration: 2000,
    ease: 'Linear'
});

// Direction helpers
wipe.setLeftToRight();
wipe.setTopToBottom();
wipe.setRevealEffect();   // reveal mode
wipe.setWipeEffect();     // wipe mode

// Wipe to another texture (for scene transitions)
wipe.setTexture('nextSceneCapture');
ParallelFilters(自定义泛光与合成)

ParallelFilters 将输入拆分为两条路径,分别独立处理,然后混合结果。这取代了 v3 中专用的 Bloom 滤镜:

const camera = this.cameras.main;
const pf = camera.filters.internal.addParallelFilters();

// Top path: threshold bright areas, then blur them
pf.top.addThreshold(0.5, 1);
pf.top.addBlur();

// Configure the blend (how top combines onto bottom)
pf.blend.blendMode = Phaser.BlendModes.ADD;
pf.blend.amount = 0.5;

// Bottom path: left empty = uses original input
使用 CaptureFrame 实现场景级效果

CaptureFrame 会在其出现在显示列表中的位置捕获当前渲染状态。在它之前渲染的对象会被捕获;在它之后渲染的对象则不会:

// Requires composite mode on the camera
this.cameras.main.setForceComposite(true);

// Objects rendered before CaptureFrame are captured
const bg = this.add.image(400, 300, 'background');

// Create the capture point
const capture = this.add.captureFrame('myCapture');

// Display the captured texture with filters applied
const display = this.add.image(400, 300, 'myCapture');
display.enableFilters();
display.filters.internal.addBlur(0, 4, 4, 2);

所有内置滤镜

滤镜添加方法描述
BarreladdBarrel(amount)挤压/膨胀变形。amount=1 为中性。
BlendaddBlend(texture, blendMode, amount, color)使用混合模式混合另一个纹理。支持标准 WebGL 中没有的模式。
BlockyaddBlocky(config)保留原始颜色的像素化(无混合)。最好在不使用抗锯齿时使用。
BluraddBlur(quality, x, y, strength, color, steps)高斯模糊。质量:0=低,1=中,2=高。
BokehaddBokeh(radius, amount, contrast)景深散景模糊效果。
ColorMatrixaddColorMatrix()通过矩阵进行颜色操作。访问 .colorMatrix 可实现棕褐色、灰度、亮度、色相等效果。
CombineColorMatrixaddCombineColorMatrix(texture)通过颜色矩阵合并两个纹理的通道。适用于 alpha 传递。
DisplacementaddDisplacement(texture, x, y)使用位移贴图纹理进行像素位移。值为非常小的浮点数(例如 0.005)。
GlowaddGlow(color, outerStrength, innerStrength, scale, knockout, quality, distance)边缘周围的发光光晕。支持内发光/外发光和挖空模式。
GradientMapaddGradientMap(config)基于亮度使用 ColorRamp 重新着色图像。
ImageLightaddImageLight(config)使用全景环境贴图和法线贴图进行基于图像的照明。
KeyaddKey(config)色度键:移除或隔离特定颜色。配置:{ color, threshold, feather, isolate }。
MaskaddMask(mask, invert, viewCamera, viewTransform, scaleFactor)通过纹理或游戏对象进行 Alpha 遮罩。
NormalToolsaddNormalTools(config)操作法线贴图:旋转、调整朝向强度、输出灰度朝向数据。
PanoramaBluraddPanoramaBlur(config)用于全景图像的球面校正模糊。与 ImageLight 配合使用。非常慢。
ParallelFiltersaddParallelFilters()将输入拆分为两条滤镜路径,混合结果。用于自定义泛光。
PixelateaddPixelate(amount)马赛克/像素化效果。像素大小 = 2 + amount。会混合颜色(与 Blocky 不同)。
QuantizeaddQuantize(config)减少调色板。支持 RGBA/HSVA 模式、gamma、偏移、抖动。
SampleraddSampler(callback, region)从渲染中提取像素数据。不会改变图像。开销较大。
ShadowaddShadow(x, y, decay, power, color, samples, intensity)带偏移、衰减和颜色的投影阴影。
ThresholdaddThreshold(edge1, edge2, invert)逐通道二值阈值。边缘可以是数组以进行逐通道控制。
TiltShiftaddTiltShift(radius, amount, contrast, blurX, blurY, strength)微缩/移轴效果(内部使用 Bokeh)。
VignetteaddVignette(x, y, radius, strength, color, blendMode)边缘变暗/着色。支持 NORMAL、ADD、MULTIPLY、SCREEN 混合模式。
WipeaddWipe(wipeWidth, direction, axis, reveal, wipeTexture)擦除/显现过渡。通过 tween 动画化 progress。

API 快速参考

启用和访问滤镜
// Game objects: must enable first
gameObject.enableFilters();
gameObject.filters.internal.addBlur();
gameObject.filters.external.addGlow();

// Cameras: filters available immediately
camera.filters.internal.addBlur();
camera.filters.external.addGlow();
FilterList 方法
const list = camera.filters.internal;

list.addBlur();                    // Factory method (one per filter type)
list.add(controllerInstance);      // Add a pre-built controller
list.add(controller, 2);           // Insert at index 2
list.remove(controller);           // Remove and destroy
list.clear();                      // Remove and destroy all
list.getActive();                  // Get all active controllers
list.list;                         // Raw array (reorder safely)
控制器通用 API
controller.active = false;                  // Disable without removing
controller.setActive(true);                 // Enable (returns this)
controller.setPaddingOverride(10, 10, 10, 10); // Override padding
controller.setPaddingOverride(null);        // Clear override
controller.ignoreDestroy = true;            // Survive FilterList.destroy()
controller.destroy();                       // Manual cleanup
Mask 滤镜 API
const mask = list.addMask('texKey');       // From texture key
const mask = list.addMask(gameObject);     // From game object
mask.invert = true;                         // Invert mask
mask.autoUpdate = false;                    // Stop auto-updating GO masks
mask.needsUpdate = true;                    // Force one update
mask.setTexture('newKey');                  // Change texture source
mask.setGameObject(newGO);                 // Change GO source
mask.viewCamera = otherCamera;             // Camera for GO rendering
mask.viewTransform = 'local';              // 'local' or 'world'
mask.scaleFactor = 0.5;                    // Scale mask texture size
ColorMatrix 预设
const cm = list.addColorMatrix();
cm.colorMatrix.sepia();
cm.colorMatrix.grayscale(1);
cm.colorMatrix.brightness(0.3);
cm.colorMatrix.hue(90);
cm.colorMatrix.saturate(-0.5);
cm.colorMatrix.contrast(0.3);
cm.colorMatrix.blackWhite();
cm.colorMatrix.negative();
cm.colorMatrix.desaturate();
cm.colorMatrix.night(0.5);
cm.colorMatrix.lsd();
cm.colorMatrix.brown();
cm.colorMatrix.vintagePinhole();
cm.colorMatrix.kodachrome();
cm.colorMatrix.technicolor();
cm.colorMatrix.polaroid();
cm.colorMatrix.shiftToBGR();

注意事项

  1. 仅限 WebGL -- 滤镜在 Canvas 渲染器中无效。如果 WebGL 不可用,enableFilters() 会提前返回。

  2. 游戏对象需要调用 enableFilters() -- 摄像机默认具有滤镜。精灵、图像、容器及其他游戏对象在访问 filters 之前需要调用 enableFilters()。

  3. 性能开销 -- 每个带有活动滤镜的对象都会产生额外的绘制调用(基础渲染一次,外加每个活动滤镜一次)。请谨慎使用,并尽早进行性能测试。

  4. 内部与外部滤镜的区别很重要 -- 内部滤镜开销更低(大小与对象区域一致)。外部滤镜是全屏的。应随对象旋转的模糊必须使用内部滤镜;应保持屏幕对齐的模糊必须使用外部滤镜。

  5. 滤镜顺序很重要 -- 滤镜按列表顺序依次应用。一个滤镜的输出会作为下一个滤镜的输入。

  6. Glow 的 quality 和 distance 不可变 -- Glow 滤镜的 quality 和 distance 在创建后无法更改。如需更改,请销毁并重新创建该滤镜。

  7. CaptureFrame 需要 forceComposite -- 摄像机必须设置 setForceComposite(true),或以其他方式渲染到帧缓冲区,CaptureFrame 才能正常工作。

  8. 为扩展效果添加内边距 -- Blur、Glow 和 Shadow 等滤镜可以自动计算内边距以扩展渲染纹理。如有需要,可用 setPaddingOverride() 覆盖。传入 null 可清除覆盖。在摄像机上使用时,请用 camera.getPaddingWrapper(x) 在图像边缘之外渲染更多世界内容。

  9. 控制器复用 -- 默认情况下,控制器会在其 FilterList 被销毁时一并销毁。设置 ignoreDestroy = true 可在多个对象间复用控制器,但你必须手动管理其生命周期。与外部滤镜配合使用效果最佳。

  10. 遮罩游戏对象渲染 -- 当使用游戏对象作为遮罩源时,它每帧都会被渲染到一个 DynamicTexture(如果 autoUpdate 为 true)。将 autoUpdate = false 并配合 needsUpdate = true 进行一次性更新,以提升静态遮罩的性能。

  11. 没有 Bloom 滤镜 -- v4 没有专用的 Bloom 滤镜。请改用 ParallelFilters 配合 Threshold + Blur + ADD 混合(参见常见模式),或使用 Phaser.Actions.AddEffectBloom 自动完成该过程。


v4 相较于 v3 的变化

v3 (FX)v4 (Filters)说明
gameObject.preFX / gameObject.postFXgameObject.filters.internal / gameObject.filters.externalpreFX/postFX 被内部/外部滤镜列表取代
camera.postFXcamera.filters.internal / camera.filters.external摄像机现在同时拥有内部和外部列表
FX.addBloom()使用 ParallelFilters + Threshold + Blur没有专用 Bloom 滤镜;用 ParallelFilters 或 Phaser.Actions.AddEffectBloom 构建
FX.addCircle()使用 Vignette 或 MaskCircle 效果已移除;请使用带半径的 Vignette 或圆形 Mask,或用 Phaser.Actions.AddMaskShape 自动完成
FX.addGradient()使用 Gradient GameObject + Quantize新的 Gradient GameObject 可渲染渐变;Quantize 可按需添加色阶
Glow 的 quality 原为 0-1 的小数Glow 的 quality 现为整数(默认 10)随机采样取代了线采样;值越低质量越高
camera.setMask()camera.filters.internal.addMask()遮罩现在是一种滤镜,而非独立系统
gameObject.setMask()gameObject.filters.internal.addMask()同样统一的滤镜系统
FX 控制器Phaser.Filters.Controller 子类模式相同:返回的控制器对象带有可变属性
--游戏对象需要调用 enableFilters()游戏对象新增了显式的启用步骤
--Blocky、Quantize、Key、Blend、CombineColorMatrix、ImageLight、NormalTools、PanoramaBlur、ParallelFilters、Samplerv4 中新增的滤镜

源文件映射

文件描述
src/gameobjects/components/Filters.js为游戏对象添加 enableFilters()、filterCamera、filters 的 Mixin
src/gameobjects/components/FilterList.js包含所有 add*() 工厂方法的 FilterList 类
src/filters/Controller.js所有滤镜的基础 Controller 类
src/filters/Barrel.js桶形畸变滤镜
src/filters/Blend.js纹理混合滤镜
src/filters/Blocky.js保留颜色的像素化滤镜
src/filters/Blur.js高斯模糊滤镜
src/filters/Bokeh.js散景 / 移轴滤镜
src/filters/ColorMatrix.js颜色矩阵滤镜(棕褐色、灰度等)
src/filters/CombineColorMatrix.js双纹理通道合并滤镜
src/filters/Displacement.js置换贴图滤镜
src/filters/Glow.js发光/描边滤镜
src/filters/GradientMap.js渐变映射重新着色滤镜
src/filters/ImageLight.js基于图像的照明滤镜
src/filters/Key.js色度键滤镜
src/filters/Mask.jsAlpha 遮罩滤镜(纹理或游戏对象)
src/filters/NormalTools.js法线贴图操作滤镜
src/filters/PanoramaBlur.js球形全景模糊滤镜
src/filters/ParallelFilters.js带混合的并行滤镜路径
src/filters/Pixelate.js像素化滤镜
src/filters/Quantize.js颜色量化滤镜
src/filters/Sampler.js像素采样/回读滤镜
src/filters/Shadow.js投影滤镜
src/filters/Threshold.js阈值滤镜
src/filters/Vignette.js暗角滤镜
src/filters/Wipe.js擦除/揭示过渡滤镜
src/gameobjects/captureframe/CaptureFrame.js用于场景级捕获的 CaptureFrame 游戏对象

相关:sprites-and-images.md、cameras.md、v4-new-features.md

评论

支持 Markdown