런타임 최적화를 위해 머터리얼에 들어있는 텍스처를 압축 하는 중에 문제 발생.
머터리얼에 들어 있는 텍스처를 수정하기 위해서는 Read/Write가 true가 되어야하는데 이것은 에디터에서만 설정할 수 있다. 텍스처를 복제하여 새롭게 생성해주면 수정이 가능하기 때문에 기존의 텍스처를 복제하려고 했다.
하지만 문제가 많이 발생했다.
1. 에디터에서는 잘 동작. 하지만 윈도우 빌드에서는 GetRawTextureData 부분에서 읽을 수 없다는 에러발생.(GetPixels도 마찬가지)
Texture2D tex = (Texture2D)mat.GetTexture(name);
byte[] data = tex.GetRawTextureData();
Texture2D compressTex = new Texture2D(tex.width, tex.height, tex.format, false);
compressTex.LoadRawTextureData(data);
바이트 배열로 가져오기도 힘듬.
2. 이 또한 에디터에서는 잘 동작함. 하지만 윈도우 빌드에서는 텍스처가 전부 회색으로 변함.
Texture2D compressTex = new Texture2D(tex.width, tex.height, tex.format, false);
Graphics.CopyTexture(tex, compressTex);
Graphics.CopyTexture 는 기본적으로 GPU에서 동작한다.
공식문서에서는 텍스처의 isReadable이 true로 설정되어 있어야 CPU에 있는 데이터에 접근 가능하다고 한다.
그런데 이것은 읽기 전용이므로 코드 상에서 수정할 수 없고, 에디터에서 설정해야하는 것 같다.
Texture2D compressTex = new Texture2D(tex.width, tex.height, tex.format, false); 는 cpu에 올라가 있으므로, 이것도 사용 불가능.
3. 해결방법. 에디터에서도 잘 동작하고 윈도우 빌드에서도 잘 동작함.
public Texture2D DuplicateTexture(Texture source)
{
RenderTexture renderTex = RenderTexture.GetTemporary(source.width,source.height);
Graphics.Blit(source, renderTex);
RenderTexture.active = renderTex;
Texture2D readableTexture = new Texture2D(source.width, source.height);
readableTexture.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
readableTexture.Apply();
RenderTexture.ReleaseTemporary(renderTex);
MonoBehaviour.Destroy(source);
return readableTexture;
}
RenderTexture을 이용하면 GPU 측에서 작업이 가능하다. 위 코드는 GPU에서 텍스처를 복제하고 ReadPixels를 통해 CPU 작업으로 넘겨주는 원리이다.
원인을 몰라서 3일동안 고생했는데, 앞으로 텍스처에 접근할 일이 있으면 RenderTexture 를 사용해야겠다.
'유니티(Unity)' 카테고리의 다른 글
vscode와 유니티에서 async 스레드 테스트 (0) | 2024.05.01 |
---|---|
자바스크립트 Dll 사용하기 (0) | 2024.04.30 |
텍스처 (0) | 2024.04.13 |
그래픽스 퍼포먼스 최적화 전후 (0) | 2024.04.08 |
Unity 3D 렌더링 최적화 및 fps 높이기 (0) | 2024.04.04 |