Unity有个消息方法 叫 OnRenderImage
MonoBehaviour.OnRenderImage(RenderTexture source,RenderTexture destination)
官方描述Description
OnRenderImage is called after all rendering is complete to render image.,该函数在所有的渲染完成后由monobehavior自动调用。
官方解释:该函数允许我们使用着色器滤波操作来修改最终的图像,输入原图像source,输出的图像放在desitination里。
public class OneShot : MonoBehaviour
{
private bool mirror;
private Action<Texture2D> callback;
private bool capturing;
public void OnRenderImage(RenderTexture source, RenderTexture destination)
{
Graphics.Blit(source, destination);
if (!capturing) { return; }
var destTexture = new RenderTexture(Screen.width, Screen.height, 0);
if (mirror)
{
var mat = Instantiate(Resources.Load<Material>("Sample_MirrorTexture"));
mat.mainTexture = source;
Graphics.Blit(null, destTexture, mat);
}
else
{
Graphics.Blit(source, destTexture);
}
RenderTexture.active = destTexture;
var texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
texture.Apply();
RenderTexture.active = null;
Destroy(destTexture);
callback(texture);
Destroy(this);
}
public void Shot(bool mirror, Action<Texture2D> callback)
{
if (callback == null) { return; }
this.mirror = mirror;
this.callback = callback;
capturing = true;
}
}
方法持续调用,考虑截图功能在项目中使用次数较少,所以尽量在使用的时候进行AddComponent 操作,然后在用完后Destroy掉。
public void Snapshot()
{
var oneShot = Camera.main.gameObject.AddComponent<OneShot>();
oneShot.Shot(true, (texture) =>
{
if (capturedImage)
{
Destroy(capturedImage);
}
capturedImage = texture;
PreviewImage.texture = capturedImage;
});
}