Search Unity

[Particle System] Make particles with an outer glow.

Discussion in 'General Graphics' started by hedgeh0g, Sep 21, 2017.

  1. hedgeh0g

    hedgeh0g

    Joined:
    Jul 18, 2014
    Posts:
    102
    Hello,

    I cannot figure out how to make a particle with two different colours. I want a white particle with an outer glow of any other colour like the example I did here in Photoshop. As you can see, the particle is white, but it also has a clear blue outer glow.

    I've checked any possible setting in the editor but I cannot figure out how to achieve this effect. Any suggestion?
    Thanks in advance.
     

    Attached Files:

    • derp.jpg
      derp.jpg
      File size:
      28.6 KB
      Views:
      5,046
  2. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    This requires customizing the built-in Particle Additive shader. Change the line which multiplies the texture pixel color with vertex color into summation instead in the fragment shader. Sorry I am on bed already (midnight here) and I don't want to type the full shader code with my phone.
     
  3. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    Fiddle both Base and Saturation values. Color result differs whether HDR in rendering camera is enabled or not. If you are not satisfied by this shader (other shader experts may be able to come up with a better formula), you may create a particle texture sheet with pre-tinted glows and randomize all tiles in Texture Sheet Animation module.

    Edit: If you prefer HDR Bloom (post-processing effect, not recommended for mobile), then there would be some minor twist to the additive shader again.

    Code (CSharp):
    1. // Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
    2.  
    3. Shader "Particles/Additive Summation" {
    4. Properties {
    5.     _MainTex ("Particle Texture", 2D) = "white" {}
    6.     _Base ("Base", Range(0.0,1.0)) = 1.0
    7.     _Saturation ("Saturation", Range(0.0,100.0)) = 1.0
    8.     _Glow ("Intensity", Range(0.0,10.0)) = 0.0
    9.     _InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
    10. }
    11.  
    12. Category {
    13.     Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" }
    14.     Blend SrcAlpha One
    15.     ColorMask RGB
    16.     Cull Off Lighting Off ZWrite Off
    17.  
    18.     SubShader {
    19.         Pass {
    20.      
    21.             CGPROGRAM
    22.             #pragma vertex vert
    23.             #pragma fragment frag
    24.             #pragma target 2.0
    25.             #pragma multi_compile_particles
    26.             #pragma multi_compile_fog
    27.  
    28.             #include "UnityCG.cginc"
    29.  
    30.             sampler2D _MainTex;
    31.             fixed _Base;
    32.             fixed _Glow;
    33.             fixed _Saturation;
    34.          
    35.             struct appdata_t {
    36.                 float4 vertex : POSITION;
    37.                 fixed4 color : COLOR;
    38.                 float2 texcoord : TEXCOORD0;
    39.                 UNITY_VERTEX_INPUT_INSTANCE_ID
    40.             };
    41.  
    42.             struct v2f {
    43.                 float4 vertex : SV_POSITION;
    44.                 fixed4 color : COLOR;
    45.                 float2 texcoord : TEXCOORD0;
    46.                 UNITY_FOG_COORDS(1)
    47.                 #ifdef SOFTPARTICLES_ON
    48.                 float4 projPos : TEXCOORD2;
    49.                 #endif
    50.                 UNITY_VERTEX_OUTPUT_STEREO
    51.             };
    52.          
    53.             float4 _MainTex_ST;
    54.  
    55.             v2f vert (appdata_t v)
    56.             {
    57.                 v2f o;
    58.                 UNITY_SETUP_INSTANCE_ID(v);
    59.                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
    60.                 o.vertex = UnityObjectToClipPos(v.vertex);
    61.                 #ifdef SOFTPARTICLES_ON
    62.                 o.projPos = ComputeScreenPos (o.vertex);
    63.                 COMPUTE_EYEDEPTH(o.projPos.z);
    64.                 #endif
    65.                 //o.color = v.color;
    66.                 //o.color.rgb = pow(v.color.rgb,_pow) + _Glow;
    67.                 o.color.rgb = v.color.rgb + _Glow;
    68.                 o.color.a = v.color.a;
    69.                 o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
    70.                 UNITY_TRANSFER_FOG(o,o.vertex);
    71.                 return o;
    72.             }
    73.  
    74.             sampler2D_float _CameraDepthTexture;
    75.             float _InvFade;
    76.          
    77.             fixed4 frag (v2f i) : SV_Target
    78.             {
    79.                 #ifdef SOFTPARTICLES_ON
    80.                 float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
    81.                 float partZ = i.projPos.z;
    82.                 float fade = saturate (_InvFade * (sceneZ-partZ));
    83.                 i.color.a *= fade;
    84.                 #endif
    85.              
    86.                 fixed4 tex = tex2D(_MainTex, i.texcoord);
    87.                 fixed4 col = tex;
    88.                 col.a *= i.color.a * tex.r * tex.g * tex.b * tex.a;
    89.                 col.rgb = (col.rgb * i.color.rgb + col.rgb * _Saturation) * _Base + i.color.rgb * _Saturation;
    90.                 UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(0,0,0,0)); // fog towards black due to our blend mode
    91.                 return col;
    92.             }
    93.             ENDCG
    94.         }
    95.     }
    96. }
    97. }
    additive summation.png
     
    Last edited: Sep 22, 2017
  4. hedgeh0g

    hedgeh0g

    Joined:
    Jul 18, 2014
    Posts:
    102
    Thanks! This works just GREAT!

    Right now I'm messing around with HDR to see every possible variation of the final result.

    One more question: what should I do if I wish for a larger outer glow (the blue one) or a more saturated outer glow? Because the current Base, Saturation, Intensity value are effecting only the white glow, and on my background the outer glow almost vanishes.

    But this is great, it is exactly what I need. Thanks again mate!
     
    Last edited: Sep 22, 2017
  5. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    It comes down to customizing your own glow texture instead of using the built-in "Default Particle" glow if adjusting Base and Saturation still doesn't give you a desired result. Also line 88 can be simplified much more, I wrote that way assuming the texture does not have an alpha channel or disabled in texture setting (texture for built-in Additive shader doesn't require one, in fact it could cause ugly gradient banding.)
    Code (CSharp):
    1. col.a *= i.color.a;
    Edit: Alternatively:
    Code (CSharp):
    1. col.a *= i.color.a * (tex.r + tex.g + tex.b) * 0.333 * tex.a;
     
    Last edited: Sep 22, 2017
    theANMATOR2b likes this.
  6. hedgeh0g

    hedgeh0g

    Joined:
    Jul 18, 2014
    Posts:
    102
    All right, I see what you mean. I'll try to make a custom glow texture then, and see what I get.

    With that change on line 88 I see the particles becoming bigger. I suppose it is because we're not taking in account the texture anymore. Am I right? Sorry, there is a reason if I'm a gameplay programmer and not a shader programmer. :D

    EDIT: wait a second, what if we customize the Alpha Blended shader instead of the Additive?
     
    Last edited: Sep 22, 2017
  7. ifurkend

    ifurkend

    Joined:
    Sep 4, 2012
    Posts:
    350
    Technically you can by changing line 14 according to blending doc (traditional transparency). The problem is that by "glow" it should be optically emissive, hence the blending with the background RGB should be additive. Alpha blend does multiplication (or so it seems) so the blending result looks "dull". Of course you can do 2 passes in the shader, but to me it's not worth the extra draw call.
     
  8. hedgeh0g

    hedgeh0g

    Joined:
    Jul 18, 2014
    Posts:
    102
    Yeah I see the problem, also the extra draw call is pretty much pointless to me.

    How about a particle with a clearly visible outline like this? No glows. Just some random white dots randomly exploding out of a source? (sorry, I'm trying to figure out something completely different from the main topic).
     

    Attached Files:

    • herp.jpg
      herp.jpg
      File size:
      25.8 KB
      Views:
      1,130