Search Unity

Using particles to mask other particles

Discussion in 'Editor & General Support' started by tanico, Feb 18, 2017.

  1. tanico

    tanico

    Joined:
    Sep 5, 2014
    Posts:
    24
    I have seen the following video and I've been trying to obtain the same effect in Unity using the Particle System, but I'm kind of having a hard time:

    https://twitter.com/timsoret/status/788524951959732224

    What I'd need is to be able to spawn some particles that instead of drawing on the screen should actually act as masks over normal particles.

    Anyone who's got any clue about a good approach to obtain the same effect?

    Cheers!
     
  2. IronLionZion

    IronLionZion

    Joined:
    Dec 15, 2015
    Posts:
    78
    Are these supposed to be rendered in 2D space or 3D?
    If in 2D space, then you could render 2 sets of particles with 2 different cameras that each output to 2 separate render textures. The particles could be white and the cameras' clear flags set to a black colour. Then you will have 2 different masks that could be used as input to a shader that creates the effect. The shader can then be used for a material that is applied to a flat plane.
     
  3. tanico

    tanico

    Joined:
    Sep 5, 2014
    Posts:
    24
    The particles are going to be in 2D.

    Ideally your solution might work.
    Camera 1: clear to black, render to texture 1 only the colored particles
    Camera 2: clear to black, render to texture 2 only white particles
    Plane 1: material with an alpha blend shader that applies the mask of texture 2 to texture 1
     
  4. tanico

    tanico

    Joined:
    Sep 5, 2014
    Posts:
    24
    This has got me closer to the result I'm looking for, but I still have a problem.
    You can see it there: https://www.dropbox.com/s/xefa93pv3ccbtv8/bus-07.gif?dl=0

    Basically the mask is working fine for the colored particles, but since the rest of the texture is also being set to black, that part is being rendered instead of being transparent. I need an idea to fix it.
     
  5. IronLionZion

    IronLionZion

    Joined:
    Dec 15, 2015
    Posts:
    78
    I won't be able to be of much help until I see the shader code.
    But take note, I'm not an expert at shaders though.

    Maybe have the black part of the coloured texture also affect the transparency.
    example pseudo code:
    Code (CSharp):
    1. fixed colMask = ConvertToGreyScale(colorTexture).r;
    2. output.a *= ceil(colMask);
     
    Last edited: Feb 20, 2017
  6. tanico

    tanico

    Joined:
    Sep 5, 2014
    Posts:
    24
    The shader is just a simple alpha mask. I set both RT to clear at alpha 0 and all the particles are at alpha 1.0

    Here's the shader's code:

    Code (CSharp):
    1. // Unlit alpha-blended shader.
    2. // - no lighting
    3. // - no lightmap support
    4. // - no per-material color
    5.  
    6. Shader "Unlit/AlphaMask" {
    7.     Properties {
    8.         _MainTex ("Base (RGB)", 2D) = "white" {}
    9.         _AlphaTex ("Alpha mask (R)", 2D) = "white" {}
    10.     }
    11.  
    12.     SubShader {
    13.         Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    14.         LOD 100
    15.      
    16.         ZWrite Off
    17.         Blend SrcAlpha OneMinusSrcAlpha
    18.  
    19.         Pass {
    20.             CGPROGRAM
    21.                 #pragma vertex vert
    22.                 #pragma fragment frag
    23.              
    24.                 #include "UnityCG.cginc"
    25.  
    26.                 struct appdata_t {
    27.                     float4 vertex : POSITION;
    28.                     float2 texcoord : TEXCOORD0;
    29.                 };
    30.  
    31.                 struct v2f {
    32.                     float4 vertex : SV_POSITION;
    33.                     half2 texcoord : TEXCOORD0;
    34.                 };
    35.  
    36.                 sampler2D _MainTex;
    37.                 sampler2D _AlphaTex;
    38.              
    39.                 float4 _MainTex_ST;
    40.              
    41.                 v2f vert (appdata_t v)
    42.                 {
    43.                     v2f o;
    44.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    45.                     o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
    46.                     return o;
    47.                 }
    48.              
    49.                 fixed4 frag (v2f i) : SV_Target
    50.                 {
    51.                     fixed4 col = tex2D(_MainTex, i.texcoord);
    52.                     fixed4 col2 = tex2D(_AlphaTex, i.texcoord);
    53.                  
    54.                     return fixed4(col.r, col.g, col.b, col2.a);
    55.                 }
    56.             ENDCG
    57.         }
    58.     }
    59.  
    60. }
    61.  
     
  7. IronLionZion

    IronLionZion

    Joined:
    Dec 15, 2015
    Posts:
    78
    Try this in your frag function:
    Code (CSharp):
    1. fixed4 frag (v2f i) : SV_Target
    2. {
    3.     fixed4 col = tex2D(_MainTex, i.texcoord);
    4.     fixed4 col2 = tex2D(_AlphaTex, i.texcoord);
    5.    
    6.     // If _AlphaTex doesn't have an alpha channel, since it is black and white, you can use:
    7.     // fixed alpha = col2.r;
    8.  
    9.     // If _AlphaTex has an alpha channel:
    10.     fixed alpha = col2.a;
    11.  
    12.     // If _MainTex has an alpha channel:
    13.     // float colMask = col.a;
    14.  
    15.     // If _MainTex doesn't have an alpha channel
    16.     // Desaturate by finding the average: not accurate but it'll do.
    17.     float colMask = (col.r + col.g + col.b) / 3;
    18.     colMask = ceil(colMask);
    19.  
    20.     alpha *= colMask;
    21.                
    22.     return fixed4(col.r, col.g, col.b, alpha);
    23. }