`findPostProcessFromContext` returns `null` for components rendered with `CameraComponent.postProcess`
维护者通常 1 天内回复
评估
这个 Issue 还没有评估数据。
描述
What happened?
When a post process is set as camera.postProcess, findPostProcessFromContext returns null for every component in the world and in the viewfinder. The components have no way to know which post process is rendering them. The same post process in a PostProcessComponent is found as expected.
This breaks multi-pass effects where components draw differently in each pass, which is what the render context is for. Take a selection highlight, like in a strategy game: it renders its subtree once as a mask, where only the selected unit draws itself, and turns that mask into an outline. Then it renders the subtree again for the scene itself. With camera.postProcess, the lookup fails, so every component draws itself into the mask, and everything gets outlined instead of only the selected unit. Nothing is thrown.
https://github.com/user-attachments/assets/1efc7431-880c-480e-bb7e-771270004aa8
What do you expect?
findPostProcessFromContext should return the camera's post process for any component that the camera renders, the same as it does for the children of a PostProcessComponent. In the example below, only the green square should be outlined.
How can we reproduce this?
- Set a post process as
camera.postProcess. - Add a component to the world that calls
findPostProcessFromContextin itsrender. - It always gets
null.
What steps should take to fix this?
When no PostProcessComponent is found, findPostProcessFromContext (post_process_component.dart#L128-L143) falls back to looking up the camera's render context:
final contextInCamera =
findRenderContext<CameraRenderContext>()?.currentPostProcess;
Render contexts are passed from a component to its children in renderChild. The world isn't a child of the camera, and the camera renders both the world and the viewfinder directly (camera_component.dart#L227-L233), so the camera's render context never reaches either of them. This lookup can never succeed.
The cameras that are rendering are already tracked in CameraComponent.currentCameras. The fallback can check their post processes there instead, from the innermost camera to the outermost.
Do have an example of where the bug occurs?
import 'dart:ui';
import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flame/post_process.dart';
import 'package:flutter/material.dart' show Colors;
import 'package:flutter/widgets.dart';
void main() => runApp(GameWidget(game: ReproGame()));
class ReproGame extends FlameGame {
@override
Future<void> onLoad() async {
camera.postProcess = SelectionHighlight();
world.addAll([
Unit(color: Colors.red, position: Vector2(-160, -40)),
Unit(color: Colors.green, position: Vector2(-40, -40), isSelected: true),
Unit(color: Colors.blue, position: Vector2(80, -40)),
]);
}
}
/// Outlines the selected units, like in a strategy game.
///
/// It renders its subtree twice: first as a mask, where only the selected
/// units draw themselves, which is turned into a yellow outline. Then the
/// scene itself, on top of the outline.
class SelectionHighlight extends PostProcess {
bool drawingMask = false;
final _outlinePaint = Paint()
..colorFilter = const ColorFilter.mode(Colors.yellow, BlendMode.srcIn)
..imageFilter = ImageFilter.dilate(radiusX: 6, radiusY: 6);
@override
void postProcess(Vector2 size, Canvas canvas) {
drawingMask = true;
canvas.saveLayer(null, _outlinePaint);
renderSubtree(canvas);
canvas.restore();
drawingMask = false;
renderSubtree(canvas);
}
}
class Unit extends RectangleComponent {
Unit({
required Color color,
required super.position,
this.isSelected = false,
}) : super(size: Vector2.all(80), paint: Paint()..color = color);
final bool isSelected;
@override
void render(Canvas canvas) {
final highlight = findPostProcessFromContext<SelectionHighlight>();
// Only the selected units draw themselves into the mask.
if ((highlight?.drawingMask ?? false) && !isSelected) {
return;
}
super.render(canvas);
}
}
Expected: only the green square is outlined. Actual: all three squares are outlined, because findPostProcessFromContext returns null and every unit draws itself into the mask.
Relevant log output
Nothing is logged or thrown.
Execute in a terminal and put output into the code block below
[√] Flutter (Channel stable, 3.47.8, on Microsoft Windows [Version 10.0.22631.6199], locale en-US)
• Flutter version 3.47.8 on channel stable
• Framework revision 737ba8f885 (11 days ago), 2026-10-22 21:37:31 -0700
• Engine revision cf636b1dfb
• Dart version 3.13.7
• DevTools version 2.60.0
[√] Windows Version (11 Pro 64-bit, 23H2, 2009)
[√] Android toolchain - develop for Android devices (Android SDK version 36.1.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop Windows apps (Visual Studio Community 2026 18.11.2)
[√] Connected device (3 available)
[√] Network resources
• No issues found!
Affected platforms
All
Are you interested in working on a PR for this?
- I want to work on this
- 主要语言
- Dart
- 星标
- 10.8k
- 派生
- 1.1k
- 平均合并
- 1 天 19 小时
- 30 天内合并 PR
- 54
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
flame-engine/flame 的其他 Issue
-
Add support to share the polygons of a Path among PathComponent and PathHitbox可能已有人在做 @adario 今天认领。 未关闭enhancement
难度 4/5 1-2 天 新手友好度 15/100
flame-engine/flame#4217 ·
维护者通常 1 天内回复
-
`UniformsSetter.setColor` sends every color to the shader as black可能已有人在做 @ufrshubham 于 3 天前认领。 未关闭bug
flame-engine/flame#4211 · 已指派 1 人 ·
维护者通常 1 天内回复
-
`Viewfinder.visibleGameSize` is not reapplied when the viewport changes size可能已有人在做 @ufrshubham 于 5 天前认领。 未关闭bug
flame-engine/flame#4204 · 已指派 1 人 ·
维护者通常 1 天内回复
-
`Viewfinder.visibleGameSize` zooms in too far with a `FixedResolutionViewport`可能已有人在做 @ufrshubham 于 5 天前认领。 未关闭bug
flame-engine/flame#4203 · 已指派 1 人 ·
维护者通常 1 天内回复
-
Camera bounds with `considerViewport: true` are not updated when the viewport is resized可能已有人在做 @ufrshubham 于 5 天前认领。 未关闭bug
flame-engine/flame#4202 · 已指派 1 人 ·
维护者通常 1 天内回复
查看 flame-engine/flame 的全部 Issue
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 66/100
bggRGjQaUbCoE/PiliPlus#3522 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 67/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 79/100
-
难度 2/5 1-3 小时 新手友好度 79/100
ccch1mneyyy/dsh-Go#731 ·
维护者通常 1 天内回复
-
enhancement good first issue help wanted
难度 2/5 1-3 小时 新手友好度 88/100