理解Unity的TextureRender

搞的头快秃了。先记下来再说:

首先理解GUI.DrawTexture(),参考博客,已经讲解的很详细了:https://blog.****.net/iFuMI/article/details/51156357

然后理解摄像机目标渲染纹理targetTexture,参考博客,已经讲解的很详细了:https://blog.****.net/jk823394954/article/details/52431470

Texture2D.ReadPixel(),参考博客:https://docs.unity3d.com/ScriptReference/Texture2D.ReadPixels.html

Texture2D.Apply(),参考博客:https://docs.unity3d.com/ScriptReference/Texture2D.Apply.html

http://www.cnblogs.com/lyh916/p/9058403.html

我是看的一个博主的博客进行的实验,对他的代码进行了简约化:

https://www.cnblogs.com/martianzone/p/3292695.html

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

public class GetPicTest : MonoBehaviour
{
    /// <summary>
    /// 创建角色所在位置
    /// </summary>
    public Transform playerPos;
    /// <summary>
    /// 声明一个全身照的RenderTexture
    /// </summary>
    public RenderTexture fullBodyRender;
    /// <summary>
    /// 将fullBodyRender的特定一帧动画保存到fullBodyTex
    /// </summary>
    public Texture2D fullBodyTex;
    /// <summary>
    /// 全身相机
    /// </summary>
    public Camera showCamera;
    /// <summary>
    /// 保存角色预置
    /// </summary>
   //public List<GameObject> charactersPrefabs = new List<GameObject>();

    public int _width = 120;
    public int _height = 120;
    //public GameObject obj;

    // Start is called before the first frame update
    void Start()
    {
        fullBodyRender = new RenderTexture(_width, _height, 32); //创建一个RenderTexture
        fullBodyRender.anisoLevel = 0; //设置该RenderTexture的各向异性
        fullBodyRender.filterMode = FilterMode.Point; //点过滤 - 纹理像素成为近似块。

        //可以把该摄像机的视图作为Renderer Texture,然后添加到一个Material对象形成一个新的材质,
        showCamera.targetTexture = fullBodyRender; //所以showCamera的视图就是fullBodyRender
        showCamera.pixelRect = new Rect(0, 0, _width, _height); //以实际像素来显示内容

    }

    // Update is called once per frame
    void Update()
    {
        
    }
    //直接在屏幕上绘制UI
    private void OnGUI()
    {
        //在屏幕中绘制一张fullBodyRender静态图
        GUI.DrawTexture(new Rect(Screen.width - _width, Screen.height - _height, _width, _height), fullBodyRender, ScaleMode.ScaleToFit);


        GUI.Box(new Rect(Screen.width - _width, 0, _width, _height), "哈哈哈哈");

        if (GUI.Button(new Rect(Screen.width/2-70,0,140,30),"GetPic"))
        {
            fullBodyTex = GetTexture2d(fullBodyRender); //相当于相机快闪
        
        }
        if (fullBodyTex)
        {
            GUI.DrawTexture(new Rect(Screen.width - _width,0,_width,_height), fullBodyTex, ScaleMode.ScaleToFit);

        }
    }
    public Texture2D GetTexture2d(RenderTexture renderT)
    {
        if (renderT == null)
            return null;

        int width = renderT.width;
        int height = renderT.height;
        Debug.Log(width);
        Debug.Log(height);

        Texture2D tex2d = new Texture2D(width, height, TextureFormat.ARGB32, false);
        RenderTexture.active = renderT; //所有的渲染进入**的RenderTexture renderT,如果活动的RenderTexture为null,所有的东西都被渲染到主窗口

        tex2d.ReadPixels(new Rect(0, 0, width, height), 0, 0); //Read pixels from screen into the saved texture data.
        tex2d.Apply();

        return tex2d;
    }
}

在程序运行之前,是这样的,Camera看到的cube比较大,因为离的近,showcamera看到的cube比较小,在Game视图先看到的是showcamera的视图。

理解Unity的TextureRender

 

然后程序刚刚运行,在Game视图下的正中间的是Camera看到的,右下角的是showCamera得到的,不信的话在场景中移动这两个Camera就能看到视图的区别。Inspector面板上的Full Body Render的图像就是整个截图的右下角,其实还是showCamra得到的。因为在程序的start()函数里showCamra.TargetTexture = FullBodyRender

理解Unity的TextureRender

点击完GetPic按钮以后,就得到如下视图,注意此时已经得到Texture2D,也就是照相机快照啦:

理解Unity的TextureRender

理解Unity的TextureRender

也可以存储成图片,如下:

tex2d.ReadPixels(new Rect(0, 0, width, height), 0, 0); //Read pixels from screen into the saved texture data.
        tex2d.Apply();

        byte[] b = tex2d.EncodeToPNG();
        Debug.Log(Application.dataPath);
        File.WriteAllBytes(Application.dataPath + "1.jpg", b);

        return tex2d;

 

理解Unity的TextureRender