Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: data/branches/Shader_HS18/programs/Cg/ParticleGS.cg @ 12373

Last change on this file since 12373 was 12115, checked in by wiesep, 6 years ago

Changed folder structure, deletet some unused files and cleaned up code

File size: 9.1 KB
Line 
1//
2// Explanation of different particle types
3//
4#define PT_LAUNCHER 0 //Firework Launcher - launches a PT_SHELL every so many seconds
5#define PT_SHELL    1 //Unexploded shell - flies from the origin and explodes into many PT_EMBERXs
6#define PT_EMBER1   2 //basic particle - after it's emitted from the shell, it dies
7#define PT_EMBER2   3 //after it's emitted, it explodes again into many PT_EMBER1s
8#define PT_EMBER3   4 //just a differently colored ember1
9#define P_SHELLLIFE 3.0
10#define P_EMBER1LIFE 2.5
11#define P_EMBER2LIFE 1.5
12#define P_EMBER3LIFE 2.0
13
14//These two were originally shader params, but they caused runtime errors
15#define NUM_EMBER_1S 30
16#define NUM_EMBER_2S 15
17#define NUM_EMBER_3S 10
18//This one was originally a variant, but this also causes runtime errors
19//#define MAX_EMBER_2S 15.0
20
21//
22// Generic particle motion handler
23//
24
25void GSGenericHandler( float3 Pos, float3 Vel, float Timer, float Type,
26                                                float elapsedTime,
27                                                float3 frameGravity)
28{
29    Pos += Vel * elapsedTime;
30    Vel += frameGravity;
31    Timer -= elapsedTime;
32        if (Pos.y > -100)
33        {
34                emitVertex( Pos : POSITION, Vel : TEXCOORD2, Timer : TEXCOORD0, Type : TEXCOORD1);
35        }
36}
37
38//
39// Sample a random direction from our random texture
40//
41float3 RandomDir(float fOffset, float globalTime, sampler1D randomTex)
42{
43    float tCoord = (globalTime + fOffset) / 300.0;
44    return tex1D(randomTex, tCoord).rgb;
45}
46
47//
48// Launcher type particle handler
49//
50void GSLauncherHandler( float3 Pos, float3 Vel, float Timer, float Type,
51                                                float elapsedTime,
52                                                float globalTime,
53                                                sampler1D randomTex,
54                                                float secondsPerFirework)
55{
56    if(Timer <= 0)
57    {
58        float3 vRandom = normalize( RandomDir( Type, globalTime, randomTex) );
59                //Give it more of an up bias
60        vRandom = normalize(vRandom + float3(0,2.5,0));
61               
62                //time to emit a new SHELL
63        float3 outputPos = Pos + Vel*elapsedTime;
64        float3 outputVel = Vel + vRandom*35.0;
65        float  outputTimer = P_SHELLLIFE + vRandom.y*0.5;
66        float outputType = PT_SHELL;
67        emitVertex(outputPos : POSITION, outputVel : TEXCOORD2, outputTimer : TEXCOORD0, outputType : TEXCOORD1);
68       
69        //reset our timer
70        Timer = secondsPerFirework + vRandom.x*0.4;
71    }
72    else
73    {
74        Timer -= elapsedTime;
75    }
76   
77    //emit ourselves to keep us alive
78    emitVertex( Pos : POSITION, Vel : TEXCOORD2, Timer : TEXCOORD0, Type : TEXCOORD1);
79}
80
81//
82// Shell type particle handler
83//     
84void GSShellHandler( float3 Pos, float3 Vel, float Timer, float Type,
85                                        float elapsedTime,
86                                        float globalTime,
87                                        sampler1D randomTex,
88                                        float3 frameGravity)
89{
90    if(Timer <= 0)
91    {
92        float3 outputPos;
93                float3 outputVel;
94                float outputTimer;
95                float outputType;
96               
97        float3 vRandom = float3(0,0,0);
98       
99        //time to emit a series of new Ember1s 
100        for(int i=0; i<NUM_EMBER_1S; i++)
101        {
102            vRandom = normalize( RandomDir( Type+i, globalTime, randomTex ) );
103            outputPos = Pos + Vel*elapsedTime;
104            outputVel = Vel + vRandom*15.0;
105            outputTimer = P_EMBER1LIFE;
106            outputType = PT_EMBER1;
107            emitVertex(outputPos : POSITION, outputTimer : TEXCOORD0, outputType : TEXCOORD1, outputVel : TEXCOORD2);
108        }
109       
110        //find out how many Ember2s to emit
111                //Not doing this because it causes a runtime error
112                //int numEmber2s = abs(vRandom.x)*MAX_EMBER_2S;
113        for(int i=0; i<NUM_EMBER_2S; i++)
114        {
115            vRandom = normalize( RandomDir( Type, globalTime, randomTex) );
116            outputPos = Pos + Vel*elapsedTime;
117            outputVel = Vel + vRandom*10.0;
118            outputTimer = P_EMBER2LIFE + 0.4*vRandom.x;
119            outputType = PT_EMBER2;
120            emitVertex(outputPos : POSITION, outputVel : TEXCOORD2, outputTimer : TEXCOORD0, outputType : TEXCOORD1);
121        }
122       
123    }
124    else
125    {
126        GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
127    }
128}
129
130//
131// Ember1 and Ember3 type particle handler
132//
133void GSEmber1Handler( float3 Pos, float3 Vel, float Timer, float Type,
134                                                float elapsedTime,
135                                                float3 frameGravity)
136{
137    if(Timer > 0)
138    {
139        GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
140    }
141}
142
143//
144// Ember2 type particle handler
145//
146void GSEmber2Handler( float3 Pos, float3 Vel, float Timer, float Type,
147                                                float elapsedTime,
148                                                float globalTime,
149                                                sampler1D randomTex,
150                                                float3 frameGravity)
151{
152    if(Timer <= 0)
153    {
154                float3 outputPos;
155                float3 outputVel;
156                float outputTimer;
157                float outputType;
158   
159        //time to emit a series of new Ember3s 
160        for(int i=0; i<NUM_EMBER_3S; i++)
161        {
162            outputPos = Pos + Vel*elapsedTime;
163            outputVel = Vel + normalize( RandomDir( Type + i, globalTime, randomTex ) )*10.0;
164            outputTimer = P_EMBER3LIFE;
165            outputType = PT_EMBER3;
166            emitVertex(outputPos : POSITION, outputVel : TEXCOORD2, outputTimer : TEXCOORD0, outputType : TEXCOORD1);
167        }
168    }
169    else
170    {
171         GSGenericHandler(Pos, Vel, Timer, Type, elapsedTime, frameGravity );
172    }
173}
174
175struct FireworkData
176{
177        float4  Pos     : POSITION;
178        float   Timer   : TEXCOORD0;
179    float       Type    : TEXCOORD1;
180        float3  Velocity : TEXCOORD2;
181};
182
183//The vertex shader that prepares the fireworks for display
184FireworkData GenerateParticles_VS(
185    in float4           inPos : POSITION,       
186        in float                inTimer : TEXCOORD0,
187        in float                inType : TEXCOORD1,
188        in float3               inVelocity : TEXCOORD2
189        )
190{
191        FireworkData output;
192        output.Pos = inPos;
193        output.Timer = inTimer;
194        output.Type = inType;
195        output.Velocity = inVelocity;
196       
197        return output;
198}
199
200POINT
201POINT_OUT
202void GenerateParticles_GS(
203        AttribArray<float3> Pos : POSITION,
204        AttribArray<float> Timer : TEXCOORD0,
205        AttribArray<float> Type : TEXCOORD1,
206        AttribArray<float3> Vel : TEXCOORD2,
207       
208        uniform sampler1D randomTex : TEXUNIT0,
209        uniform float3 frameGravity,
210        uniform float globalTime,
211        uniform float elapsedTime,
212        uniform float secondsPerFirework
213        )
214{
215        if( Type[0] == PT_LAUNCHER )
216        GSLauncherHandler( Pos[0], Vel[0], Timer[0], Type[0],
217                                                        elapsedTime, globalTime, randomTex, secondsPerFirework);
218        else if ( Type[0] == PT_SHELL )
219        GSShellHandler( Pos[0], Vel[0], Timer[0], Type[0],
220                                                        elapsedTime, globalTime, randomTex, frameGravity);
221        else if ( Type[0] == PT_EMBER1 ||
222              Type[0] == PT_EMBER3 )
223       GSEmber1Handler( Pos[0], Vel[0], Timer[0], Type[0],
224                                                        elapsedTime, frameGravity);
225    else if( Type[0] == PT_EMBER2 )
226        GSEmber2Handler( Pos[0], Vel[0], Timer[0], Type[0],
227                                                        elapsedTime, globalTime, randomTex, frameGravity);
228}
229
230struct ColoredFirework
231{
232        float3  pos : POSITION;
233    float4      color : COLOR;
234        float   radius : TEXCOORD0;
235};
236
237//The vertex shader that prepares the fireworks for display
238ColoredFirework DisplayParticles_VS
239(
240    in float3           inPos : POSITION,
241        in float                inTimer : TEXCOORD0,
242        in float                inType : TEXCOORD1,
243        in float3               inVelocity : TEXCOORD2
244       
245
246    //uniform float4x4 worldViewProj
247)
248{
249        ColoredFirework output;
250    //
251    // Pass the point through
252    //
253    output.pos = inPos; //Multiply by world matrix?
254    output.radius = 1.5;
255   
256    // 
257    // calculate the color
258    //
259    if( inType == PT_LAUNCHER )
260    {
261        output.color = float4(1,0.1,0.1,1);
262        output.radius = 1.0;
263    }
264    else if( inType == PT_SHELL )
265    {
266        output.color = float4(0.1,1,1,1);
267        output.radius = 1.0;
268    }
269    else if( inType == PT_EMBER1 )
270    {
271        output.color = float4(1,1,0.1,1);
272        output.color *= (inTimer / P_EMBER1LIFE );
273    }
274    else if( inType == PT_EMBER2 )
275    {
276        output.color = float4(1,0.1,1,1);
277    }
278    else if( inType == PT_EMBER3 )
279    {
280        output.color = float4(1,0.1,0.1,1);
281        output.color *= (inTimer / P_EMBER3LIFE );
282    }
283   
284    return output;
285}
286
287//The geometry shader that prepares the fireworks for display
288POINT
289TRIANGLE_OUT
290void DisplayParticles_GS( AttribArray<float3> Pos : POSITION,
291                                                        AttribArray<float4> Color : COLOR,
292                                                        AttribArray<float> Radius : TEXCOORD0,
293                                                       
294                                                        uniform float4x4 inverseView,
295                                                        uniform float4x4 worldViewProj)
296{
297        //float3 g_positions[4] = { float3( -1, 1, 0 ), float3( 1, 1, 0 ), float3( -1, -1, 0 ), float3( 1, -1, 0 ) };
298        float3 g_positions[4] = { float3( -1, 1, 0 ), float3( -1, -1, 0 ), float3( 1, 1, 0 ), float3( 1, -1, 0 ) };
299    float2 g_texcoords[4] = { float2(0,1), float2(1,1), float2(0,0), float2(1,0) };
300       
301       
302        //
303    // Emit two new triangles
304    //
305    for(int i=0; i<4; i++)
306    {
307                float3 position = -g_positions[i]*Radius[0];
308        position = mul( (float3x3)inverseView, position ) + Pos[0];
309        float4 outPos = mul( worldViewProj, float4(position,1.0) );
310       
311        emitVertex(outPos : POSITION, Color[0] : COLOR0, g_texcoords[i] : TEXCOORD0);
312    }
313    restartStrip();
314}
315
316//The pixels shaders that colors the fireworks
317float4 DisplayParticles_PS(     float2 iTexCoord : TEXCOORD0,
318                                                        float4 iColor : COLOR0,
319                                                        uniform sampler diffuseTex : register(s0)) : COLOR
320{
321        return tex2D(diffuseTex, iTexCoord) * iColor;
322        //return float4(iTexCoord.x, iTexCoord.y, 0, 1) + iColor * 0.01;
323        //return float4(iTexCoord.xy, 0, 1) * 0.3 + tex2D(diffuseTex, iTexCoord) * 0.7 + iColor * 0.01;
324}
Note: See TracBrowser for help on using the repository browser.