使用RenderTexture為物體生成快照

2021-08-21 22:19:34 字數 3167 閱讀 9177

rendertexture的定義和作用

rendertexture are textures that can be rendered to.

rendertexture(下文簡稱rtt)是可以被渲染的紋理,簡稱渲染紋理。一般來說,rtt可以應用在製作動態陰影,反射以及監視攝像機(車輛後視鏡)等,另一方面可以應用到遊戲截圖,背景模糊等方面,用途十分廣泛。以後這些技術都會慢慢分享到部落格上,敬請期待!

rtt的用法

camera(攝像機)是unity中非常重要的乙個元件,其中有乙個屬性叫做targettexture,在設定了targettexture後,camera會在渲染時將其螢幕上的影象渲染到targettexture上。在相機渲染完成後可以讀取螢幕畫素內的快取來使用。其中,相機渲染完成有三種呼叫方式:

1.onpostrender()

onpostrender is called after a camera finished rendering the scene.

onpostrender在相機完成渲染場景時呼叫。這次遇到的需求是需要為物體生成快照,做法是另外建立乙個相機,在另乙個位置完成渲染工作,**如下:

//快照相機

public camera shotcam;

public uitexture texture;

void onpostrender()

//這裡刪除的時機有問題,會導致不顯示相機渲染的影象問題

//謝謝一位好心讀者提醒,改正後的**在下方

修正後的**:

public camera shotcam;

public uitexture texture;

private texture2d tex = null;

void onpostrender()

//設定當前rendertexture為快照相機的targettexture

rendertexture rt = shotcam.targettexture;

rendertexture.active = rt;

tex = new texture2d(rt.width, rt.height);

//讀取緩衝區畫素資訊

tex.readpixels(new rect(0, 0, rt.width, rt.height), 0, 0);

texture.maintexture = tex;

}

場景中的效果如下:

2.使用協程(yield return new waitforendofframe())

yield return new waitforendofframe()

等待當前幀結束。類似於onpostrender(),可以使用for迴圈來依次對多個物體進行快照,**如下:

public gameobject gos;

void start()

ienumerator rendergotexcr()

}

ps:yield語句要放在設定rendertexture.active之前,因為只有在幀結束時shotcam的targettexture才被正確渲染,才可以通過readpixels取得正確的影象。tex在使用過後最好使用destroy()銷毀,或者在設定maintexture之前銷毀之前的texture,否則就會像博主一樣寫著寫著部落格發現unity執行了一段時間就把記憶體吃光了場景效果如下:

3.使用camera.render()

我們發現當要對多個物體進行快照時onpostrender()就沒那麼好用了,因為我們需要在相機渲染前將物體展示出來(onprerender()),在相機渲染後取得畫素資訊,對於兩個函式分別處理gameobject我們是拒絕的(程式設計師就喜歡簡單粗暴!)。那麼使用協程又有什麼問題呢?細心的同學會發現,每次渲染乙個物體都需要等到幀結束,那麼當需要渲染的物體較多時渲染時間會明顯變長,這顯然也不是我們想要的,那麼有沒有能在很短時間內完成大量物體的渲染呢?camera.render()給了我們福音。

camera.render()

手動渲染相機。廢話不多說,貼**:

public gameobject gos;

void start()

}texture2d rendergotex()

camera.render()無需等待幀結束,它在呼叫時強制渲染相機,通過返回的tex進行操作即可,同樣不要忘了texture的記憶體問題,場景中效果如下:

咦,怎麼會發生重疊現象呢,明明在取得tex之後呼叫了destroy()函式呀!這個也困擾了我一段時間,後來發現是destroy函式的延遲問題。destroy()函式對實際物體的銷毀會延遲到當前迴圈更新後,在渲染前完成的,所以我們在這一幀執行for迴圈時,雖然每次迴圈都呼叫了destroy()來銷毀物體,但是實際上它們是在for迴圈結束後才一起銷毀的,所以為了避免此問題,我們改用destroyimmediate(),或者先呼叫gameobject.setactive(false)後再destroy(),後者是比較推薦的做法,原因請看官方文件

結尾語

博主只是初入江湖的小菜,最近萌生寫部落格的想法,希望能將自己在學習和工作中遇到的問題以及所感所想與大家分享,同時也是對自我的總結。最後感謝大家的支援,你們的支援就是我的動力!

原文:

每日隨筆 RenderTexture

還是不怎麼懂,之後再編輯。2個攝像機,主攝像機只渲染ui層,次攝像機渲染設定的層。所以各自的攝像機做了各自的事,如果需要將次攝像機表現在主攝像機上 1,次攝像機使用任意乙個rendertexture,在這裡次攝像機使用solidecolor。2,主攝像機下ui層加乙個rawimage,然後放置同乙個...

Unity 利用Render Texture 快照

一.首先我們得拿到渲染紋理 我們在project面板creat乙個rendertexture,然後把這個渲染紋理給相機的rendertexture,如下圖所示 然後如下面 往面料滑動列表刷資料 private void upadteclothdata item.transform.setparent...

使用GraphEdit使用

1 註冊元件。其實乙個filter就是乙個com元件,所以使用之前需要註冊,可以有兩種方法對元件進行註冊。1.直接使用命令。命令列下輸入 regsvr32 hqtlystd.ax 編譯之後你會在工程目錄下的debug中找到hqtlystd.ax,這個就是要用的filter 即可註冊成功。2.vc6....