Search Unity

Graphics.Blit image effect not working after upgrading to 2017.3.1

Discussion in 'Shaders' started by AlexGK, Feb 17, 2018.

  1. AlexGK

    AlexGK

    Joined:
    Jul 31, 2013
    Posts:
    38
    Hello:

    I'm still learning the basics of shader programming, so this may be a silly problem.

    I adapted some code I found online for displaying a "blast" image effect (my changes made possible for multiple blasts). After I upgraded Unity from 5.6 to 2017.3.1, the effect stopped working. I noticed there is a new option on Player Settings for Android (my target platform) to specify a Blit Type, and I mess around with it, but with no success. Besides, the effect no longer works on Standalone either.

    The effect is something similar to this (not my game):




    You can download a sample project here.

    Also, here's the code responsible for the effect:

    ExplosionEffect.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class ExplosionEffect : MonoBehaviour {
    6.     public Material explosionMaterial;
    7.     [Range(-10f, 10f)]
    8.     public float amplitude = 0.035f;
    9.     private readonly int maxExplosions = 6;
    10.     private Explosion[] explosions;
    11.  
    12.     private int amplitudeID;
    13.     private int explosionRadiusID;
    14.     private int explosionSizesID;
    15.     private int explosionActivesID;
    16.     private int explosionPositionsID;
    17.  
    18.     private RenderTexture renderTexture;
    19.     private Camera cam;
    20.  
    21.     private void Start() {
    22.         cam = Camera.main;
    23.         explosions = new Explosion[maxExplosions];
    24.  
    25.         amplitudeID = Shader.PropertyToID("_Amplitude");
    26.         explosionRadiusID = Shader.PropertyToID("_ExplosionRadius");
    27.         explosionSizesID = Shader.PropertyToID("_ExplosionSizes");
    28.         explosionActivesID = Shader.PropertyToID("_ExplosionActives");
    29.         explosionPositionsID = Shader.PropertyToID("_ExplosionPositions");
    30.  
    31.         explosionMaterial.SetFloat(amplitudeID, amplitude);
    32.         explosionMaterial.SetFloatArray(explosionRadiusID, GetAllRadius());
    33.         explosionMaterial.SetFloatArray(explosionSizesID, GetAllSizes());
    34.         explosionMaterial.SetFloatArray(explosionActivesID, GetAllActives());
    35.         explosionMaterial.SetVectorArray(explosionPositionsID, GetAllPositions());
    36.     }
    37.  
    38.     private void Update() {
    39.         for (int i = 0; i < maxExplosions; i++) {
    40.             if (explosions[i].IsActive) {
    41.                 explosions[i].SetActiveTime(explosions[i].ActiveTime + Time.deltaTime);
    42.                 if (explosions[i].ActiveTime >= explosions[i].time) {
    43.                     explosions[i].SetActiveTime(0f);
    44.                     explosions[i].radius = 0f;
    45.                     explosions[i].DeActivate();
    46.                 }
    47.                 else {
    48.                     explosions[i].radius = (explosions[i].ActiveTime / explosions[i].time) * explosions[i].size;
    49.                 }
    50.             }        
    51.         }
    52.  
    53.         explosionMaterial.SetFloatArray(explosionRadiusID, GetAllRadius());
    54.         explosionMaterial.SetFloatArray(explosionSizesID, GetAllSizes());
    55.         explosionMaterial.SetFloatArray(explosionActivesID, GetAllActives());
    56.         explosionMaterial.SetVectorArray(explosionPositionsID, GetAllPositions());
    57.     }
    58.  
    59.     public void SetExplosion(float _time, float _size, Vector2 _position) {
    60.         for (int i = 0; i < maxExplosions; i++) {
    61.             if (!explosions[i].IsActive) {
    62.                 explosions[i].time = _time;
    63.                 explosions[i].size = SetScreenExplosionSize(_size);
    64.                 explosions[i].position = _position;
    65.                 explosions[i].radius = 0f;
    66.                 explosions[i].SetActiveTime(0f);
    67.  
    68.                 explosions[i].Activate();
    69.                 break;
    70.             }
    71.         }
    72.     }
    73.  
    74.     private float SetScreenExplosionSize(float _size) {
    75.         if (cam.orthographicSize > 0) {
    76.             return _size / cam.orthographicSize;
    77.         }
    78.         return 0f;
    79.     }
    80.  
    81.     private float[] GetAllRadius() {
    82.         float[] radius = new float[maxExplosions];
    83.         for (int i = 0; i < maxExplosions; i++) {
    84.             radius[i] = explosions[i].radius;
    85.         }
    86.         return radius;
    87.     }
    88.  
    89.     private float[] GetAllSizes() {
    90.         float[] sizes = new float[maxExplosions];
    91.         for (int i = 0; i < maxExplosions; i++) {
    92.             sizes[i] = explosions[i].size;
    93.         }
    94.         return sizes;
    95.     }
    96.  
    97.     private float[] GetAllActives() {
    98.         float[] actives = new float[maxExplosions];
    99.         for (int i = 0; i < maxExplosions; i++) {
    100.             actives[i] = explosions[i].IsActive ? 1 : 0;
    101.         }
    102.         return actives;
    103.     }
    104.  
    105.     private Vector4[] GetAllPositions() {
    106.         Vector4[] positions = new Vector4[maxExplosions];
    107.         for (int i = 0; i < maxExplosions; i++) {
    108.             positions[i] = cam.WorldToViewportPoint(explosions[i].position);
    109.         }
    110.         return positions;
    111.     }
    112.  
    113.  
    114.     void OnPreRender() {
    115.         renderTexture = RenderTexture.GetTemporary(Screen.width, Screen.height, 16);
    116.         cam.targetTexture = renderTexture;
    117.     }
    118.  
    119.     void OnPostRender() {
    120.         cam.targetTexture = null; //null means framebuffer
    121.         Graphics.Blit(renderTexture, null as RenderTexture, explosionMaterial);
    122.         RenderTexture.ReleaseTemporary(renderTexture);
    123.     }
    124.  
    125. }
    ExplosionEffectShader.shader
    Code (CSharp):
    1. Shader "CerosWare/ExplosionEffectShader"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex("Texture", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         Tags { "RenderType"="Opaque" }
    10.         LOD 100
    11.  
    12.         Pass
    13.         {
    14.             CGPROGRAM
    15.  
    16.             #pragma vertex vert
    17.             #pragma fragment frag
    18.          
    19.             #include "UnityCG.cginc"
    20.  
    21.             struct appdata
    22.             {
    23.                 float4 vertex : POSITION;
    24.                 float2 uv : TEXCOORD0;
    25.             };
    26.  
    27.             struct v2f
    28.             {
    29.                 float2 uv : TEXCOORD0;
    30.                 float4 vertex : SV_POSITION;
    31.             };
    32.  
    33.             sampler2D _MainTex;
    34.             float4 _MainTex_ST;
    35.             uniform float _ExplosionActives[6];
    36.             uniform float _ExplosionRadius[6];
    37.             uniform float _ExplosionSizes[6];
    38.             uniform float4 _ExplosionPositions[6];
    39.             uniform float _Amplitude;
    40.  
    41.             v2f vert (appdata v)
    42.             {
    43.                 v2f o;
    44.                 o.vertex = UnityObjectToClipPos(v.vertex);
    45.                 o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.uv.xy);        
    46.  
    47.                 return o;
    48.             }
    49.          
    50.             float4 frag (v2f i) : SV_Target
    51.             {
    52.                 for (int expIndex = 0; expIndex < 6; expIndex++) {
    53.                     float active = _ExplosionActives[expIndex];
    54.                     if (active == 1) {
    55.                         float4 position = _ExplosionPositions[expIndex];
    56.                         float2 diff = float2(i.uv.x - position.x, i.uv.y - position.y);
    57.                         float dist = sqrt(diff.x * diff.x + diff.y * diff.y);
    58.                         float radius = _ExplosionRadius[expIndex];
    59.  
    60.                         if (dist < radius) {
    61.                             float size = _ExplosionSizes[expIndex];
    62.                             if (dist < radius + size) {
    63.                                 float angle = (dist - radius) * 2 * 3.141592654 / size;
    64.                                 float cossin = (1 - cos(angle)) * 0.5;
    65.                                 i.uv.x -= cossin * diff.x * _Amplitude / dist;
    66.                                 i.uv.y -= cossin * diff.y * _Amplitude / dist;
    67.                                 break;
    68.                             }
    69.                         }
    70.                     }
    71.                 }
    72.                 return tex2D(_MainTex, i.uv);
    73.             }
    74.  
    75.             ENDCG
    76.         }
    77.     }
    78. }
     
    Last edited: Feb 17, 2018