当前位置: 首页 > news >正文

使用渲染纹理的制作摄像头

https://www.cnblogs.com/chenliyang/p/6558455.html

使用渲染纹理的制作摄像头

从Unity5版本开始,渲染纹理的功能对所有用户开放(是的,包括免费版本)!你可以使用此功能来创造很酷的效果,在本文中,我将向你说明怎么创建一个很酷的监控相机,把相机视图投影到屏幕上。

什么是渲染纹理呢?

渲染纹理是一种你可以在其上绘制,然后像使用其他精灵/纹理一样的纹理。其中,最酷的一件事就是你可以使用它作为相机视图的目标——这样相机把它所见的绘制到纹理上(而不是显示在屏幕上)。

另外,这里还包含了一个可把渲染纹理保存为.PNG文件的脚本,你可以随便使用。

 

在TV上显示一个监控相机(忽略吸血鬼...)

该技术类似于一个监控相机设置。你有一个可看见图像的相机,然后把它记录到渲染纹理上(相当于视频带或硬件驱动存放图像),最后把图像投影到TV屏幕上。

下载

你可下载完整的Unity包(需Unity5+ 版本),或你可以跟教程做。

这个包中包括一个随机显示对象(和一个吸血鬼!)的demo场景。相机指向随机的对象,并把它显示到TV屏幕上。

吸血鬼里有一个不错的设计——你选择哪个相机是否可看见(当然,镜子或相机不能看到吸血鬼)。

在样例场景中,你可以做如下控制:

· 箭头按键——移动监控相机

· V——切换吸血鬼的可见性

· S——保存监控相机当前视图为.PNG文件。

具体步骤

若你对Unity非常熟悉,你可以跳过本节。

对于Unity新手,这里会包含大部分的详细的基本操作。若你不理解或想不通,只需要打开资源包——一个非常简单的工程——看看这些对象和他们的设置。

这个技术很大的优势就是关键功能不需要一行代码。它们都包含在了Unity的编辑器中了。

本工程有两个脚本,但是他们是附加功能(其中一个是移动相机,另一个是保存渲染纹理为.PNG文件的)。

新建工程

新建的Unity的3D项目。

你需要的资源是两个精灵(一个TV和一个吸血鬼)。你可以从下载文件中找到或使用你自己的。

把TV放到屏幕上,然后在其他地方随机放置些对象(待会要用监控相机观察这些对象)。把吸血鬼放到这些随机对象当中。

为使TV和吸血鬼精灵导入到场景中,需要选中它们,然后把纹理类型改为精灵。

调整TV大小来使其看起来大小合适。缩放比为(4,4,1)差不多刚好。它会要把放置到场景视图中的对象转换为2D的。

你可以直接使用Untiy主菜单(比如:主菜单>GameObject>3D 对象>立方体)创建球型和立方体等等,或通过拖拽一些精灵到场景中来创建一些随机项供相机查看。

大致如下图所示,进入下一步。

 

场景如图

创建吸血鬼

通过创建一个特殊层并告诉监控相机忽略此层,使吸血鬼对相机不可见。

在层次面板中选中吸血鬼,然后选择添加图层...在属性面板下拉列表中添加新图层,如下:

 

创建新图层

在用户图层8的字段下键入“vampire”。

 

命名为‘vampire’

在吸血鬼选中的状态下,设置它的图层为吸血鬼:

 

设置图层目前不起任何作用,但是在我们操作几步后,它就会起作用了。

创建渲染纹理

在资源文件夹任意地方右键单击,选择创建>渲染纹理。创建一个新的渲染纹理。命名为SecurityCameraTexture。

 

创建一个渲染纹理

 

 

选择SecurityCameraTexture纹理,在属性面板中设置它大小为480x270。它的大小决定着它的分辨率,以及将要从相机视图中保存的.PNG图像的分辨率。

 

设置渲染纹理的大小

从渲染纹理创建材质

使用刚才创建的SecurityCameraTexture创建一个新的材质 :

1.  

在资源文件夹任意地方右键单击

2. 

选择创建>材质,命名为SecurityFootage

3. 

选中新材质,修改它的着色器属性(在属性面板上)为手机/漫反射(Mobile/Diffuse)(你需要让它的材质接受一个纹理,缺省是不支持的)。

4. 

把SecurityCameraTexture 拖拽到材质的纹理属性上(右上角带有山峰照片的小盒子上):

 

创建新材质

至此,我们创建了一个材质,它可以把theSecurityCameraTexture 纹理显示到任何对象表面。

监控相机

向场景中添加一个新的相机(主菜单>GameObject>相机)。

重命名新相机为SecurityCamera。

把SecurityCameraTexture 拖拽到SecrityCamera的目标纹理字段上。这就使相机视图显示渲染纹理而不是显示到屏幕上,因为相机此时是作为录像而不是把它显示到游戏屏幕上。

 

当相机被选中,你可以看到一个可看到场景窗口的小小预览窗口。

当相机被选中时,它的视图在预览窗口中显示的是场景视图。你的场景也许与上图不太一样。

 

把相机移动到可以看到所有对象和吸血鬼的地方。你需要确保相机在你3D空间场景的前方,这样就可以看到场景中所有对象。当可在相机预览窗口中看到所有对象时(不包括TV屏幕),进行下个步骤。

过滤吸血鬼

在上图预览窗口(需要把对象显示在TV屏幕上,待会就可以了)中,你不能看到吸血鬼。为过滤吸血鬼,在层次面板中选中SecurityCamera,然后从它的裁剪Mask中移除vampirelayer (这样它就看不吸血鬼图层的任何东西):

1. 

在层次面板中选中SecurityCamera 

2. 

在属性面板中,点击裁剪Mask的下拉列表

3. 

取消吸血鬼图层的对勾(勾选的图层是相机可见的)。

 

过滤vampire图层的对象

 

 若在相机预览中吸血鬼依旧可见,回去看看,确保你对吸血鬼创建了吸血鬼图层。

创建TV

在场景中创建一个平面(主菜单>GameObject>3D对象>平面(Plane))。重命名平面为TVScreen。

若你之前没有用过平面,可能会觉得奇怪。因为平面是一个二维的平面,它在某些角度和视角下可能看不到。旋转平面使其面向相机。切换3D和2D场景视图可帮助你修改它。

修改TV Screen使其适合TV精灵的屏幕。确保它被放置到TV精灵的正前方,让主相机看到它。

拖拽SecurityFootage 到TV Screen的材质>元素0(Element 0)的属性(待会你需要像屏幕下方一样扩展材质列表):

使用之前创建的SecurityFootage作为平面的材质

至此,已经把材质关联到TV 屏幕上。你会想起之前的步骤,材质将显示监控相机看到的。

若TV图片上下颠倒,你需要旋转平面到正确位置。

就是这样!

 

你甚至不需要运行场景就可以看到场景对象(除了吸血鬼)显示到TV屏幕上了。超级棒!

我们总结一下我们基本步骤:

1. 

创建一个渲染纹理

2. 

创建一个相机将看到的内容绘制到渲染纹理上

3. 

创建一个材质来显示渲染纹理

4. 

最后,创建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。注释说明了每段代码功能。

 

 

[csharp]  view plain  copy
 
 print?
  1. Code example:  
  2. using UnityEngine;  
  3. using System.Collections;  
  4. using System;  
  5.    
  6. public class CameraSnapshot : MonoBehaviour  
  7. {  
  8. [SerializeField]  
  9. RenderTexture securityCameraTexture;  // drag the render texture onto this field in the Inspector  
  10. [SerializeField]  
  11. Camera securityCamera; // drag the security camera onto this field in the inspector  
  12.    
  13. void LateUpdate()  
  14. {  
  15.    
  16.     if (Input.GetKeyDown("s"))  
  17.     {  
  18.         StartCoroutine(SaveCameraView());  
  19.     }  
  20.    
  21. }  
  22.    
  23. public IEnumerator SaveCameraView()  
  24. {  
  25.     yield return new WaitForEndOfFrame();  
  26.   
  27.     // get the camera's render texture  
  28.     RenderTexture rendText= RenderTexture.active;  
  29.     RenderTexture.active = securityCamera.targetTexture;  
  30.    
  31.     // render the texture  
  32.     securityCamera.Render();  
  33.    
  34.     // create a new Texture2D with the camera's texture, using its height and width  
  35.     Texture2D cameraImage= new Texture2D(securityCamera.targetTexture.width, securityCamera.targetTexture.height, TextureFormat.RGB24, false);  
  36.     cameraImage.ReadPixels(new Rect(0, 0, securityCamera.targetTexture.width, securityCamera.targetTexture.height), 0, 0);  
  37.     cameraImage.Apply();  
  38.     RenderTexture.active = rendText;  
  39.    
  40.     // store the texture into a .PNG file  
  41.     byte[] bytes = cameraImage.EncodeToPNG();  
  42.    
  43.     // save the encoded image to a file  
  44.     System.IO.File.WriteAllBytes(Application.persistentDataPath + "/camera_image.png", bytes);  
  45. }  
  46. }  
  47.       


 

 

一旦脚本添加到场景中,就可以按下“S”键来获取相机截图。你可以访问保存的文件。

总结

渲染纹理是一个你可以绘制的画布。通过关联渲染纹理到相机的输出,就可以把相机所见绘制到渲染纹理上。

因为渲染纹理是一个纹理,就可以把它关联到材质上。然后,添加材质到对象上并有效的把渲染纹理投影到对象的表面。

监控显示是对它工作原理是一个很好的比喻。相机就是相机,渲染纹理是视频录制,材质是你视频投影到的屏幕。

展望?

现在,你应该理解了渲染纹理的工作原理,并可灵活使用。.PNG输出也提供了很多可能。渲染纹理特性(还有其他属性)对Unity5之前的非专业版本用户不开放,越来越开放使Unity成为越来越棒的工具。

使用该技术的一些想法:

· 使用多个精灵形成一个新的图片保存为.PNG,在游戏中使用(比如:通过不同的特征组成一张脸)。

· 红外相机可以看到裸眼不可见生物。

· 若你可以找到一个方法修改相机输出(比如:让TV屏幕为黑白屏或像老电脑屏幕一样泛绿光)。

相关文章:

  • 如何实现文件上传 - JavaWeb
  • Shiro之身份认证、与spring集成(入门级)
  • ES6语法详解(一)
  • 设计模式之六大原则
  • -HTMLCSS- 之京东首页学习
  • 导读
  • SSL/TLS协议运行机制的概述
  • dva/dynamic
  • Java基础-线程操作共享数据的安全问题
  • 三、Mac平台下集成 FFmpeg 框架
  • (汇总)os模块以及shutil模块对文件的操作
  • windows2008搭建FTP限制上传文件大小
  • 「转载」用户使用分享_开源PaaS Rainbond
  • 京东架构师-----解析Hystrix线程隔离技术
  • spring整合kaptcha验证码
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • IP路由与转发
  • Java 内存分配及垃圾回收机制初探
  • log4j2输出到kafka
  • Mysql优化
  • vue-cli3搭建项目
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 配置 PM2 实现代码自动发布
  • 如何合理的规划jvm性能调优
  • 软件开发学习的5大技巧,你知道吗?
  • 使用common-codec进行md5加密
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 听说你叫Java(二)–Servlet请求
  • 用mpvue开发微信小程序
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (过滤器)Filter和(监听器)listener
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (四) Graphivz 颜色选择
  • (转)EOS中账户、钱包和密钥的关系
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • (状压dp)uva 10817 Headmaster's Headache
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .net framework 4.0中如何 输出 form 的name属性。
  • .NET处理HTTP请求
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • []我的函数库
  • [20190401]关于semtimedop函数调用.txt
  • [Assignment] C++1
  • [BZOJ 2142]礼物(扩展Lucas定理)
  • [BZOJ1877][SDOI2009]晨跑[最大流+费用流]
  • [C++进阶篇]STL中vector的使用
  • [CF482B]Interesting Array
  • [CSS]CSS 字体属性