같은 Texture에서 여러 개의 Sprite를 생성할 때 SetPassCall은 1이라는 말 + 동적으로 그것을 진행하는 방법

10400 단어 Unity
이 보도의 내용은 제목과 같다.
여러 개의 이미지를 하나의 무늬로 포장한 다음에 원시 이미지의 수량과 상응하는 Sprite를 생성할 때 SetPassCall은 1만 있으면 된다.
나는 중요한 이동 환경에서 특히 유용하다고 생각한다. 얼마나 많은 SetPassCall을 줄일 수 있는지.
이번에는 Texture Packing과 Sprite 생성을 동적으로 진행함으로써 이 방법을 유연하게 활용할 것입니다.
다음은 이해하기 쉬운 결과의 그림을 붙인다.

(※ 이해하기 어렵지만 아무것도 없는 경우 SetPassCall이 2이므로 추가된 것은 1에 불과합니다.)
또한, Unity 5.6.0f3로 검증.

개시하다


설마, 대량의 Texture Packing을 그림으로 만들어서 Sprite를 만드는 건 아니겠지.Create의 SetPassCall이 1인가요? - Negipoyc(@CST negi)2017년 4월 15일.
@CST_negi그렇습니다.-이토 주간(@warapuri)2017년 4월 15일.

확인


Script를 작성합니다.
내용
1. WWW를 사용하여 10장의 이미지를 다운로드합니다.
2. 모든 이미지를 다운로드할 수 있다면 이미지로 포장한다.
3. 봉인된 텍스쳐부터 스프릿.Create를 사용하여 원래 이미지를 Sprite화합니다.
4. Sprite Renderer 10개의 경우 3.에서 만든 Sprite를 지정합니다.
TexPacker.cs
using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using System.Linq;

public class TexPacker : MonoBehaviour
{
    void Start()
    {
        //10個SpriteRendererを取得する
        var spriteRenderers = GetComponentsInChildren<SpriteRenderer>();
        //1.WWWを使って、画像を10枚ダウンロードする
        var streams = Enumerable.Range(0,spriteRenderers.Count()).Select(i => Observable.FromCoroutine<Texture2D>(obs => GetTextures(i.ToString(), obs)));
        //2. すべての画像がダウンロードできたら
        Observable.WhenAll(streams)
            .Subscribe(textures =>
            {
                //2.それらを用いて1枚の画像にパッキングする。
                var packedTexture = new Texture2D(4096, 4096);

                //このuvsにはPackした画像のどこに元画像があるかを格納するものです。
                //(x:0.39, y:0.88, width:0.25, height:0.06)のような値がパックした枚数分入ってます。
                var uvs = packedTexture.PackTextures(textures, 0, 4096, false);

                //元画像を切り出すためにPackした画像のWとHをとっておく
                var packedTextureWidth = packedTexture.width;
                var packedTextureHeight = packedTexture.height;

                for (var i = 0; i < spriteRenderers.Length; i++)
                {
                    //3.元の画像をSprite化する。Packした画像のwとh、そしてuvsを使うことで元の画像を切り抜ける。
                    //またメッシュは矩形でいいので、SpriteMeshType.FullRectを指定してSprite化するとき余計な負荷がかからないようにする。
                    var s = Sprite.Create(packedTexture, new Rect(packedTextureWidth * uvs[i].x, packedTextureHeight * uvs[i].y, packedTextureWidth * uvs[i].width, packedTextureHeight * uvs[i].height), Vector2.one * 0.5f, 100, 10, SpriteMeshType.FullRect);

                    //4.10個のSpriteRendererに対して3.で作ったSpriteを割り当てる。
                    spriteRenderers[i].sprite = s;
                }
            });
    }

    //WWWを使ってダウンロードするやつ。今回はStreamingAssetsからロードしている。
    IEnumerator GetTextures(string i, IObserver<Texture2D> observer)
    {
        var filePath = "file:///" + Application.streamingAssetsPath + "/image" + i + ".png";
        var www = new WWW(filePath);
        {
            while (!www.isDone) { yield return null; }
            var tex = www.texture;
            observer.OnNext(tex);
        }
        observer.OnCompleted();
    }
}
이때의 Hierrarchy는 이랬다.

끝맺다


결과는 문장의 첫머리와 같다.
Sprite가 여러 개인 경우에도 SetPassCall을 1로 제어할 수 있습니다.
동적으로 진행할 수 있기 때문에 인터넷에 그림이 있어도 WWW를 사용할 수 있다.
이럴 때 유니렉스의 WhenAll의 소중함을 느낄 수 있다.

좋은 웹페이지 즐겨찾기