gindemit/unity-rlottie

Texture flickering if CPU is under load

Closed this issue · 11 comments

Hi! First of all, thank you for this great library. I am using Lottie on the loading screen to display our logo. Everything is great, but I found that the logo would flicker for some unknown reason, presumably when CPU load is high. In the following video, I am getting all C# types from all loaded assemblies in another thread, and you can see the logo flickers:

bandicam.2023-03-18.14-06-54-380.mp4

(Note the UI thread hangs at 0:06 so the logo animation paused there.) The logo itself originally looks like this:

Warudo.Looped.Updated.mp4

Very confused why this is happening. I have tried both Update and UpdateAsync() (with DrawOneFrameAsyncGetResult() in LateUpdate()), both suffer from the same problem. Even more curious is that this doesn't happen in the editor, only in standalone builds.

Please let me know if you have any ideas. Thanks!

Hello @TigerHix, can you please provide more technical details. The operation system, Unity version. It would be nice, if you share the animation file you use, so that I try to reproduce the issue on my end. Thank you!

@khindemit Sure, here it is: https://pastebin.com/z49QnpLB

OS: Windows 11 22H2
Unity: 2021.3.18f1

Thanks for looking into it!

Hey @TigerHix, thanks a lot for the report. I was able to reproduce it on Windows 11 Mono build. Unity version 2019.4.40f1.

It flickers for me if I select the 128 and below pixels quality. For 256 and above the flickering disappears. I try to figure our why it happens.

2023-04-03.22-50-22.mp4

Hey @TigerHix. following changes helped to fix the issues with flickering on Windows:
image

It seems something is wrong with the UpdateAsync() and DrawOneFrameAsyncGetResult() logic. I'll try to figure out what. You can switch to Update (call it from unity Update, not LateUpdate)

@khindemit Thanks for looking into it! Unfortunately, this doesn't fix the issue for me :(

Here's my code that calls LottieAnimation:

using LottiePlugin;
using UnityEngine;
using UnityEngine.UI;

namespace Warudo.Bootstrap {
    public sealed class AnimatedLogo : MonoBehaviour {
        
        [SerializeField] private TextAsset _animationJson;
        [SerializeField] private uint _textureWidth = 2048;
        [SerializeField] private uint _textureHeight = 2048;
        [SerializeField] private Graphic _graphic;

        private LottieAnimation _lottieAnimation;

        private void Start() {
            _lottieAnimation = LottieAnimation.LoadFromJsonData(
                _animationJson.text,
                string.Empty,
                _textureWidth,
                _textureHeight);
            ((RawImage)_graphic).texture = _lottieAnimation.Texture;
        }
        private void OnDestroy() {
            _lottieAnimation?.Dispose();
            _lottieAnimation = null;
        }

        private void Update() {
            if (_lottieAnimation != null) {
                _lottieAnimation.Update();
            }
        }
    }
}

Hi @TigerHix, I just figured out that when the build player on Windows is started from cmd with "-force-gfx-direct" flag the flickering dissapers. This flag disables the multithreaded rendering. I'll try to figure out why rlottie tries to render the animation even when the LottieRenderImmediately(..) call is done.

@gindemit Thanks for the update. This sounds strange indeed - hope you can figure it out!

Hello, @TigerHix! Thanks to the advanced capabilities of GPT-4, I was able to identify the issue with the flickering. Please try using the following code:

using LottiePlugin;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;

namespace Warudo.Bootstrap
{
    public sealed class AnimatedLogo : MonoBehaviour
    {
        [SerializeField] private TextAsset _animationJson;
        [SerializeField] private uint _textureWidth = 2048;
        [SerializeField] private uint _textureHeight = 2048;
        [SerializeField] private Graphic _graphic;

        private LottieAnimation _lottieAnimation;
        private WaitForEndOfFrame _waitForEndOfFrame;

        private void Start()
        {
            _lottieAnimation = LottieAnimation.LoadFromJsonData(
                _animationJson.text,
                string.Empty,
                _textureWidth,
                _textureHeight);
            ((RawImage)_graphic).texture = _lottieAnimation.Texture;
            _waitForEndOfFrame = new WaitForEndOfFrame();
            StartCoroutine(RenderLottieAnimationCoroutine());
        }
        private void OnDestroy()
        {
            _lottieAnimation?.Dispose();
            _lottieAnimation = null;
        }

        private IEnumerator RenderLottieAnimationCoroutine()
        {
            while (true)
            {
                if (_lottieAnimation != null)
                {
                    _lottieAnimation.Update();
                }
                yield return _waitForEndOfFrame;
            }
        }
    }
}

Please let me know if this resolves the issue.

Hey @TigerHix, any news?

I just tested the changes and it worked! All hail ChatGPT! 😆

I don't quite understand how this fixed the issue, but glad it's now fixed.

Thanks for investigating into this issue!

Thanks for the test! Glad it is fixed for you.
You can also try out the latest 0.2.1 version, there is AnimatedImage component that does similar thing as AnimatedLogo class.