При загрузке изображений в необработанное изображение есть небольшая небольшая задержка, все равно, когда он запускается снова, чтобы избежать задержки? - PullRequest
1 голос
/ 10 июля 2020

Он работает очень хорошо, но все же есть небольшая задержка в обновлении , когда оно снова запускается l oop. Это почти идеальная плавная петля. Я не уверен, что вызывает эту задержку и как ее избежать.

Возможно, проблема в том, что последнее изображение черное. Я сделал это в блендере, чтобы первый и последний кадры были черными. Может ли это вызвать эффект задержки?

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;

public class StreamVideo : MonoBehaviour
{
    public Texture[] frames;                // array of textures
    public float framesPerSecond = 2.0f;    // delay between frames
    public RawImage image;

    void Start()
    {
        DirectoryInfo dir = new DirectoryInfo(@"C:\tmp");
        // since you use ToLower() the capitalized version are quite redundant btw ;)
        string[] extensions = new[] { ".jpg", ".jpeg", ".png", ".ogg" };
        FileInfo[] info = dir.GetFiles().Where(f => extensions.Contains(f.Extension.ToLower())).ToArray();

        if (!image)
        {
            //Get Raw Image Reference
            image = gameObject.GetComponent<RawImage>();
        }

        frames = GetTextures(info);
    }

    private Texture[] GetTextures(FileInfo[] fileInfos)
    {
        var output = new Texture[fileInfos.Length];
        for (var i = 0; i < fileInfos.Length; i++)
        {
            var bytes = File.ReadAllBytes(fileInfos[i].FullName);
            output[i] = new Texture2D(1, 1);
            if (!ImageConversion.LoadImage((Texture2D)output[i], bytes, false))
            {
                Debug.LogError($"Could not load image from {fileInfos.Length}!", this);
            }
        }

        return output;
    }

    void Update()
    {
        int index = (int)(Time.time * framesPerSecond) % frames.Length;
        image.texture = frames[index]; //Change The Image
    }
}

1 Ответ

1 голос
/ 10 июля 2020

Отправка текстур из ОЗУ в GPU каждый кадр не идеален и не нужен на самом деле.

Вы можете загружать все текстуры в GPU на Start(). А затем используйте Update() только для изредка update MaterialPropertyBlock (или другого типа облегченного указателя, который понимает GPU), чтобы указать, какую (ранее загруженную) текстуру отрисовывать с этого момента.

Texture2D.Apply () отправляет данные текстуры из RAM (CPU) в GPU. Следовательно, будут загружены все кадры:

frames = GetTextures(info);
foreach( var frame in frames )
    frame.Apply( updateMipmaps:true , makeNoLongerReadable:true );

Чтобы узнать, какие текстуры черные:

for( int i=0 ; i<frames.Length ; i++ )
{
    var frame = frames[i];
    if( IsItAllBlack(frame) )
        Debug.Log($"frame #{i} is all black");
}

bool IsItAllBlack ( Texture2D tex )
{
    var pixels = tex.GetPixels();
    foreach( var col in pixels )
        if( (col.r+col.g+col.b)>0 )
            return false;
    return true;
}

Кстати: не забудьте освободить память, используемую этими текстурами, если они больше не нужны:

foreach( var frame in frames )
    Destroy(frame);

Это не происходит автоматически, когда текстура загружается вручную из кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...