Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This post has been wikified, any user with enough reputation can edit it.
avatar image
0
Question by Exalia · Nov 16, 2013 at 10:13 AM · shadershadersparticlesparticlepassing

Particle Shader help

Hi,

I'm starting to learn shaders and wanted to create my own particle effect shader.

The only thing I want to pass to the shader is the frame time (Time.deltaTime) and the shader will do the rest of the work (Transformation and modifying the alpha value)

I want to calculate the age of the particle by setting a lifetime (LT) and a current age (Age) then by doing LT - Age I can find out how 'old' the particle is, the older the particle the higher the alpha value. When alpha reaches 1 or the fragment is invisible I want to set the Age back to 0. The position of the particle will be definied by the Age also, if the Age is 0 the particle will be ontop of the emitter.

I would like to do all transformation in the vertex shader and all alpha value modifyin gin the fragment shader.

I don't understand the shaders very well and was hoping someone could offer some assistance in how to get my method working. This is the second shader I'm trying to write so I'm still trying to understand the syntax :)

Here's what I have so far

 Shader "Custom/ParticalShader" 
 {
     Properties 
     {
         _Speed ("Particle Speed", Range (0,100)) = 1
     }
     SubShader 
     {
         Pass
         {    
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #include "UnityCG.cginc"
             
             float _Speed;
             
             struct v2f {
                 float4 pos : SV_POSITION;
                 float3 color : COLOR0;
             };
 
             v2f vert (appdata_base v)
             {
                 float t = frac(v.vertex.z + _Speed * _Time); 
                   float s = pow(t, 1);
               
                 v2f o;
                 o.pos.x = 20 * s * sin(62.0 * v.vertex.z);
                    o.pos.z = 20 * s * cos(163.0 * v.vertex.z);
                    o.pos.y = t * 80;
                    
                    //o.pos += 7.8 * (v.vertex.x * UNITY_MATRIX_I_V, + v.vertex.y * UNITY_MATRIX_I_V).xyz;
                    //o.pos += vec4(0,0,0,0);
                    
                    o.pos = mul (UNITY_MATRIX_VP, o.pos);
                 o.color = 1.0 - t;
                 return o;
             }
 
             half4 frag (v2f i) : COLOR
             {
                 return half4 (i.color, 1);
             }
             ENDCG
         }
     }
 }

I'm reading up on this as I post it but I would still like to know the community's opinion on how to do this :)

Thanks in advance

Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Exalia · Dec 04, 2013 at 11:36 PM 0
Share

Currently my particle shader works but is hard to see without billboarding, trying to implement this now

avatar image OP_toss · Dec 04, 2013 at 11:58 PM 0
Share

Cool project!

I have a couple more questions for you... What is instancing vertices? Do you do that in c# with a single procedural mesh? Is this attached to each individual particle? Is each particle a mesh then?

You might want to look into tessellation shaders in order to vastly improve performance of your particle system. The idea is that you could have 1 shader create all your particle geo for you, for basically free, and much faster than doing it on the cpu. I have little experience with this, but the concept is enticing.

FYI Raising a number to the power of 1 does nothing. But I assume you know that...

Also you mention setting the alpha based on age, but then your alpha is being set to 1. Have you not gotten to the fragment shader yet? Using color to pass this info from the vertex to the fragment shader should suffice, though I recommend using each channel separately so you can send 4 floats of data across, if you need. So maybe you can use rgb for velocity, and a for age?

Billboarding is just some matrix math. Here's a glsl solution I found, may be of use to you:

 gl_Position = gl_Projection$$anonymous$$atrix 
                * (gl_$$anonymous$$odelView$$anonymous$$atrix * vec4(0.0, 0.0, 0.0, 1.0) 
                + vec4(gl_Vertex.x, gl_Vertex.y, 0.0, 0.0));


Hope that helped!

avatar image Exalia · Dec 05, 2013 at 02:01 PM 0
Share

This was some awesome help, Although I am making my particle system for $$anonymous$$obile so I don't have access to tessellation, I do however have access to transform feedback (Although Unity doesn't seem to support this directly).

avatar image Exalia · Dec 05, 2013 at 02:08 PM 0
Share

To answer some of your questions

I have several Quads and attatch the shader to each quad (This achieves 1 draw call but only by batching, I would like to get rid of this and make it 1 draw call with no batching)

Hehe yeah I did know that I was just playing around with some variables :)

Correct I haven't got to the fragment shader yet.

Using the colour channgels to pass data is awesome I'm definitely going to try to impliment this. Thanks :)

I managed to sort the billboarding to some extent :) (For anyone else looking at this question)

             v2f vert (appdata_base v)
             {
                 float t = frac(v.vertex.z + _Speed * _Time); 
                   float s = pow(t, 1);
                   float3 eyeVector = ObjSpaceViewDir( v.vertex );
                 float3 upVector = float3(0,1,0);
                 float3 sideVector = normalize(cross(eyeVector,upVector));
               
                 v2f o;
                 o.pos.x = 20 * s * sin(62.0 * v.vertex.z);
                    o.pos.z = 20 * s * cos(163.0 * v.vertex.z);
                    o.pos.y = t * _Height;
                 o.pos.xyz += 7.8 * (v.vertex.x * sideVector + v.vertex.y * upVector).xyz;
                    o.pos = mul (UNITY_$$anonymous$$ATRIX_VP, o.pos);
                 o.color = 1.0 - t;
                 return o;
             }

It is was OP_toss said but in the unity syntax :)

avatar image luchoscar · Jul 17, 2014 at 06:23 AM 0
Share

I did something similar to what you are doing but ins$$anonymous$$d of having a quad a had an empty game object and added a mesh with a single point in order to use a material that implemented a vertex/geometry/fragment shader. You could try something like having a collection of vertices (Vector4) were the w component represents the alpha over time which gets set to a separate variable in the vertex shader and passed to the geometry shader. You could have something like this

 struct GS_INPUT
 {
 float4    pos : POSITION;
 float alphaVal : TEXCOORD0;
 };
 
 // Vertex Shader ------------------------------------------------
 GS_INPUT VS_$$anonymous$$ain(appdata_full v)
 {            
 GS_INPUT output = (GS_INPUT)0;
                 
 output.pos =  mul(_Object2World, float4(v.vertex.xyz, 1));
 output.texCoord = float2(0, 0);
 output.alphaVal = v.vertex.w;    // this will get pass to the GS and then the FS to do transparency over time        
 return output;
 }
         
 struct FS_INPUT
 {
 float2  texCoord : TEXCOORD0;
 float alphaVal : TEXCOORD1;
 };
 
 [maxvertexcount(4)] // this indicates how many vertices will be output (4 for quad)
 // point indicates we are sending one vertex at a time to the GS
 // inout is the format on how the GPU should read the output, in this case triangle strip
 void GS_$$anonymous$$ain(point GS_INPUT p[1], inout TriangleStream triStream)
 {
 // here you can use some vector math to create a quad that is always facing the camera using Unity shader constants or you  can pass the camera position all the way here this includes normals if you want to get fancy and have them react to light as well as uv coordinates if you have a texture
 }


0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

19 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Limit particle shader / discard from certain worldpos 1 Answer

PS Custom Vertex Streams to Particle Trail 0 Answers

How to convert Legacy/Particles/Alpha Blended to Standard?And How to configure the standard option? 0 Answers

Shader tiling error 0 Answers

My particles glow at night how can I stop the glowing 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges