Render Texture是什么呢?
Render Texture是一种你可以在其上绘制,然后像使用其它精灵/纹理一样的纹理。其中,最酷的一件事就是你可以将它作为相机视图的目标——这样相机把它所看到的绘制到纹理上(而不是显示在屏幕上)。
另外,这里还包含了一个可把渲染纹理保存为.PNG文件的脚本,你可以随便使用。
在TV上显示一个监控相机(忽略右下的吸血鬼...)
该技术类似于一个监控相机设置。你有一相机可以摄像,然后把它记录到渲染纹理上(相当于视频带或硬件驱动存放图像),最后把图像投影到TV屏幕上。
下载
你可下载完整的Unity包(需unity5+ 版本),或跟着教程做。
完整工程&资源文件见文末。
包中有一个显示几个随机对象(和一个吸血鬼!)的demo场景。相机指向随机对象,并把它显示到TV屏幕上。
吸血鬼里有一个不错的设计——可以选择哪个相机可见(当然,镜子或相机不能看到吸血鬼)。
在示例场景中,可以通过下列控制观看场景:
· 箭头按键——移动监控相机
· V——切换吸血鬼的可见性
· S——将监控相机当前视图存为.PNG文件。
具体步骤
若你对Unity非常熟悉,可以跳过本节。
对于Unity新手,这里会详细讲解大部分基本操作。若有不理解或想不通,只需要打开资源包,就是一个非常简单的工程,看看这些对象及其设置。
这个技术很大的优势就是不需要一行代码就能完成关键功能。它们都包含在了Unity的编辑器中了。
本工程有两个脚本,但是他们有另外的功能(其中一个是移动相机,另一个是保存渲染纹理为.PNG文件的)。
新建工程
新建一个3D的Unity项目。
你需要两个精灵资源(TV和吸血鬼)。可以从下载文件中获取或使用你自己的。
把TV放到场景中,然后在其他地方随机放置些对象(待会要用监控相机观察这些对象)。把吸血鬼放到这些随机对象当中。
为使TV和吸血鬼精灵导入到场景中,需要选中它们,然后把纹理类型改为Sprite。
调整TV大小来使其看起来大小合适。缩放比为(4,4,1)差不多刚好。它会把放置到场景视图中的对象转换为2D的。
你可以直接使用Untiy主菜单(比如:Main Menu>GameObject>3D Object>Cube)创建球型和立方体等等,或通过拖拽一些精灵到场景中来创建一些随机项以供相机查看。
场景大致如下图所示后,进入下一步。
场景如图
创建吸血鬼
通过创建一个特殊Layer并告诉监控相机忽略此层,使吸血鬼对相机不可见。
在层次面板中选中吸血鬼,然后选择添加图层...在属性面板下拉列表中添加新图层,如下:
创建新图层
在用户图层8的字段下键入“vampire”。
命名为‘vampire’
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps8B9E.tmp.png
设置图层目前不起任何作用,但是在我们操作几步后,它就会起作用了。
创建渲染纹理
在资源文件夹任意地方右键单击,选择Create > Render Texture。就新建了一个Render Texture。命名为SecurityCameraTexture。
创建一个渲染纹理
选择SecurityCameraTexture纹理,在属性面板中设置它大小为480x270。大小决定着它的分辨率,以及将要从相机视图中保存的.PNG图像的分辨率。
设置渲染纹理的大小
从Render Texture创建材质
使用刚才创建的SecurityCameraTexture创建一个新的材质 :
- 在资源文件夹任意地方右键单击
- 选择Create > Material,命名为SecurityFootage
- 选中新材质,修改它的着色器属性(在属性面板上)为Mobile/Diffuse(你需要让它的材质接受一个纹理,缺省是不支持的)。
- 把SecurityCameraTexture 拖拽到材质的纹理属性上(右上角带有山峰照片的小盒子上):
创建新材质
至此,我们创建了一个材质,它可以把theSecurityCameraTexture 纹理显示到任何对象表面。
监控相机
向场景中添加一个新的相机(Main Menu > GameObject > Camera)。
重命名新相机为SecurityCamera。
把SecurityCameraTexture 拖拽到SecrityCamera的Target Texture字段上。这就使相机视图显示渲染纹理而不是显示到屏幕上,因为相机此时是作为录像而不是把它显示到游戏屏幕上。
当相机被选中,你可以看到一个可看到场景窗口的小小预览窗口。
当相机被选中时,它的视图在预览窗口中显示的是场景视图。你的场景也许与上图不太一样。
把相机移动到可以看到所有对象和吸血鬼的地方。你需要确保相机在你3D空间场景的前方,这样就可以看到场景中所有对象。当相机预览窗口可以看到所有对象时(不包括TV屏幕),进行下个步骤。
过滤吸血鬼
在上图预览窗口(需要把对象显示在TV屏幕上,待会就可以了)中,你不能看到吸血鬼。为过滤吸血鬼,在层次面板中选中SecurityCamera,然后从它的Culling Mask中移除vampirelayer (这样它就看不vampire图层的任何东西):
- 在层次面板中选中SecurityCamera
- 在属性面板中,点击Culling Mask 的下拉列表
- 取消勾选vampire图层(勾选的图层是相机可见的)。
过滤vampire图层的对象
若在相机预览中吸血鬼依旧可见,回去看看,确保吸血鬼的Layer设置为vampir。
创建TV
在场景中创建一个平面(Main Menu > GameObject > 3D Object > Plane)。重命名平面为TVScreen。
若之前没有用过平面,可能会觉得奇怪。因为平面是一个二维的平面,它在某些角度和视角下可能看不到。旋转平面使其面向相机。切换3D和2D场景视图以便于修改。
修改TV Screen使其适合TV精灵的屏幕。确保它被放置到TV精灵的正前方,让主相机看到它。
拖拽SecurityFootage 到TV Screen的材质的Element 0属性(待会你需要像屏幕下方一样扩展材质列表):
使用之前创建的SecurityFootage作为平面的材质
至此,已经把材质关联到TV 屏幕上。你会想起之前的步骤,材质将显示监控相机看到的内容。
若TV图片上下颠倒,你需要旋转平面到正确位置。
就是这样!
你甚至不需要运行场景就可以看到场景对象(除了吸血鬼)显示到TV屏幕上了。超级棒!
我们总结一下基本步骤:
- 创建一个Render Texture
- 创建一个相机将其看到的内容绘制到Render Texture上
- 创建一个材质来显示Render Texture
- 最后,创建TV 屏幕显示材质。
跟真的监控相机一样,我们捕捉视图,通过一个录像设备(渲染纹理类似于电影的摄像机)把它发送到一个屏幕上。
提高部分
示例工程中包含两个额外的代码。一个脚本是添加一些用户控制以便移动监控相机和切换吸血鬼的显示和隐藏;另一个脚本当按下“S”键时,把监控相机视图保存为一个.PNG格式图片文件。第二个脚本如下,并做了注释。
保存渲染纹理
代码是Unity问答上的‘Mate-O’ 编写,做了些修改(http://answers.unity3d.com/questions/22954/how-to-save-a-picture-take-screenshot-from-a-camer.html)
代码很简单——读取渲染纹理像素,编码为.PNG ,最后保存为.PNG。注释说明了每段代码功能。
[C#]
纯文本查看
复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
using
UnityEngine;
using
System.Collections;
using
System;
public
class
CameraSnapshot : MonoBehaviour
{
[SerializeField]
RenderTexture securityCameraTexture;
[SerializeField]
Camera securityCamera;
void
LateUpdate()
{
if
(Input.GetKeyDown(
"s"
))
{
StartCoroutine(SaveCameraView());
}
}
public
IEnumerator SaveCameraView()
{
yield
return
new
WaitForEndOfFrame();
RenderTexture rendText= RenderTexture.active;
RenderTexture.active = securityCamera.targetTexture;
securityCamera.Render();
Texture2D cameraImage=
new
Texture2D(securityCamera.targetTexture.width, securityCamera.targetTexture.height, TextureFormat.RGB24,
false
);
cameraImage.ReadPixels(
new
Rect(0, 0, securityCamera.targetTexture.width, securityCamera.targetTexture.height), 0, 0);
cameraImage.Apply();
RenderTexture.active = rendText;
byte
[] bytes = cameraImage.EncodeToPNG();
System.IO.File.WriteAllBytes(Application.persistentDataPath +
"/camera_image.png"
, bytes);
}
}
|
一旦脚本添加到场景中,就可以按下“S”键来获取相机截图。你可以访问保存的文件。
总结
Render Texture是一个你可以绘制的画布。通过关联渲染纹理到相机的输出,就可以把相机所见绘制到渲染纹理上。
因为渲染纹理是一个纹理,就可以把它关联到材质上。然后,添加材质到对象上并有效的把渲染纹理投影到对象的表面。
监控显示是对它的工作原理是一个很好的比喻。相机就是相机,渲染纹理是视频录制,材质是你视频投影到的屏幕。