UnityShader19:渲染纹理(上)之截屏功能实现
一、渲染到 RT
渲染纹理(Render Texture) 就是游戏开发中经常被提到的 RT,渲染到 RT 本质上就是不将渲染的结果直接显示的屏幕上,而是存至一张指定的纹理中
在 Unity 中最简单的操作(三步实现渲染到 RT,无需写代码):
这样这台摄像机的渲染结果就会存入你设置的 RT 中,而不再显示在屏幕上
这个设置转成代码就是:
_renderTexture = new RenderTexture(width, height, 8);
_camera.targetTexture = _renderTexture;
二、FBO 与渲染到 RT 的原理
1):纹理从 CPU 到 GPU:
所有的贴图资源最开始都是存在 CPU 的内存中的,在渲染的过程中它会被送到 GPU 的内存里,在这之后 GPU 才能使用它进行渲染
2):再提 FBO
帧缓冲(FrameBufferObject, FBO)的详细介绍可以参考下面三章:
- 主要是这一章:OpenGL基础33:帧缓冲(上)之离屏渲染
- OpenGL基础34:帧缓冲(中)之附件
- OpenGL基础35:帧缓冲(下)之简单图像处理
关于 FBO 本质上就是 GPU 渲染结果的目的地,我们绘制的所有结果:包括颜色、深度等信息都最终存在这个这里
现在的 GPU 当然可以创建多个 FBO,其中有个默认的 FBO 直接连着我们的显示器窗口区域,而其它的 FBO 存在的目的就是允许我们将渲染结果保存在 GPU 的一块存储区域以待之后使用
3):FBO 里面的内容,怎么用?
- 通过 ReadPixels() 方法将 FBO 里面的内容拷回 CPU,这可以用来实现经典的截屏操作
- 将 FBO 里面的内容拷贝到一张 GPU 上的 Texture 中
- 省去拷贝流程,直接将这个 FBO 关联到对应的 Texture,这样就等于在绘制时就直接绘制到这个 Texture 上,这即是 Unity RT 的实现原理
一个很经典的函数是 Graphics.Blit(src, target, mat, pass):其内部使用 mat 材质用 src 做 mainTex,clear 为 black 后渲染到 target 上,mat 留空可以理解为直接拷贝纹理,一般都是使用这种方法渲染到 RT,在做一些屏幕后处理时这个方法几乎是必用到的
三、实现截屏功能
按下 S 键就可以将当前的游戏画面保存到 D 盘的根目录下:
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class ScreenShot : MonoBehaviour
{private void Update(){if (Input.GetKeyDown(KeyCode.S)){Debug.Log("Save");Save();}}private RenderTexture TargetTexture;private void OnRenderImage(RenderTexture source, RenderTexture destination){TargetTexture = source;Graphics.Blit(source, destination);}private void Save(){RenderTexture.active = TargetTexture;int width = RenderTexture.active.width;int height = RenderTexture.active.height;//↑ 把当前的fbo设为可读的对象 ↓ 调用ReadPixels操作将其读回内存Texture2D png = new Texture2D(width, height, TextureFormat.ARGB32, true);png.ReadPixels(new Rect(0, 0, width, height), 0, 0);byte[] bytes = png.EncodeToPNG();string file = string.Format(@"D:\TestPic.png");System.IO.File.WriteAllBytes(file, bytes);Debug.Log("Save Down");}
}
关于 Unity 内置的 OnRenderImage() 函数:
该脚本必须挂载在有相机组件的游戏对象上,该函数在所有的渲染完成后由 monobehavior 自动调用,其允许我们使用着色器滤波操作来修改最终的图像,第一个参数 source 为输入原图像,第二个参数 desitination 为输出的图象
还需要注意的点:
若要将 RenderTexture 拷贝回 CPU 内存,那么拷贝前后的 Tex 的格式必须匹配,且必须是 RGBA32 这种基本类型,要注意的是很多机器支持 ARRBHALF 或者 ARGBFLOAT 这样的浮点格式来存储其它非颜色信息(例如 uv 坐标),这种不能直接拿来当 256 位颜色信息使用
参考文章:
- https://blog.csdn.net/leonwei/article/details/54972653
- https://www.jianshu.com/p/334770f39127
- https://blog.csdn.net/qq_36383623/article/details/86303938
UnityShader19:渲染纹理(上)之截屏功能实现相关推荐
- Cocos2d-x 截屏功能集成
1.集成到Director 这里选择把截屏功能继承到Director中,让全局的导演来执行截屏功能是一个很好的主意. void Director::saveScreenshot(const std:: ...
- android4.3 截屏功能的尝试与失败分析
感谢网友cjd6568358的帮助,新版的Android系统截屏功能已经实现,需要的朋友请移步项目主页:https://github.com/Android-ScreenShot/AndroidScr ...
- Android实现录屏和截屏功能
Android实现录屏和截屏功能 1. MediaProjectionManager介绍 2.所需权限 3.示例代码 1. MediaProjectionManager介绍 用于获取screen ca ...
- android实现长截屏,Android实现全屏截图或长截屏功能
本文实例为大家分享了Android实现全屏截图或长截屏功能的具体代码,供大家参考,具体内容如下 全屏截图: /** * 传入的activity是要截屏的activity */ public stati ...
- html禁止手机截屏,[置顶] Android 应用内禁止截屏功能的实现
截图介绍 Android的调试工具DDMS提供有截屏功能,很多软件也会有截屏功能,在做支付等安全类应用的时候,为了保证用户的资产和系统安全,往往会禁止应用内截屏,禁止之后,在此应用处于前台的情况下,截 ...
- android自动截图实现,Android实现截屏功能
原标题:Android实现截屏功能 该方法主要利用SDK提供的view.getDrawingCache()方法,主要步骤如下: 设置view.setDrawingCacheEnabled(true) ...
- 苹果xr截屏怎么截_原来苹果手机自带长截屏功能!以前一直不知道,真让人相见恨晚...
阅读本文前,请您先点击上面的蓝色字体,再点击"关注",这样您就可以继续免费收到文章了.每天都有分享,完全是免费订阅,请放心关注. 注:本文转载自网络,如有侵权,请联系删除 你关注的 ...
- 在Chrome 浏览器上滚动截屏
浏览器原生功能实现滚动截屏,截取整个页面;|;插件推荐「Nimbus Screenshot」 在Chrome 浏览器上滚动截屏,不需要插件和任何 app,利用 chrome 浏览器原生功能即可实现. ...
- 苹果平板如何截屏_原来苹果手机自带长截屏功能!以前一直不知道,真让人相见恨晚...
原来苹果手机自带长截屏功能!以前一直不知道,真让人相见恨晚. 关于长截图,苹果用户总是比安卓用户更加艰难一些,因为还需要利用一些第三方软件才能够截图. 最近才发现,原来苹果手机也能够轻松实现长截图功能 ...
最新文章
- Db4o结合Linq、Lambda表达式的简单示例
- 【2012.4.22】北京植物园卧佛寺
- producer send源码_Kafka源码深度剖析系列(七)——Producer核心流程初探
- FreeRTOS 之五 动态内存管理(heap_1.c)详解
- 2_6 CompositeMode.cpp 组合模式
- leetcode 777. Swap Adjacent in LR String | 777. 在LR字符串中交换相邻字符(双指针)
- 如何通过parent object ID获得underlying object structure IBASE ID
- C#JsonConvert.DeserializeObject反序列化json字符
- Spring实战Day2
- kendo-ui学习笔记——题记
- 复杂结构体的存取器 [C宏——智者的利刃,愚者的恶梦]
- 【Flink】kafka INVALID_PRODUCER_EPO send data to Kafka old epoch newer producer same transactionalId
- 使用Oracle 10g的Logminer挖掘日志
- sap原因代码配置路径_使用Visual Studio Code编写和激活ABAP代码 (上)
- 电脑系统怎么修改图片格式
- python删除表格重复行_python 删除excel表格重复行,数据预处理操作
- linux之getcwd函数解析,如何在Linux 中使用getcwd()函数
- 仿钉钉考勤统计页面的日历组件,通过日历展示每日考勤打卡情况,支持在日历上打两种不同类型的点,大致适配各种分辨率效果图
- 无线网络打印机服务器安装步骤,在win7安装带网络服务器的打印机步骤.ppt
- 数据结构与算法(十一)Trie字典树
热门文章
- python程序员工资-被Python程序员高工资惊到!报告却显示Python热度降了?
- python基础知识-一篇文章搞定Python全部基础知识
- python自学行吗-有编程基础Python自学行吗?
- 安装完python怎么打开-python安装后怎么启用
- python主要用来做什么-python主要用来做什么
- linux离线语音识别安装运行总结
- asp.net listview 单元格文字颜色_Excel – 如何批量修改单元格中部分关键字的字体颜色?...
- asp.net 提取html div,asp.net – 将div固定在html中的某一点
- java只有整形才能运算符为,java入门_初识java
- 带网格的_雨花区井圭路社区开展消防安全网格化实战演练活动