Unity RenderTexture的应用

C#

浏览数:201

2019-8-30

在开发过程中,有2个与RenderText相关的2个需求,看到 Unity3d中渲染到RenderTexture的原理,几种方式以及一些问题 这篇博客,对RenderText的理解更深了一些。

将这个FBO直接关联一个GPU上的texture对象,这样就等于在绘制时就直接绘制到这个texure上,这样也省去了拷贝时间,GLES中一般是使用FramebufferTexture2D()这样的接口。
那么unity的RenderTexture正是这种方式的一种实现,它定义了在server-side的一个tex对象,然后将渲染直接绘制到这个tex上。

在此记录一下RenderTexture的应用。

  1. UGUI上显示模型(粒子特效由于Alpha透明通道,显示会有一点问题,可以通过Shader Blend混合处理)

  2. Camera相机拍照分享,保存为jpg

这两个功能的原理都是: One typical usage of render textures is setting them as the “target texture” property of a Camera ( Camera.targetTexture ), this will make a camera render into a texture instead of rendering to the screen.
官方文档

1. UGUI上显示模型

UGUI上显示模型.png

  1. 创建拍摄用的摄像机
  2. 创建RenderTexture并绑定到摄像机camera.targetTexture上
  3. RenderTexture绑定到rawImage.texture上(rawImage见上图)
  4. 创建显示的模型,相机可见
  5. 注意Destroy销毁 创建出来的RenderTexture 和相机
  6. 注意模型上的粒子特效由于Alpha透明通道,显示会有一点问题,可以通过Shader Blend混合处理,挂载在rawImage上。
public void CreateCamera(Vector3 pos, Vector3 rot, int width, int height, string layerName, float size)
{
    // 创建拍摄用的摄像机
    GameObject go = new GameObject("ModelCamera");
    _camera = go.AddComponent<Camera>();
    _camera.clearFlags = CameraClearFlags.SolidColor;
    _camera.transform.position = pos;
    _camera.transform.rotation = Quaternion.Euler(rot);
    _camera.cullingMask = LayerMask.GetMask(layerName);
    _camera.orthographic = true;
    _camera.orthographicSize = size;
    _camera.backgroundColor = new Color(0,0,0,0);

    // 创建RenderTexture并绑定到摄像机上
    _renderTexture = new RenderTexture(width, height, 8);
    _camera.targetTexture = _renderTexture;

    if (_rawImage != null)
    {
        _rawImage.texture = _renderTexture;
    }
}

2. Camera相机拍照分享,保存为jpg

private IEnumerator CameraPhoto(Camera cam, Rect rect, string name) {
    if (rt == null) {
        rt = RenderTexture.GetTemporary(renderTextureDesc);
    }
    cam.targetTexture = rt;
    cam.Render();

    RenderTexture currentActiveRT = RenderTexture.active;
    RenderTexture.active = rt;
    Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
    screenShot.ReadPixels(rect, 0, 0);
    screenShot.Apply();
    yield return new WaitForEndOfFrame();

    cam.targetTexture = null;
    RenderTexture.active = currentActiveRT;

    byte[] bytes = screenShot.EncodeToJPG();
    string file = Application.dataPath + "/Texture/" + name;
    System.IO.File.WriteAllBytes(file, bytes);
}
  1. Rendertexture的分配和销毁上有一个地方需要注意:
    如果频繁的要new一个rt出来,那么不要直接new,而是使用RenderTexture提供的GetTemporary和ReleaseTemporary,它将在内部维护一个池,反复重用一些大小格式一样的rt资源,因为让GPU为你分配一个新的texture其实是要耗时间的。
  2. EncodeToJPG 生成的图片体积更小

相关文章

Unity 深度缓冲区之查看深度图

作者:云木unity