A Complete XBox 360 GPU Particle System: Tech & Pipeline Sebastian Sylvan & Dr Simon Scarle Rare...
-
Upload
justin-shelton -
Category
Documents
-
view
217 -
download
0
Transcript of A Complete XBox 360 GPU Particle System: Tech & Pipeline Sebastian Sylvan & Dr Simon Scarle Rare...
Background: The Xbox 360
Flexible fetching
VS_OUTPUT vs_main( int ix : INDEX ){
int index = (ix+0.5)/a_const.x; float4 pos;
float2 uv;asm{
vfetch pos, index, position0;vfetch uv, index, texcoord0;
};/* .... snip .... */
}
Background: The Xbox 360
Memory Export
Main Memory
Vertex Shade
r
Pixel Shad
er
Frame
BufferDIP
ME
ME
Simulationvoid simulation_shader( int ix : INDEX ){
Particle p = decompress(fetch_particle(ix));
Particle newp = simulate( p, ix, delta_time );
write_particle( ix, compress(newp) );}
Simulation
Newtonian motion
// a = (sum of forces) / massnewp.vel = p.vel + dt*a;newp.pos = p.pos + p.vel*dt;
Simulation
Turbulence :Position-dependent
random forcea += f(tex3D(turb_tex, g(p.pos)));
Scale/bias position into “turbulence
space”
Per-system scale/bias
Simulation
Alleviating Cache Thrashing
•Use small texture•Use “thin” format (e.g. 10:11:11)
•Sort the particles
Simulation
Emissionfloat4 rnd;float x = (ix+rnd_offset) % rnd_size;asm{ tfetch1D rnd, x, rnd_tex, UnnormalizedTextureCoords=true};
Particle newp = create_particle(rnd);rnd = ix > half_N ? rnd.xyzw : rnd.wzyx;
Sorting
Odd-Even mergemerge(s){ n = size(s) if ( n == 2 ) { return CAS(s(0),s(1)) } else { odds = s(1,3,..,n-1) evens = s(0,2,..,n-2) result = interleave( merge(evens), merge(odds))
for ( i = (1,3,..,n-2) ) { (x,y) = CAS(result(i), result(i+1)) result(i)= x result(i+i)= y } }}
Merge the two halves of the array s
Sorting
Odd-Even merge2 3 8 12 1 6 7 10
2 8 6 103 121 7
2 1 8 7 3 6 12 10
1 7 2 8 3 10 6 12
1 3 2 6 7 10 8 12
Sorting
Odd-Even merge sortNested algorithm, needs manual
flattening for parallelism:
Instant Insanity!
Sorting
Advice for staying sane
•Write “twin” version in GPPL• Debugging: step through PIX and
your “twin” simultaneously
Sorting
Or, just copy my stuff!
Google: “Particle System Simulation and Rendering on the Xbox 360 GPU“
Sorting
When incremental sorting fails
Whenever there the position changes too quickly
Prime example: Respawns Solution: Delay simulation/rendering of newly spawned particle
for a few frames for sorting
Rendering
Geometry AmplificationProduce N vertices for each particle
Index Buffer
Particle Buffer
...
...
An Complete XBox 360 GPU Particle System: Tech & Pipeline
Sebastian Sylvan & Dr Simon ScarleRare MGS
almost
^
Old System
1. Artist wants a new particle system2. Artist talks to Programmer3. Programmer implements code/shaders to
produce the effect4. Artist looks at particles and wants it exactly
the same only completely different5. Goto 2 : Rinse & Repeat
New System
• Rare usually takes an Art Driven approach• Creation of particle effects via art tool• Sebastian's Tech demos implemented in our
pipeline with this in mind– highly customisable– efficiency
Artist Input
• Particle.mb produced by Maya– Main art package at Rare– Use Maya particle options as base
• Extend – custom attributes on particle nodes• Random Scaling/orientation• Soft Particles• Timing
Interim Build Format
• Parse particle data from artist input– Rparticle
• Currently undergoing a de-Maya-ification process– i.e. add another rparticle producer– rparticle objects produced in WorldBuilder/Viewer
Rparticle
• Collection of arrays of custom data storage classes – RparticleObject – RparticleEmitter– RparticleField– RparticleRamp
• And a couple of R1 data classes– RmodelShader– RmodelNurbsCurve
Simulation Shader
• Lego-ized/modular construction• “Death to the Über-Particle by meta-coding”• RparticleObject is parsed into two lists of
ISimulationFragment– Initialisation– Simulation
• Fragments output needed HLSL to build up the shader
Simulation Shader
• Helper mini-fragments• Initialisation Frags– Create a new particle– Depends on emitter
• Directional• Omni-directional• Volume• Curve/Texture
• Simulation Frags– Euler integration for
Newtonian motion– Fields
• Gravity/Uniform• Drag• radial• vortex
– Collisions• Sphere• plane
InitFragmentOmniinitcode << GetRandomNumGenerator() <<
‘’ void InitParticle( int index, inout Part particle ){‘’‘’ float4 rnd = Random( index );’’ ’’ particle.pos = float3( 0, 0, 0);’’
‘’ float3 buildVel = 2 * ( rnd.x – 0.5 );““ float fac = sqrt ( 1 - buildVel.z* buildVel.z );”<< SinCos( ‘’theta’’, ‘’2* PI* rnd.y’’ )<<“ buildVel.x = fac* cosTheta;"“ buildVel.y = fac* sinTheta;”“ particle. Vel = buildVel;“;
initcode << OffSetMinMaxDistance( m_emitter->GetMinDist(), m_emitter->GetMaxDist() )<<
“ particle.vel *= ( 2* rnd.w - 1) *”<< m_emitter->GetSpeedRandom() <<‘’ +’’ << m_emitter->GetSpeed() <<‘’;’’<< Epilogue( 0, pdesc );
Simulation Shader
• Very easy to add new types of emitter and dynamics– implement HLSL code in a ISimulationFragment
• Not a huge Über-shader – Only the Code needed
• Slight problem adding a new Feature to an “Active” Asset– Shader rebuild not just a parameter tweak
Render Shader
• Three customizations of our standard shader builder– no Über-shader again– Easy use of current special effects
• Three standard base types– Pointsprites– Line / Streaks– Quad / billboards / sprites
Render Shader
• geometry amplification for non-point sprite primitives– Use velocity to get 2nd vertex for line particles– Produce further vertices for camera facing quads
• Once again only required parts of shader are present
• Line fade / colour change• ramp textures to rotate/scale sprites
Parameters
• Broadest sense– Parameters/Data for effects• Softness• Spread• Emitter transform
– Position, direction
– Textures• Ramps
– scaleX, scaleY, rotation, RGBA
• Curve / texture emitters