渋谷ほととぎす通信

エンジニア社長によるUnityとAIのブログ & エンジニアの生存戦略

【Unity】RenderTextureのメモリ管理(知らないとヤバい)

【Unity】RenderTextureのメモリ管理(知らないとヤバい)

こんにちは、Unityエンジニアのオオバです。

お悩みさん
お悩みさん
  • RenderTextureってメモリを食うの?
  • RenderTextureのメモリ解放っていつ?
  • オオバ
    オオバ
    本記事ではこれらの悩みを解決します。

    RenderTexture(レンダーテクスチャ)を使ってますか?

    RenderTextureを使いこなすとUnity表現の幅が広がるため覚えておきたい機能のひとつです。

    しかしRenderTextureってどのタイミングでメモリ解放されるんだろう?って思ったことはありませんか。

    RenderTextureは特性上メモリを多く使用してしまいがちです。パフォーマンスが重要なゲーム開発においてRenderTextureのメモリ解放タイミングは正しく理解しておく必要があります。

    そこで本記事ではRenderTextureのメモリ解放について解説していきますので、本格的にRenderTextureを学びたい方はぜひ最後まで読んでみてください。

    👉DOTweenの教科書を読んでUnityアニメーションをプログラミングしてみよう!

    RenderTextureとは?

    そもそもRenderTextureとは何でしょうか?

    RenderTextureの特徴を簡単にまとめてみます。

    • カメラ映像をテクスチャ化できる
    • ランタイムで動的にリアルタイム更新が可能
    • GPUリソース(VRAM)を使用する

    以上の特徴があり、リアルタイムに更新できるGPUを使ったテクスチャです。UIなどで使用するTexture2Dと間違えやすいです。

    Texture2DはCPUを利用する一方、RenderTextureはGPUを利用します。Textureと名前がついているため、同じようなものだと勘違いしやすいですが全く別物であることに注意してください。

    RenderTextureの用途

    RenderTextureの用途ですが、結論様々な場所で使われています。ゲームで使われる表現に絞ると、

    • 鏡のような表現
    • ダイアログUIの背景にブラーをかける
    • カメラ映像のカラー調整

    などなど。カメラの映像に対し何か処理を加えたい時などにRenderTextureを使います。

    RenderTextureはメモリを消費しがち

    RenderTextureは端末の全画面サイズで使用しがちです。最近のスマホやスマホやモニタは解像度が高く、フルサイズの解像度でRenderTextureを作成すると使用するメモリも高くなってしまいます。

    よく使われる手法は解像度の最大値を決めることです。RenderTextureの最大サイズを決めておくことで使用メモリの計画を立てやすくなります。

    とはいえRenderTextureがメモリを使用しがちなので、正しくメモリの確保と解放のタイミングを理解しておきましょう。

    RenderTextureがメモリを確保するタイミング

    RenderTextureがメモリを確保するタイミングについて解説します。

    結論から言うと 「RenderTextureを生成したタイミング」 です。

    具体的には以下のソースコードを実行したタイミングでメモリが確保されます。

    var rt = new RenderTexture(2048, 2048, 0);  
    rt.name = "MyRT_0";  
    rt.Create();  
    

    MemoryProfilerを使って確認

    本当にメモリが確保されているのかUnity製のMemory Profilerを使って確認していきましょう。

    UnityメニューPackage Manager
    メニュー Window -> Package ManagerからPackage Managerウィンドウを開きます。

    【Unity】RenderTextureのメモリ管理(知らないとヤバい)_0

    Memory Profiler をインストールしておきます。

    Unityエディタで計測しても良いのですが、より正しい値、挙動を確認するため手元のiPhone16Proで計測します。

    ここからはビルドした実機を使って進めていきます。

    【Unity】RenderTextureのメモリ管理(知らないとヤバい)_1
    ↑上図のような検証用ボタンとRenderTextureを画面に映し出す検証アプリを作りました。

    ※イラストはAI(StableDiffusion)で作成

    実機とパソコンをUSBケーブルで繋いでアプリを起動しておきます。

    【Unity】RenderTextureのメモリ管理(知らないとヤバい)_2
    Memory Profilerウィンドウの左上プルダウンから実機を選択すると、実機をプロファイルできるようになります。

    ではRenderTextureを生成したタイミングをプロファイルしてみます。

    【Unity】RenderTextureのメモリ管理(知らないとヤバい)_3

    すると自分で作成したRenderTexture(MyRT_0)が16.0MBメモリを確保していることが分かります。

    ところが実装方法によってはRenderTextureの生成タイミングでメモリを確保しないケースもあるためこの後解説します。

    RenderTexture生成時にメモリを確保しないケース

    実はソースコードの書き方によってRenderTextureを生成してもメモリが確保されない場合があります。

    それは Create メソッドです。RenderTexture生成時にCreateメソッドを呼ばないとそのタイミングではメモリが確保されません。

    var rt = new RenderTexture(2048, 2048, 0);  
    

    上記のソースコードを実行したタイミングではメモリは確保されません。

    お悩みさん
    お悩みさん
    いつメモリが確保されるの?

    RenderTextureにピクセルを書き込んだタイミングでメモリが確保されます。

    具体的には以下のタイミングです。

    Graphics.Blit(texture, rt);  
    

    上記はBlit関数でRenderTexture(rt)にTexture2Dを書き込んでいます。

    RenderTextureをnewで作成したけどメモリが増えないなぁ。。。って気になっている方は、Createの仕様を思い出してみてください。

    RenderTextureのメモリ解放タイミング

    次にRenderTextureのメモリ解放タイミングについて解説します。RenderTextureのメモリ解放方法は2つあります。

    • Releaseメソッド
    • Destroyメソッド

    具体的なソースコードで表すと以下です。

    // Releaseメソッドでメモリ解放  
    _rt.Release();  
    
    // Destroyメソッドでメモリ解放  
    Destroy(_rt);  
    
    お悩みさん
    お悩みさん
    どちらを使った方が良いの?

    どちらのメソッドを実行してもメモリは解放されますが、両者には大きな違いがあります。

    それは 「使い回せるか否か」 です。

    Releaseメソッドを実行した後、Graphics.Blitで再びピクセルに書き込むことができますが、Destroyメソッドの場合はできません。

    ReleaseメソッドはあくまでVRAM側のメモリを解放するだけでRenderTexture自体は残っています。一方DestroyはRenderTexture自体を削除しているのです。

    RenderTextureを使いまわす場合はReleaseを、使い終わって二度と使わない場合はDestroyという使い分けでOKです。

    RenderTextureのメモリ解放まとめ

    本記事では、RenderTextureのメモリ管理 について解説しました。RenderTextureは GPUを使用して動的に描画できるテクスチャで、鏡のような反射表現や背景のブラー処理などに活用されます。しかし、メモリ消費が激しく、適切な管理が必要です。

    RenderTextureは生成時(Createメソッド実行時)にメモリを確保しますが、Createを呼ばない場合はピクセル描画(Graphics.Blit実行時)に確保される点に注意です。

    RenderTextureのメモリ解放には2つの方法がありました。

    1. Releaseメソッド(VRAMの解放のみ、再利用可能)
    2. Destroyメソッド(RenderTexture自体を削除、再利用不可)

    頻繁に使うRenderTextureはReleaseで解放しつつ使い回す。不要になったらDestroyで完全削除という使い分けをしましょう。

    また高解像度RenderTextureの無駄な生成を避けた方がよいです。RenderTextureのメモリ管理を適切に行うことで、パフォーマンスの最適化 や不要なメモリ使用の削減 につながります。

    特にモバイル向けの開発では、無駄なメモリ消費を抑えるためにも、RenderTextureの作成・解放タイミングを意識することが重要です。

    オススメ記事
    検証環境
    • Unity6000.0.32f1
    • iPhone16Pro