Unity中RenderTexture详解以及它的用途

什么是RenderTexture?

RenderTexture是unity定义的一种特殊的Texture类型,它是连接着一个FrameBufferObject的存在于GPU端的Texture(Server-Side Texture),从上面对RenderTexture的解释我们了解到要先知道Texture和FrameBufferObject是什么

什么是Texture?

中文翻译叫纹理,先说一下一个纹理是如何被渲染到屏幕上的 ,起初纹理存在硬盘(RAM)里,它被cpu解压缩(数据在cpu端它就只是二进制数据),如果想要显示它,那么数据将会被发送给(上传到,cpu和gpu之间的通信可以理解成client和server之间的通信)GPU,gpu将它放在显存(VARM)中,显存中有一块内存区域叫做RenderBuffer(渲染缓存),RenderBuffer只是数据缓存,它还不能用作Texture渲染,尽管它现在已经是一个texture了,在这里 texture等待着被渲染,当要渲染这个Texture时,会生成一个FrameBuffer(帧缓存),当这个帧缓存被添加到默认的帧缓存物体上(FrameBufferObject)时,它就会被绘制到屏幕上.FrameBuffer指向的是显存中RenderBuffer的地址,简单的来说,RenderBuffer需要附加在FrameBuffer上,它才能是五颜六色的图片,否则它只是显存上的一堆数据,关于RenderBuffer和FrameBuffer可以看这些文章:

Linux OpenGL 实践篇-10-framebuffer - 北冥有鱼其名为鲲 - 博客园

OpenGL ES学习之路(3.1) 着色器渲染过程、渲染方式、FrameBuffer与RenderBuffer - 简书

简单的几句话描述的渲染过程其实非常复杂耗时,所幸有许多框架精心主导着这部分数据传输,微软有DirectX,苹果有Metal ,还有OpenGL,WebGL等.在unity中通过调用Graphic.Blit()来渲染一个Texture.


什么是FrameBufferObject?

        可以理解FrameBufferObject是一个集合,集合了FrameBuffer,通过快速刷新Framebuffer实现动态效果,最典型的FBO就是Unity的Main Camera,它是默认的FBO,是gpu里渲染结果的目的地.但是现代gpu通常可以创建很多其他的FBO(Unity中可以创建多个Camera),这些FBO不连接窗口区域,这种我们创建的FBO的存在目的就是允许我们将渲染结果保存在gpu的一块存储区域,待之后使用,这种用法叫做离屏渲染,这是一个非常有用的东西。Camera 输出的FBO,可以嵌在另一个FBO中,Unity中使用RenderTexture来接收FBO(可视化FBO),Game窗口是一个特殊的RenderTexture,它允许多个FBO叠加渲染,当Camera的RenderTarget都设置为null时表示输出到game窗口(没有摄像机的RenderTaget为null会显示没有摄像机进行渲染),设置不为null表示输出到某个RT.

如何使用FrameBufferObject?

1.将这个FBO上的结果传回CPU这边的贴图,在gles中的实现一般是ReadPixels()这样的函数,这个函数是将当前设为可读的FBO拷贝到cpu这边的一个存储buffer,没错如果当前设为可读的FBO是那个默认FBO,那这个函数就是在截屏,如果是你自己创建的FBO,那就把刚刚绘制到上面的结果从gpu存储拿回内存。

2. 将这个FBO上的结果拷贝到一个gpu上的texture,在gles中的实现一般是CopyTexImage2D(),它一般是将可读的FBO的一部分拷贝到存在于gpu上的一个texture对象中,直接考到server-sider就意味着可以马上被gpu渲染使用

3.将这个fbo直接关联一个gpu上的texture对象,这样就等于在绘制时就直接绘制到这个texure上,这样也省去了拷贝时间,gles中一般是使用FramebufferTexture2D()这样的接口。

unity是如何使用FBO的?

Unity通过上面说的第三个方法将FBO输出到RenderTexture,在unity里要使用这个FBO,只能基于这个RenderTexture(目前我知道的是这样,可能有我不知道的用法).

在Unity固定渲染管线中(Unity2019.3以后 自定义渲染管线脱离预览版,新的通用渲染管线Camera设置发生了改变,如果依然使用固定渲染管线则以下通用),通过Camera组件来使用FBO,多摄像机使用下,根据ClearFlags来决定渲染内容:

需要强调的是Clear操作, 多Camera下,DepthOnly 和Don't Clear实际上都使Clear操作失效了 ,场景中会渲染多个摄像机的渲染内容

RenderTexture的用途?

1.屏幕后处理,3d游戏最基本的后处理是抗锯齿,从Unity的FrameDebugger(可以看到所有FrameBuffer,不管它们属于哪个FBO)中可以看到抗锯齿的操作在OverlayUI之前,所以各位做2d游戏的可以选择把抗锯齿关掉,其他的后处理如bloom,HDR等都是操作屏幕这个默认的RenderTexture,配合上相关效果的Material 

2.在Scene中直接将RT作为Texture传给其他材质球,操作是调用Material.SetTexture 为该RT,即可实现在另一个表面渲染另一个Camera的内容.可以制作后视镜功能

3.copy回cpu端的内存:基本操作是在当前帧渲染完毕后(协程中, yield return new WaitForEndOfFrame()),设置RenderTexture.active为目标RenderTexture(因为当前帧已渲染过,所以该RenderTexture不会被渲染).Texture.ReadPixels保存到显存.Texture.GetRawTextureData()读回cpu内存,可以保存到硬盘或者通过互联网通信(在unity中实现的截屏,录屏,实时共享屏幕).

以上2,3都属于离屏渲染的应用.

RenderTexture的注意事项

1.rendertexture的分配和销毁,如果你频繁的要new一个rt出来,那么不要直接new,而是使用RenderTexture提供的GetTemporaryReleaseTemporary,它将在内部维护一个池,反复重用一些大小格式一样的rt资源,因为让gpu为你分配一个新的tex其实是要耗时间的。

2.在将RT拷会cpu的过程中,帧数下降较多,在unity Profiler中发现Texture.ReadPixel()耗时很多,推测该方法效率很低,使用

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        sw.Start();

//待测试的代码

sw.Stop(); sw.Elapsed能够显示函数耗时是普通函数的700倍

优化方案:方法耗时的原因大概是像素点太多了,降低输出的texture分辨率可以减少像素. Camera output到的RenderTexture,可以通过指定一个降低的分辨率的RenderTexture(注意!!!用于接收该renderTexture的textrue2d分辨率必须和它保持一致),猜测这也是性能较低的机器无法进行高分辨率音视频的原因,另一方面,Game窗口的RenderTexture虽然一直存在于GPU端,但是降低分辨率也能减轻gpu的压力,通过Screen.SetResolution实现.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容