Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Distortion shader problem

Discussion in 'Shaders' started by pertsa, Apr 22, 2014.

  1. pertsa

    pertsa

    Joined:
    Jul 3, 2013
    Posts:
    15
    Hi,

    We have a shader that makes a nice lens like distortion effect. It works fine in most mobile platforms, like Asus Nexus 7 with Tegra, but freezes the fps totally in Asus Nexus 7 with Snapdragon. Both devices run Android 4.4. Any ideas what might go wrong?

    Code (csharp):
    1.  
    2. Shader "Custom/Aberration" {
    3.     Properties {
    4.         _DistortAmt  ("Distortion", Float) = 10.0
    5.         _DamageTex ("Base (RGBA)", 2D) = "white"
    6.         _DamageMin("Damage Min", float) = 0.0
    7.         _DamageMax("Damage Max", float) = 0.0
    8.     }
    9.     Category {
    10.    
    11.         // We must be transparent, so other objects are drawn before this one.
    12.         Tags { "Queue"="Transparent+1" "RenderType"="Opaque" }
    13.        
    14.         SubShader {
    15.        
    16.             // This pass grabs the screen behind the object into a texture.
    17.             // We can access the result in the next pass as _GrabTexture
    18.             GrabPass {                         
    19.                 Name "BASE"
    20.                 Tags { "LightMode" = "Always" }
    21.             }
    22.            
    23.             // Main pass: Take the texture grabbed above and use the bumpmap to perturb it
    24.             // on to the screen
    25.             Pass {
    26.                 Name "BASE"
    27.                 Tags { "LightMode" = "Always" }
    28.                 Tags { "RenderType" = "Opaque" }
    29.                 Blend SrcAlpha OneMinusSrcAlpha
    30.                 CGPROGRAM
    31.                 #pragma vertex vert
    32.                 #pragma fragment frag
    33.                 #pragma fragmentoption ARB_precision_hint_fastest
    34.                 #include "UnityCG.cginc"
    35.                     float _DistortAmt;
    36.                     sampler2D _GrabTexture;
    37.                     sampler2D _DamageTex;
    38.                     float _DamageMin;
    39.                     float _DamageMax;
    40.                     float4 _GrabTexture_TexelSize;
    41.                    
    42.                     struct appdata_t {
    43.                         float4 vertex : POSITION;
    44.                         float2 uv : TEXCOORD0;
    45.                         float3 normal : NORMAL;
    46.                     };
    47.                    
    48.                     struct v2f {
    49.                         float4 vertex : POSITION;
    50.                         float4 pos : TEXCOORD0;
    51.                         float3 normal : TEXCOORD1;
    52.                         float2 uv : TEXCOORD2;
    53.                         float view : TEXCOORD3;
    54.                     };
    55.                     v2f vert (appdata_t v) {
    56.                         v2f o;
    57.                         #if UNITY_UV_STARTS_AT_TOP
    58.                         float scale = -1.0;
    59.                         #else
    60.                         float scale = 1.0;
    61.                         #endif
    62.                        
    63.                         o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    64.                         o.uv = v.uv;
    65.                         o.pos.xy = (float2(o.vertex.x, o.vertex.y*scale)+o.vertex.w)*0.5;
    66.                         o.pos.zw = o.vertex.zw;
    67.                         o.normal = mul((float3x3)UNITY_MATRIX_MVP, v.normal);
    68.                         o.view = dot(normalize(v.normal),normalize(WorldSpaceViewDir(v.vertex)));
    69.                         return o;
    70.                     }
    71.                     half4 frag( v2f i ) : COLOR {
    72.                         float4 c = tex2D(_DamageTex, i.uv);
    73.                         float2 offset = i.normal.xy*(1.0-i.view) * _DistortAmt * _GrabTexture_TexelSize.xy;
    74.                         float4 posOrig = i.pos;
    75.                         i.pos.xy = i.pos.z * offset + i.pos.xy;
    76.                         half4 dist = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.pos));
    77.                         return half4(dist.rgb, smoothstep(_DamageMin, _DamageMax, c.r));
    78.                     }
    79.                 ENDCG
    80.             }
    81.         }
    82.         Fallback "Custom/CheapoAberration"
    83.     }
    84. }
    85.  
    br, pertsa
     
  2. pertsa

    pertsa

    Joined:
    Jul 3, 2013
    Posts:
    15
    In addition to previous, I noticed that in Android build shader worked OK on Tegra when compiled with Unity 4.2.2. But when I build with Unity 4.3.4, it drops the framerate to near zero on Tegra device too.

    br, pertti
     
  3. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    It might not be the performance problem you're dealing with, but I see your GrabPass doesn't specify a texture name, only a pass name, so it's doing that expensive operation every time.
     
  4. pertsa

    pertsa

    Joined:
    Jul 3, 2013
    Posts:
    15
    Well spotted and that improved things a bit. Unfortunately on device performance is still not acceptable.

    I tend to believe that we must come up with a replacement shader for the "glass" on mobile. Any tips highly appreciated.

    br, pertsa
     
  5. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Don't use grabpass on mobile, period. Instead, render to a texture, and use that.
     
  6. Aldrick

    Aldrick

    Joined:
    Feb 19, 2014
    Posts:
    64
    I find grabpass doesn't work on ios,by causing the screen black.Do you have any ideas about it?
     
  7. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    888
    A small hint only. You should use all texture lookups in the first place of code if its possible.

    Code (CSharp):
    1. half4 frag( v2f i ) : COLOR {
    2.                         float4 c = tex2D(_DamageTex, i.uv);
    3.                         half4 d = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.pos));
    4. ..
    5.                     }
    That supports the optimized memory and multi shader threading on mobil and desktop gpu.
    Should be not the solution for your issue, but can raise performance drastically.