(URP프로젝트에서는 안 됨)
광고를 위해 배경을 투명하게 캡처해야 할 일이 생겨서 R&D함
그냥 렌더 텍스쳐를 png로 뽑으면 될 줄 알았는데..
잘 안 되서 여기저기 검색해서 정리해봄
using System.Collections;
using UnityEngine;
public class TransparencyCapture : MonoBehaviour
{
public Camera _camera;
private void Update()
{
if (Input.GetKey(KeyCode.Space))
{
Capture();
}
}
private void Capture()
{
string path = Application.dataPath + "/capture.png";
StartCoroutine(CoCapture(path));
}
private IEnumerator CoCapture(string path)
{
if (path == null)
{
yield break;
}
// ReadPixels을 하기 위해서 쉬어줌
yield return new WaitForEndOfFrame();
Rect rect = new Rect(0f, 0f, Screen.width, Screen.height);
Texture2D texture = Capture(Camera.main, rect);
byte[] bytes = texture.EncodeToPNG();
System.IO.File.WriteAllBytes(path, bytes);
}
private Texture2D Capture(Camera camera, Rect pRect)
{
Texture2D capture;
CameraClearFlags preClearFlags = camera.clearFlags;
Color preBackgroundColor = camera.backgroundColor;
{
camera.clearFlags = CameraClearFlags.SolidColor;
camera.backgroundColor = Color.black;
camera.Render();
Texture2D blackBackgroundCapture = CaptureView(pRect);
camera.backgroundColor = Color.white;
camera.Render();
Texture2D whiteBackgroundCapture = CaptureView(pRect);
for (int x = 0; x < whiteBackgroundCapture.width; ++x)
{
for (int y = 0; y < whiteBackgroundCapture.height; ++y)
{
Color black = blackBackgroundCapture.GetPixel(x, y);
Color white = whiteBackgroundCapture.GetPixel(x, y);
if (black != Color.clear)
{
whiteBackgroundCapture.SetPixel(x, y, GetColor(black, white));
}
}
}
whiteBackgroundCapture.Apply();
capture = whiteBackgroundCapture;
Object.DestroyImmediate(blackBackgroundCapture);
}
camera.backgroundColor = preBackgroundColor;
camera.clearFlags = preClearFlags;
return capture;
}
private Color GetColor(Color black, Color white)
{
float alpha = GetAlpha(black.r, white.r);
return new Color(
black.r / alpha,
black.g / alpha,
black.b / alpha,
alpha);
}
private float GetAlpha(float black, float white)
{
return 1 + black - white;
}
private Texture2D CaptureView(Rect rect)
{
Texture2D captureView = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.ARGB32, false);
captureView.ReadPixels(rect, 0, 0, false);
return captureView;
}
}
잘나온 거 같은데 완벽하진 않은 것 같음
'개발 > Unity, C#' 카테고리의 다른 글
Unity 2Pass Outline Toon Shader (0) | 2020.12.26 |
---|---|
Unity 하드웨어 스펙으로 자동 옵션 세팅하기 (0) | 2020.10.18 |
C# Closure 클로저 (0) | 2020.04.18 |
Unity 2019.3 URP Camera Stacking (0) | 2020.04.04 |
Unity Safe Area, Device Simulator (0) | 2019.12.29 |