VideoLab icon indicating copy to clipboard operation
VideoLab copied to clipboard

请教下:做缩放动画时,画面会有抖动的感觉,不流畅,如何解决呢?

Open yinghuochong opened this issue 1 year ago • 2 comments

https://github.com/user-attachments/assets/a36cb875-6037-4d89-ba32-8f54f5b92140

demo代码如下:

    func scaleAnimationDemo() -> VideoLab {
        // 1. LayerGroup
        var timeRange = CMTimeRange(start: CMTime.zero, duration: CMTime(seconds: 5, preferredTimescale: 600))
        let keyTimes = [CMTime(seconds: 0, preferredTimescale: 600),
                        CMTime(seconds: 5, preferredTimescale: 600)]
        let animation1 = KeyframeAnimation(keyPath: "scale",
                                           values: [1, 1.2],
                                           keyTimes: keyTimes,
                                           timingFunctions: [.quadraticEaseInOut])
        var transform = Transform.identity
        transform.animations = [animation1]
        
        
        // Add sub-renderLayer1
        let image = UIImage(named: "image2.HEIC")
        let imageSource = ImageSource(cgImage: image?.cgImage)
        imageSource.selectedTimeRange = CMTimeRange(start: CMTime.zero, duration: timeRange.duration)
        timeRange = imageSource.selectedTimeRange
        let renderLayer1 = RenderLayer(timeRange: timeRange, source: imageSource)
        renderLayer1.transform = transform
        
        // 2. Composition
        let composition = RenderComposition()
        composition.renderSize = CGSize(width: 2016, height: 1512)
        composition.layers = [renderLayer1]
        
        // 3. VideoLab
        let videoLab = VideoLab(renderComposition: composition)
        
        return videoLab
    }

yinghuochong avatar Dec 02 '24 06:12 yinghuochong

找到原因了: 需要把metal中的 constexpr sampler quadSampler; 修改成 constexpr sampler quadSampler(coord::normalized, address::clamp_to_edge, filter::linear);

具体原因如下: 在 Metal 开发中,constexpr sampler 用于声明常量采样器对象,constexpr sampler quadSampler;constexpr sampler quadSampler(coord::normalized, address::clamp_to_edge, filter::linear); 存在明显区别,下面为你详细分析:

1. constexpr sampler quadSampler;

这行代码声明了一个名为 quadSampler 的常量采样器对象,但没有显式指定其采样参数。在这种情况下,quadSampler 会使用默认的采样参数。 默认参数说明 坐标模式(coord):通常默认是 coord::normalized,表示纹理坐标使用归一化坐标(范围从 0.0 到 1.0)。 寻址模式(address):默认的寻址模式可能是 address::repeat,即当纹理坐标超出 [0, 1] 范围时,纹理会重复采样。 过滤模式(filter):默认过滤模式一般是 filter::nearest,采用最近邻过滤,在采样时会选择离采样点最近的纹理像素值。

2. constexpr sampler quadSampler(coord::normalized, address::clamp_to_edge, filter::linear);

这行代码同样声明了一个名为 quadSampler 的常量采样器对象,不过显式地指定了采样参数。 显式参数说明 坐标模式(coord::normalized):明确指定使用归一化坐标,这意味着纹理坐标范围是从 0.0 到 1.0。如果纹理坐标超出这个范围,会根据寻址模式进行处理。 寻址模式(address::clamp_to_edge):当纹理坐标超出 [0, 1] 范围时,会将坐标值钳制到纹理的边缘。也就是说,如果纹理坐标小于 0.0,会被视为 0.0;如果大于 1.0,会被视为 1.0。这样可以避免纹理重复或出现未定义行为。 过滤模式(filter::linear):使用线性过滤,在采样时会对周围的纹理像素进行加权平均,从而得到更平滑的采样结果。与最近邻过滤相比,线性过滤可以减少锯齿和块状效应,使纹理看起来更加平滑。

总结

constexpr sampler quadSampler; 使用默认的采样参数,适用于对采样效果要求不高,或者希望使用简单默认设置的场景。 constexpr sampler quadSampler(coord::normalized, address::clamp_to_edge, filter::linear); 显式指定了采样参数,能根据具体需求精确控制纹理采样的行为,例如在需要平滑过渡、避免纹理重复等场景中使用。

yinghuochong avatar Mar 05 '25 09:03 yinghuochong

@yinghuochong 感谢提出的 issue,并且找到了解决方案。如果方便的话,欢迎提一个 Pull request。

ruanjx avatar Mar 16 '25 15:03 ruanjx