理解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的视图。
然后程序刚刚运行,在Game视图下的正中间的是Camera看到的,右下角的是showCamera得到的,不信的话在场景中移动这两个Camera就能看到视图的区别。Inspector面板上的Full Body Render的图像就是整个截图的右下角,其实还是showCamra得到的。因为在程序的start()函数里showCamra.TargetTexture = FullBodyRender
点击完GetPic按钮以后,就得到如下视图,注意此时已经得到Texture2D,也就是照相机快照啦:
也可以存储成图片,如下:
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;