Fix noise anchor and flickering in NoiseStyle and NoiseFilter#1433
Fix noise anchor and flickering in NoiseStyle and NoiseFilter#1433zfw1234567 wants to merge 18 commits into
Conversation
|
|
||
| auto imageFilter = args.excludeEffects | ||
| ? nullptr | ||
| : layer->getImageFilter(contentMatrix.getMaxScale(), contentBounds.width(), |
There was a problem hiding this comment.
这里仍然走的是『先合成 ImageFilter → makeWithFilter』老路径,所以 NoiseFilter 不得不额外暴露 getComposeFilter(scale, w, h, oo) 把几何参数塞进 ImageFilter,并且在 NoiseFilter 内部维护一套只为这条路径存在的 composedFilter / composedDirty / composedScale 缓存。
而 Layer::createSubtreeCacheImage 那条路径已经迁到 applyFilters() 上,逐个 filter 调 filterImage() 把几何参数直接传进去,不需要 getComposeFilter。
建议这里也改成 applyFilters() 风格(把 ApplyImageFilterIfNeeded 里的 clipBounds 反向裁剪和 imageMatrix 偏移合并那段一起重构),配合给 LayerFilter::filterBounds 加 MapDirection 参数(默认 Forward,LayerImageFilter 转发到底层 ImageFilter,NoiseFilter 之类 identity 直接返回 srcRect),然后:
- 删掉 Layer::getImageFilter 整个入口(Layer 不再需要拿底层 ImageFilter,bounds 反推也走 LayerFilter::filterBounds(rect, scale, Reverse))
- 删掉 LayerFilter::getComposeFilter 这套虚函数
- 删掉 NoiseFilter 的 composedFilter / composedDirty / composedScale 缓存
这样能消掉『两条渲染路径要保持几何同步』的隐患,也能去掉只为 NoiseFilter 一个类存在的兜底机制。如果这次 PR 改动面太大,可以拆个 follow-up,但 getComposeFilter 这个名字和 composedFilter 缓存看起来像是临时方案,容易被忘掉。
…ck dispatch in Layer::drawLayerStyleDefault.
…and simplify NoiseFilter caching
| * LayerFilter represents a filter that applies effects to a layer, such as blurs, shadows, or color | ||
| * adjustments. It creates a new offscreen image that replaces the original layer content. | ||
| * LayerFilters are mutable and can be changed at any time. | ||
| * LayerFilter is the abstract base class for filters that apply effects to a layer, such as blurs, |
| class LayerFilter : public LayerProperty { | ||
| public: | ||
| /** | ||
| * Applies this filter to the given input image at the specified scale factor. The offset stores |
| * @param offset If non-null, receives the (x, y) translation of the filtered image. | ||
| * @return The filtered image, or nullptr on failure. | ||
| */ | ||
| std::shared_ptr<Image> filterImage(std::shared_ptr<Image> input, float scale, float width, |
There was a problem hiding this comment.
width,height,originOffset看下能不能组装成一个Rect行为,有点太散了
| * forwards to this method when subclasses do not override the 5-arg version. | ||
| */ | ||
| virtual std::shared_ptr<ImageFilter> onCreateImageFilter(float scale); | ||
| virtual std::shared_ptr<Image> onFilterImage(std::shared_ptr<Image> input, float, Point*) { |
| * grow or shrink the visible region. The default implementation returns nullptr. | ||
| */ | ||
| void invalidateFilter(); | ||
| virtual std::shared_ptr<ImageFilter> getImageFilter(float scale); |
There was a problem hiding this comment.
getImageFilter不在这个基类里暴露,放在LayerImageFilter里
|
|
||
| protected: | ||
| std::shared_ptr<ImageFilter> onBuildNoiseImageFilter(float scale, int width, int height) override; | ||
| std::shared_ptr<ImageFilter> onBuildNoiseImageFilter(float scale, Point shift) override; |
| float contentScale, std::shared_ptr<Image> extraSource, | ||
| const Point& extraSourceOffset, float alpha, | ||
| BlendMode blendMode); | ||
| BlendMode blendMode, const Point& contentOffset); |
There was a problem hiding this comment.
contentOffset是否可以放在canvas上处理,这里有extraSourceOffset+contentOffset两个,是否用1个就能解决
There was a problem hiding this comment.
contentoffset是用于补偿因path导致的shader采样锚点的偏移,和cavas无关,extraSourceOffset和contentOffset这里是两个不同的东西
问题描述
噪声锚点偏移:
噪声闪烁:
AlphaThresholdFragmentProcessor的 GLSL 着色器使用step()函数进行 alpha 阈值判断,产生硬边界,导致噪声在不同帧之间出现闪烁。主要变更
filterImage()重载,接受 width/height/originOffset,使 NoiseFilter 能将噪声锚定到内容边界中心,而非随 inputImage 裁切而偏移draw()/onDraw()添加contentOffset参数,使 NoiseStyle 能通过采样矩阵偏移将噪声锚定到内容位置,避免 path 模式下的偏移问题,同时消除drawLayerStyleDefault中的类型检查分发getComposeFilter()替换为getImageFilter(),简化缓存机制GLSLAlphaThresholdFragmentProcessor中的step()替换为smoothstep(threshold - 0.01, threshold + 0.01, alpha),消除硬边界闪烁