Search Unity

ImageEffectOpaque renders too late in builds (ok in editor)

Discussion in 'Image Effects' started by RobbyZ, Feb 6, 2020.

  1. RobbyZ

    RobbyZ

    Joined:
    Apr 17, 2015
    Posts:
    38
    Hello,

    I have a project using the old post process v1 stack and the legacy standard assets edge detection shader. It generally works fine, except we have one problem with the edge detection script rendering on top of fog. (Unity version 2018.4.2f1)

    It appears that after the game is built, the edge detection script is running too late in the process. Its OnRenderImage function is tagged with [ImageEffectOpaque], and runs appropriately in editor -- but in a build it runs too late.

    UnityImageEffectRenderOrder.jpg

    As we are nearing ship, we would like to make a minimal set of changes in order to resolve the problem. Anyone have any tips?

    PS - here is the edge detection script for ease of reference:

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4. namespace UnityStandardAssets.ImageEffects
    5. {
    6.     [ExecuteInEditMode]
    7.     [RequireComponent (typeof (Camera))]
    8.     [AddComponentMenu ("Image Effects/Edge Detection/Edge Detection")]
    9.     public class EdgeDetection : PostEffectsBase
    10.     {
    11.         public enum EdgeDetectMode
    12.         {
    13.             TriangleDepthNormals = 0,
    14.             RobertsCrossDepthNormals = 1,
    15.             SobelDepth = 2,
    16.             SobelDepthThin = 3,
    17.             TriangleLuminance = 4,
    18.         }
    19.  
    20.  
    21.         public EdgeDetectMode mode = EdgeDetectMode.SobelDepthThin;
    22.         public float sensitivityDepth = 1.0f;
    23.         public float sensitivityNormals = 1.0f;
    24.         public float lumThreshold = 0.2f;
    25.         public float edgeExp = 1.0f;
    26.         public float sampleDist = 1.0f;
    27.         public float edgesOnly = 0.0f;
    28.         public Color edgesOnlyBgColor = Color.white;
    29.  
    30.         public Shader edgeDetectShader;
    31.         private Material edgeDetectMaterial = null;
    32.         private EdgeDetectMode oldMode = EdgeDetectMode.SobelDepthThin;
    33.  
    34.  
    35.         public override bool CheckResources ()
    36.         {
    37.             CheckSupport (true);
    38.  
    39.             edgeDetectMaterial = CheckShaderAndCreateMaterial (edgeDetectShader,edgeDetectMaterial);
    40.             if (mode != oldMode)
    41.                 SetCameraFlag ();
    42.  
    43.             oldMode = mode;
    44.  
    45.             if (!isSupported)
    46.                 ReportAutoDisable ();
    47.             return isSupported;
    48.         }
    49.  
    50.  
    51.         new void Start ()
    52.         {
    53.             oldMode    = mode;
    54.         }
    55.  
    56.         void SetCameraFlag ()
    57.         {
    58.             if (mode == EdgeDetectMode.SobelDepth || mode == EdgeDetectMode.SobelDepthThin)
    59.                 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
    60.             else if (mode == EdgeDetectMode.TriangleDepthNormals || mode == EdgeDetectMode.RobertsCrossDepthNormals)
    61.                 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
    62.         }
    63.  
    64.         void OnEnable ()
    65.         {
    66.             SetCameraFlag();
    67.         }
    68.  
    69.         [ImageEffectOpaque]
    70.         void OnRenderImage (RenderTexture source, RenderTexture destination)
    71.         {
    72.             if (CheckResources () == false)
    73.             {
    74.                 Graphics.Blit (source, destination);
    75.                 return;
    76.             }
    77.  
    78.             Vector2 sensitivity = new Vector2 (sensitivityDepth, sensitivityNormals);
    79.             edgeDetectMaterial.SetVector ("_Sensitivity", new Vector4 (sensitivity.x, sensitivity.y, 1.0f, sensitivity.y));
    80.             edgeDetectMaterial.SetFloat ("_BgFade", edgesOnly);
    81.             edgeDetectMaterial.SetFloat ("_SampleDistance", sampleDist);
    82.             edgeDetectMaterial.SetVector ("_BgColor", edgesOnlyBgColor);
    83.             edgeDetectMaterial.SetFloat ("_Exponent", edgeExp);
    84.             edgeDetectMaterial.SetFloat ("_Threshold", lumThreshold);
    85.  
    86.             Graphics.Blit (source, destination, edgeDetectMaterial, (int) mode);
    87.         }
    88.     }
    89. }
    90.  
     
  2. craigtww

    craigtww

    Joined:
    Jun 23, 2020
    Posts:
    2
    I know it has been over a year but I ran into the same issue with Unity 2018.4.36f and found a solution.

    Builds with high managed stripping level have this issue but builds with a low managed stripping level would not have this issue.
    https://docs.unity3d.com/2018.4/Documentation/Manual/ManagedCodeStripping.html

    It seems the ImageEffectOpaque attribute is being stripped.

    The best solution would be to make sure the attribute is not stripped using a link.xml file. I am still figuring out how to do this.
     
  3. craigtww

    craigtww

    Joined:
    Jun 23, 2020
    Posts:
    2
    this linker file worked for me:


    <linker>
    <assembly fullname="UnityEngine.CoreModule">
    <type fullname="UnityEngine.ImageEffectOpaque" preserve="all"/>
    </assembly>
    </linker>