Search Unity

What does BloomOptimized and 4x anti-aliasing product such huge RenderTexture ram cost?

Discussion in 'Image Effects' started by Aldrick, Jul 17, 2019.

  1. Aldrick

    Aldrick

    Joined:
    Feb 19, 2014
    Posts:
    64
    This is my BloomOpimized script,which is based on Unity's embedded one:
    Code (CSharp):
    1.  
    2.  
    3. using System;
    4. using UnityEngine;
    5.  
    6. namespace UnityStandardAssets.ImageEffects
    7. {
    8.     [ExecuteInEditMode]
    9.     [RequireComponent (typeof(Camera))]
    10.     [AddComponentMenu ("Image Effects/Bloom and Glow/Bloom (Optimized)")]
    11.     public class BloomOptimized : PostEffectsBase
    12.     {
    13.  
    14.         public enum Resolution
    15.         {
    16.             Low = 0,
    17.             High = 1,
    18.         }
    19.  
    20.         public enum BlurType
    21.         {
    22.             Standard = 0,
    23.             Sgx = 1,
    24.         }
    25.  
    26.         [Range(0.0f, 1.5f)]
    27.         public float threshold = 0.25f;
    28.         [Range(0.0f, 2.5f)]
    29.         public float intensity = 0.75f;
    30.  
    31.         [Range(0.25f, 5.5f)]
    32.         public float blurSize = 1.0f;
    33.  
    34.         Resolution resolution = Resolution.Low;
    35.         [Range(1, 4)]
    36.         public int blurIterations = 1;
    37.  
    38.         public BlurType blurType= BlurType.Standard;
    39.  
    40.         public Shader fastBloomShader = null;
    41.         private Material fastBloomMaterial = null;
    42.  
    43.  
    44.         public override bool CheckResources ()
    45.         {
    46.             CheckSupport (false);
    47.  
    48.             fastBloomMaterial = CheckShaderAndCreateMaterial (fastBloomShader, fastBloomMaterial);
    49.  
    50.             if (!isSupported)
    51.                 ReportAutoDisable ();
    52.             return isSupported;
    53.         }
    54.  
    55.         void OnDisable ()
    56.         {
    57.             if (fastBloomMaterial)
    58.                 DestroyImmediate (fastBloomMaterial);
    59.         }
    60.  
    61.         void OnRenderImage (RenderTexture source, RenderTexture destination)
    62.         {
    63.             if (CheckResources() == false)
    64.             {
    65.                 Graphics.Blit (source, destination);
    66.                 return;
    67.             }
    68.             source.name = "BloomOptimized";
    69.  
    70.             int divider = 4;
    71.             float widthMod = 0.5f;
    72.  
    73.             fastBloomMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod, 0.0f, threshold, intensity));
    74.             source.filterMode = FilterMode.Bilinear;
    75.  
    76.             var rtW= source.width/divider;
    77.             var rtH= source.height/divider;
    78.  
    79.             // downsample
    80.             RenderTexture rt = RenderTexture.GetTemporary (rtW /2, rtH / 2, 0, source.format);
    81.         rt.name="BloomOptimized rt";
    82.             rt.filterMode = FilterMode.Bilinear;
    83.             Graphics.Blit (source, rt, fastBloomMaterial, 1);
    84.  
    85.             //var passOffs= blurType == BlurType.Standard ? 0 : 2;
    86.             var passOffs = 0;
    87.  
    88.             for(int i = 0; i < blurIterations; i++)
    89.             {
    90.                 fastBloomMaterial.SetVector ("_Parameter", new Vector4 (blurSize * widthMod + (i*1.0f), 0.0f, threshold, intensity));
    91.  
    92.                 // vertical blur
    93.                 RenderTexture rt2 = RenderTexture.GetTemporary (rtW /2, rtH/2, 0, source.format);
    94.                 rt2.name="BloomOptimized rt2";
    95.                 rt2.filterMode = FilterMode.Bilinear;
    96.                 Graphics.Blit (rt, rt2, fastBloomMaterial, 2 + passOffs);
    97.                 RenderTexture.ReleaseTemporary (rt);
    98.                 rt = rt2;
    99.  
    100.                 // horizontal blur
    101.                 rt2 = RenderTexture.GetTemporary (rtW/2, rtH/2, 0, source.format);
    102.                 rt2.name="BloomOptimized rt22";
    103.                 rt2.filterMode = FilterMode.Bilinear;
    104.                 Graphics.Blit (rt, rt2, fastBloomMaterial, 3 + passOffs);
    105.                 RenderTexture.ReleaseTemporary (rt);
    106.                 rt = rt2;
    107.             }
    108.  
    109.             fastBloomMaterial.SetTexture ("_Bloom", rt);
    110.  
    111.             Graphics.Blit (source, destination, fastBloomMaterial, 0);
    112.  
    113.  
    114.             RenderTexture.ReleaseTemporary (rt);
    115.         }
    116.     }
    117. }
    118.  
    And this is the RenderTexture's RAM profile:
    upload_2019-7-17_19-9-32.png

    As it shows,the "source" RT named "BloomOptimized" has a very big 71.2MB size.As the resolution is 2159*1080,hereby a standard 2048 * 1024 resolution RT will occupy 64MB RAM,which means 1024 * 1024 equals 32MB.And it seems the anti-aliasing index will times the RT producing times,so 32MB / 4 equals 8MB if no anti-aliasing is used.That is still confusing,because RGBA has 4 channels so the maximum RAM it costs would be 4MB for a 1024*1024 RT.Why it is doubled?

    How to reduce this RT ram size considerably?
     
    Last edited: Jul 17, 2019
  2. aldrickbanks

    aldrickbanks

    Joined:
    Jul 18, 2019
    Posts:
    4
    I find there is a RenderTextureMemoryless.MSAA argument when using RenderTexture.GetTemporary method which seems to be relevant.Maybe it can reduce the RT's memory size,but as the biggest RT is the "source",which is retrieved directly from the Engine,not controlled by my script,then I don't know how to reduce the size of the "source" RT.

    And still,,no idea why the size is doubled.
     
  3. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    5,760
    As I understand it, it’s because it needs enough space to save all the samples (so whatever the resolution is, times the AA samples).

    Memoryless would have helped but AFAIK it only works on iOS/tvOS.
     
  4. aldrickbanks

    aldrickbanks

    Joined:
    Jul 18, 2019
    Posts:
    4
    But the profiling result shows that it doubles the memory after resolution timing the AA samples.

    My screen resolution is about 2.2K.So the memory of resolution timing AA samples should be about 36MB.But now it is 72MB.

    I don't know where does that final double come from.
     
  5. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    5,760
    What format are your rendertextures?
     
  6. aldrickbanks

    aldrickbanks

    Joined:
    Jul 18, 2019
    Posts:
    4
    RGBA32.I think It is not customizable.It is Unity's default "source" RenderTexture in OnRenderImage() method.

    You can see the detail in the codes and profile table.Hightlighted ones in green are those.
    Untitled-2.jpg
     
    Last edited: Jul 19, 2019
  7. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    5,760
    Unity's defaults went out of whack recently, so I doubt it's ARGB32. If the camera has HDR enabled, it may very well be
    ARGBHalf, which uses 16bit per channel instead of 8bit, and that would explain the size.
     
    Peter77 likes this.
  8. aldrickbanks

    aldrickbanks

    Joined:
    Jul 18, 2019
    Posts:
    4
    We don't enable hdr.And the shadow map and depth map's RT sizes are correct,as shows in the table.Only the image effects(OptmizedBloom)'s RT size is twice as big as what it should be.Really strange.
     
  9. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    5,760
    Do
    Debug.Log("Source rt format is : " + source.format);
    Debug.Log("Destination rt format is : " + destination.format);

    inside OnRenderImage
     
    brownboot67 likes this.