一、渲染到 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 里面的内容,怎么用?

  1. 通过 ReadPixels() 方法将 FBO 里面的内容拷回 CPU,这可以用来实现经典的截屏操作
  2. 将 FBO 里面的内容拷贝到一张 GPU 上的 Texture 中
  3. 省去拷贝流程,直接将这个 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:渲染纹理(上)之截屏功能实现相关推荐

  1. Cocos2d-x 截屏功能集成

    1.集成到Director 这里选择把截屏功能继承到Director中,让全局的导演来执行截屏功能是一个很好的主意. void Director::saveScreenshot(const std:: ...

  2. android4.3 截屏功能的尝试与失败分析

    感谢网友cjd6568358的帮助,新版的Android系统截屏功能已经实现,需要的朋友请移步项目主页:https://github.com/Android-ScreenShot/AndroidScr ...

  3. Android实现录屏和截屏功能

    Android实现录屏和截屏功能 1. MediaProjectionManager介绍 2.所需权限 3.示例代码 1. MediaProjectionManager介绍 用于获取screen ca ...

  4. android实现长截屏,Android实现全屏截图或长截屏功能

    本文实例为大家分享了Android实现全屏截图或长截屏功能的具体代码,供大家参考,具体内容如下 全屏截图: /** * 传入的activity是要截屏的activity */ public stati ...

  5. html禁止手机截屏,[置顶] Android 应用内禁止截屏功能的实现

    截图介绍 Android的调试工具DDMS提供有截屏功能,很多软件也会有截屏功能,在做支付等安全类应用的时候,为了保证用户的资产和系统安全,往往会禁止应用内截屏,禁止之后,在此应用处于前台的情况下,截 ...

  6. android自动截图实现,Android实现截屏功能

    原标题:Android实现截屏功能 该方法主要利用SDK提供的view.getDrawingCache()方法,主要步骤如下: 设置view.setDrawingCacheEnabled(true) ...

  7. 苹果xr截屏怎么截_原来苹果手机自带长截屏功能!以前一直不知道,真让人相见恨晚...

    阅读本文前,请您先点击上面的蓝色字体,再点击"关注",这样您就可以继续免费收到文章了.每天都有分享,完全是免费订阅,请放心关注. 注:本文转载自网络,如有侵权,请联系删除 你关注的 ...

  8. 在Chrome 浏览器上滚动截屏

    浏览器原生功能实现滚动截屏,截取整个页面;|;插件推荐「Nimbus Screenshot」 在Chrome 浏览器上滚动截屏,不需要插件和任何 app,利用 chrome 浏览器原生功能即可实现. ...

  9. 苹果平板如何截屏_原来苹果手机自带长截屏功能!以前一直不知道,真让人相见恨晚...

    原来苹果手机自带长截屏功能!以前一直不知道,真让人相见恨晚. 关于长截图,苹果用户总是比安卓用户更加艰难一些,因为还需要利用一些第三方软件才能够截图. 最近才发现,原来苹果手机也能够轻松实现长截图功能 ...

最新文章

  1. Db4o结合Linq、Lambda表达式的简单示例
  2. 【2012.4.22】北京植物园卧佛寺
  3. producer send源码_Kafka源码深度剖析系列(七)——Producer核心流程初探
  4. FreeRTOS 之五 动态内存管理(heap_1.c)详解
  5. 2_6 CompositeMode.cpp 组合模式
  6. leetcode 777. Swap Adjacent in LR String | 777. 在LR字符串中交换相邻字符(双指针)
  7. 如何通过parent object ID获得underlying object structure IBASE ID
  8. C#JsonConvert.DeserializeObject反序列化json字符
  9. Spring实战Day2
  10. kendo-ui学习笔记——题记
  11. 复杂结构体的存取器 [C宏——智者的利刃,愚者的恶梦]
  12. 【Flink】kafka INVALID_PRODUCER_EPO send data to Kafka old epoch newer producer same transactionalId
  13. 使用Oracle 10g的Logminer挖掘日志
  14. sap原因代码配置路径_使用Visual Studio Code编写和激活ABAP代码 (上)
  15. 电脑系统怎么修改图片格式
  16. python删除表格重复行_python 删除excel表格重复行,数据预处理操作
  17. linux之getcwd函数解析,如何在Linux 中使用getcwd()函数
  18. 仿钉钉考勤统计页面的日历组件,通过日历展示每日考勤打卡情况,支持在日历上打两种不同类型的点,大致适配各种分辨率效果图
  19. 无线网络打印机服务器安装步骤,在win7安装带网络服务器的打印机步骤.ppt
  20. 数据结构与算法(十一)Trie字典树

热门文章

  1. python程序员工资-被Python程序员高工资惊到!报告却显示Python热度降了?
  2. python基础知识-一篇文章搞定Python全部基础知识
  3. python自学行吗-有编程基础Python自学行吗?
  4. 安装完python怎么打开-python安装后怎么启用
  5. python主要用来做什么-python主要用来做什么
  6. linux离线语音识别安装运行总结
  7. asp.net listview 单元格文字颜色_Excel – 如何批量修改单元格中部分关键字的字体颜色?...
  8. asp.net 提取html div,asp.net – 将div固定在html中的某一点
  9. java只有整形才能运算符为,java入门_初识java
  10. 带网格的_雨花区井圭路社区开展消防安全网格化实战演练活动