Unity中RenderTexture詳解以及它的用途

什么是RenderTexture?

RenderTexture是unity定義的一種特殊的Texture類型,它是連接著一個FrameBufferObject的存在于GPU端的Texture(Server-Side Texture),從上面對RenderTexture的解釋我們了解到要先知道Texture和FrameBufferObject是什么

什么是Texture?

中文翻譯叫紋理,先說一下一個紋理是如何被渲染到屏幕上的 ,起初紋理存在硬盤(RAM)里,它被cpu解壓縮(數據在cpu端它就只是二進制數據),如果想要顯示它,那么數據將會被發(fā)送給(上傳到,cpu和gpu之間的通信可以理解成client和server之間的通信)GPU,gpu將它放在顯存(VARM)中,顯存中有一塊內存區(qū)域叫做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實現動態(tài)效果,最典型的FBO就是Unity的Main Camera,它是默認的FBO,是gpu里渲染結果的目的地.但是現代gpu通初蹇眨可以創(chuàng)建很多其他的FBO(Unity中可以創(chuàng)建多個Camera)引几,這些FBO不連接窗口區(qū)域高氮,這種我們創(chuàng)建的FBO的存在目的就是允許我們將渲染結果保存在gpu的一塊存儲區(qū)域,待之后使用,這種用法叫做離屏渲染,這是一個非常有用的東西宜岛。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毫别,那這個函數就是在截屏娃弓,如果是你自己創(chuàng)建的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設置發(fā)生了改變,如果依然使用固定渲染管線則以下通用),通過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端的內存:基本操作是在當前幀渲染完畢后(協(xié)程中, 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中發(fā)現Texture.ReadPixel()耗時很多,推測該方法效率很低,使用

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

? ? ? ? sw.Start();

//待測試的代碼

sw.Stop(); sw.Elapsed能夠顯示函數耗時是普通函數的700倍

優(yōu)化方案:方法耗時的原因大概是像素點太多了,降低輸出的texture分辨率可以減少像素.?Camera output到的RenderTexture,可以通過指定一個降低的分辨率的RenderTexture(注意!!!用于接收該renderTexture的textrue2d分辨率必須和它保持一致),猜測這也是性能較低的機器無法進行高分辨率音視頻的原因,另一方面,Game窗口的RenderTexture雖然一直存在于GPU端,但是降低分辨率也能減輕gpu的壓力,通過Screen.SetResolution實現.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末鲤拿,一起剝皮案震驚了整個濱河市假褪,隨后出現的幾起案子,更是在濱河造成了極大的恐慌近顷,老刑警劉巖生音,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宁否,死亡現場離奇詭異,居然都是意外死亡缀遍,警方通過查閱死者的電腦和手機慕匠,發(fā)現死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來域醇,“玉大人台谊,你說我怎么就攤上這事∑┲浚” “怎么了锅铅?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長减宣。 經常有香客問我狠角,道長,這世上最難降的妖魔是什么蚪腋? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任丰歌,我火速辦了婚禮,結果婚禮上屉凯,老公的妹妹穿的比我還像新娘立帖。我一直安慰自己,他們只是感情好悠砚,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布晓勇。 她就那樣靜靜地躺著,像睡著了一般灌旧。 火紅的嫁衣襯著肌膚如雪绑咱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天枢泰,我揣著相機與錄音描融,去河邊找鬼。 笑死衡蚂,一個胖子當著我的面吹牛窿克,可吹牛的內容都是我干的。 我是一名探鬼主播毛甲,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼年叮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了玻募?” 一聲冷哼從身側響起只损,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎七咧,沒想到半個月后跃惫,有當地人在樹林里發(fā)現了一具尸體啸蜜,經...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年辈挂,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片裹粤。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡终蒂,死狀恐怖,靈堂內的尸體忽然破棺而出遥诉,到底是詐尸還是另有隱情拇泣,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布矮锈,位于F島的核電站霉翔,受9級特大地震影響,放射性物質發(fā)生泄漏苞笨。R本人自食惡果不足惜债朵,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瀑凝。 院中可真熱鬧序芦,春花似錦、人聲如沸粤咪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寥枝。三九已至宪塔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間囊拜,已是汗流浹背某筐。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留冠跷,地道東北人来吩。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像蔽莱,于是被迫代替她去往敵國和親弟疆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內容