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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

[Help] Fade/Distortion Image effect

Discussion in 'Shaders' started by WhiteSkullDev, Mar 14, 2015.

  1. WhiteSkullDev

    WhiteSkullDev

    Joined:
    Mar 14, 2015
    Posts:
    8
    Okay, I have tried everything I can think of but I just can't get this effect to work.

    Basically what I intend to do is recreate this effect on my camera:
    http://glslsandbox.com/e#23666.2

    I've been using the built in motion blur Image effect as it makes use of the previous screen that was rendered, and so far I've been partially successful.
    My problem is getting the previous rendered screen to slowly move to the side overtime while it fades to black.
    It won't budge no matter what I do.

    Here's both my .cs and .shader files:

    AfterImage.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [ExecuteInEditMode]
    5. public class AfterImage : MonoBehaviour
    6. {
    7.     public Shader shader;
    8.     private Material material
    9.     {
    10.         get
    11.         {
    12.             if (m_material == null)
    13.                 m_material = new Material(shader);
    14.             return m_material;
    15.         }
    16.     }
    17.     private Material m_material = null;
    18.     private RenderTexture rTexture = null;
    19.     public float alpha = 0.1f;
    20.  
    21.     void OnRenderImage(RenderTexture source, RenderTexture dest)
    22.     {
    23.         if (rTexture == null || rTexture.width != rTexture.width || rTexture.height != rTexture.height)
    24.         {
    25.             DestroyImmediate(rTexture);
    26.             rTexture = new RenderTexture(source.width, source.height, 0);
    27.             rTexture.hideFlags = HideFlags.HideAndDontSave;
    28.             Graphics.Blit(source, rTexture);
    29.         }
    30.  
    31.         material.SetFloat("_alpha", alpha);
    32.         Graphics.Blit(source, rTexture, material);
    33.         Graphics.Blit(rTexture, dest);
    34.     }
    35. }
    36.  
    AfterImage.shader
    Code (CSharp):
    1. Shader "Custom/AfterImage"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Main Texture", 2D) = "white" {}  
    6.         _alpha ("Alpha", float) = 0.0
    7.     }
    8.     SubShader
    9.     {
    10.         Pass
    11.         {
    12.             Blend SrcAlpha OneMinusSrcAlpha              
    13.             CGPROGRAM
    14.            
    15.             #pragma vertex vert_img
    16.             #pragma fragment frag
    17.             #include "UnityCG.cginc"
    18.             #pragma target 3.0
    19.  
    20.             sampler2D _MainTex;
    21.             uniform float _alpha;
    22.  
    23.             float4 frag(v2f_img inpu): COLOR
    24.             {              
    25.                 float2 uv = inpu.uv * 1.01;
    26.                 float4 newcol = tex2D(_MainTex, uv);
    27.                 newcol.a = _alpha;
    28.                 return newcol;
    29.             }
    30.             ENDCG
    31.         }
    32.  
    33.  
    34.     }
    35.     FallBack "Diffuse"
    36. }
    37.  
    Any help would be greatly appreciated :^)
     
  2. WhiteSkullDev

    WhiteSkullDev

    Joined:
    Mar 14, 2015
    Posts:
    8
    polite bump
    still haven't found a way around this :c
     
  3. kebrus

    kebrus

    Joined:
    Oct 10, 2011
    Posts:
    415
    I didn't test, i'm gonna just throw ideas to (hopefully) help you out.

    When you are sampling the image using tex2D you can scroll the uv in any direction, for example:
    Code (csharp):
    1. float2 uv = inpu.uv  + float2(0.1, 0.1);
    This is blend the new image in a new position, change the 0.1 values yourself to see how it changes. This comes with a problem though, the effect will work but not exactly as you expect, because what you really want to do is to move and darken then previous image and your current shader is only doing something in the new frame.

    The way to correctly do this is to save the result in a rendertexture and reuse it as is in the new frame as texture input, that way you could sample the previous frame and do whatever you want with it inside the shader.

    [edit] looking more carefully into your csharp script you are already saving the previous frame in a render texture so now you only need to pass it to the shader as if it were a regular texture.
     
  4. WhiteSkullDev

    WhiteSkullDev

    Joined:
    Mar 14, 2015
    Posts:
    8
    Hello again,

    so after a lot of thought I was able to come up with something pretty close to what I intended.

    I'll leave the code below, it might help somebody down the road:

    AfterImage.shader
    Code (CSharp):
    1. Shader "Custom/AfterImage"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Albedo (RGB)", 2D) = "white" {}
    6.         _BackBuffer ("Albedo (RGB)", 2D) = "black" {}    
    7.         _Distance ("_Distance", float) = 0.02
    8.         _Alpha ("_Alpha", float) = 0.8
    9.         _Color ("_Color", Color) = (0.0,0.0,0.0,0.0)
    10.     }
    11.     SubShader
    12.     {        
    13.         Pass
    14.         {
    15.             Blend SrcAlpha OneMinusSrcAlpha
    16.             CGPROGRAM
    17.             #pragma vertex vert_img
    18.             #pragma fragment frag
    19.             #include "UnityCG.cginc"
    20.  
    21.             sampler2D _MainTex;
    22.             sampler2D _BackBuffer;
    23.  
    24.             uniform float _Distance;
    25.             uniform float _Alpha;
    26.             uniform float4 _Color;
    27.  
    28.             fixed4 frag(v2f_img v2f) : COLOR
    29.             {
    30.                 fixed4 col = tex2D(_BackBuffer, v2f.uv + float2(_Distance, 0.0));
    31.                 col.rgb *= _Color.rgb;    
    32.                 fixed4 main = tex2D(_MainTex, v2f.uv);
    33.                 col.a = _Alpha;
    34.                 return col - main;
    35.             }
    36.  
    37.             ENDCG
    38.         }
    39.      
    40.     }
    41.     FallBack "Diffuse"
    42. }
    43.  
    AfterImage.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [ExecuteInEditMode]
    5. public class AfterImage : MonoBehaviour
    6. {
    7.     public Shader shader;
    8.     private Material m_mat = null;
    9.     private Material mat { get {
    10.         if(m_mat == null)
    11.             m_mat = new Material(shader);
    12.         return m_mat;
    13.     }
    14.     }
    15.     private RenderTexture _BackBuffer;
    16.     public float _Distance = 0.05f;
    17.     public float _Alpha = 0.8f;
    18.     public Color _Color;
    19.  
    20.     void OnRenderImage(RenderTexture source, RenderTexture destination)
    21.     {
    22.         if(_BackBuffer == null)
    23.         {
    24.             _BackBuffer = new RenderTexture(source.width, source.height, 0, RenderTextureFormat.ARGB32);
    25.             _BackBuffer.filterMode = FilterMode.Point;
    26.             _BackBuffer.antiAliasing = 2;
    27.         }
    28.         mat.SetFloat("_Distance", _Distance);
    29.         mat.SetFloat("_Alpha", _Alpha);
    30.         mat.SetColor("_Color", _Color);
    31.         Graphics.Blit(source, destination, mat);
    32.         Graphics.Blit(destination, _BackBuffer);
    33.         mat.SetTexture("_BackBuffer", _BackBuffer);
    34.     }
    35. }
    36.  
     

    Attached Files:

    Last edited: Mar 21, 2015