본문 바로가기

Programming/Unity

Unity - 렌더 텍스처 이미지로 저장하기

 

사이드 프로젝트를 진행하던 와중에, 캐릭터들의 초상화를 각각 이미지로 저장해줘야 할 일이 생겼어요.

캐릭터가 3D 오브젝트였고, 바리에이션이 존재하는 상황이라 유니티에서 렌더 텍스처를 사용해 초상화 이미지 파일을 생성하는 방향으로 결정했습니다.

 

렌더텍스처와 스크립트 적용 화면

 

일단 렌더 텍스처를 생성해 캐릭터를 렌더할 카메라와 연결해 줍니다.
(Unity 매뉴얼 참고 - Project 창 우클릭 / Create / Render Texture → 렌더할 카메라의 Target Texture에 링크)

 

 

렌더 텍스처 - Unity 매뉴얼

렌더 텍스처는 Unity가 런타임 시점에 생성하고 업데이트하는 텍스처입니다. 렌더 텍스처를 사용하려면 Assets > Create > Render Texture를 사용하여 새 렌더 텍스처를 생성한 후 Camera 컴포넌트의 타겟

docs.unity3d.com

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;

public class RenderTextureExporter : MonoBehaviour
{
    [SerializeField] private RenderTexture texture;
    [SerializeField] private string saveLocation;
    [SerializeField] private string name;

    public void SaveTexture()
    {
        RenderTexture.active = texture;
        var texture2D = new Texture2D(texture.width, texture.height);
        texture2D.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);
        texture2D.Apply();

        var data = texture2D.EncodeToPNG();

        string fileName = name + ".png";
        string path = System.IO.Path.Combine(Application.dataPath, saveLocation, fileName);
        File.WriteAllBytes(path, data);
    }
}

 

그 이후에, 렌더 텍스처를 이미지로 저장해주는 스크립트를 추가해줍니다.

유니티 에셋 내 경로와 파일 이름을 지정해서 저장할 수 있게 해주고, 에디터 스크립트를 추가해서 인스펙터에서 간단하게 이미지를 저장할 수 있게 처리했습니다.

 

RenderTexture.active = texture;
···
texture2D.ReadPixels(new Rect(0, 0, texture.width, texture.height), 0, 0);

 

스크립트를 작성하면서 궁금했던 부분은 텍스처를 링크해주었는데, 왜 RenderTexture.active 에 값을 넣어주는지 였는데, Texture2D.ReadPixels() 메소드가 현재 활성화된 렌더 텍스처에서 값을 읽어오기 때문이었습니다.

 

현재 렌더링 대상(화면 또는 RenderTexture)에서 픽셀을 읽고 텍스처에 씁니다.
이 메소드는 현재 활성화된 렌더 타겟에서 직사각형 픽셀 영역을 복사하고, destX와 destY로 정의된 텍스처의 위치에 씁니다. 두 좌표 모두 픽셀 좌표계를 사용하며, 왼쪽 아래가 (0,0)입니다.

- Textrue2D.ReadPixels Unity 스크립팅 API 中
 

Texture2D-ReadPixels - Unity 스크립팅 API

Reads the pixels from the current render target (the screen, or a RenderTexture), and writes them to the texture.

docs.unity3d.com

 

RenderTexture-active - Unity 스크립팅 API

Currently active render texture.

docs.unity3d.com

 


 

아래 글들에서 너무 많은 도움을 받았습니다 😍

 

[C#] 유니티 렌더텍스쳐 이미지로 저장

유니티에서 렌더텍스쳐 이미지로 저장 using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; public class Shutter : MonoBehaviour { public RenderTexture DrawTe..

mgtul.tistory.com

 

Convert RenderTexture to Texture2D

I need to save a RenderTexture object to a .png file that will then be used as a texture to wrap about a 3D object. My problem is right now I can't save a RenderTexture object using EncodeToPNG() b...

stackoverflow.com

 


 

번외로, 회사에서도 캐릭터를 UI상에 그릴 때 렌더 텍스처를 사용하는데,
2d 캐릭터를 렌더 텍스처로 그렸을 때 스프라이트가 겹쳐진 부분에서 경계가 끊겨 보이는 문제가 발생하더라고요.

렌더 텍스처에서 타겟을 그릴 때, 스텐실 버퍼를 사용하면서 스프라이트 경계의 알파 부분이 discard 되면서 끊어져 보이는게 아닌가? 싶기는 한데, 나중에 시간내서 한번 체크해 보려고 합니다.

+ 렌더 텍스처의 Color Format을 변경하면 끊겨 보이는 문제가 해결되는 것 같은데, 이것도 추후에 확인할 내용에 추가...