Add Trapcode Particular VFX systems: Aux trails, Layer emitter, Bounce physics, Curves over life (v1.1.0)
e14f09d verified Download examples/10_trapcode_particular_features.py from ArifiIslam/particri: direct link, hf CLI and curl.
- Browser
- Download file 5.18 kB
-
https://huggingface.co/ArifiIslam/particri/resolve/main/examples/10_trapcode_particular_features.py
- Command line
-
hf download hf://ArifiIslam/particri/examples/10_trapcode_particular_features.py
-
curl -L -o 10_trapcode_particular_features.py https://huggingface.co/ArifiIslam/particri/resolve/main/examples/10_trapcode_particular_features.py
5.18 kB
| """ | |
| Example 10: Trapcode Particular Iconic Features Showcase | |
| Demonstrates: | |
| 1. Auxiliary Particle System (Aux Trails & Secondary Sparkle Dust) | |
| 2. Floor Collision & Bounce Physics (Elasticity & Surface Friction) | |
| 3. Custom Curves Over Life (Bell, GrowAndFade, Pulse) | |
| 4. Layer Mask Emitter (Particle Birth from Image/Logo with Pixel Color Inheritance) | |
| """ | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) | |
| import numpy as np | |
| from PIL import Image, ImageDraw, ImageFont | |
| import particri as pc | |
| output_dir = Path("output") | |
| output_dir.mkdir(exist_ok=True) | |
| print("--- 1. Generating Aux Trails & Floor Bounce Demo ---") | |
| engine_bounce = pc.ParticleEngine(max_particles=35000, width=1920, height=1080) | |
| # Add Floor Bounce Plane at y=920 | |
| engine_bounce.add_bounce_plane(coord=920.0, bounce=0.62, friction=0.88, is_horizontal=True, is_max=True) | |
| # Add Gravity & subtle atmospheric drag | |
| engine_bounce.add_gravity(0.0, 180.0) | |
| engine_bounce.add_drag(0.08) | |
| # Add slight curl noise turbulence | |
| engine_bounce.add_curl_noise(seed=42, strength=60.0, frequency=0.002, speed=0.2) | |
| # Primary Emitter: Golden Fountain shooting upwards & outwards | |
| engine_bounce.add_emitter( | |
| shape=pc.EmitterShape.Circle, | |
| position=(960.0, 750.0), | |
| size=(30.0, 30.0), | |
| rate=180.0, | |
| speed_range=(250.0, 520.0), | |
| angle_range=(-2.35, -0.78), # Upward fan | |
| lifetime_range=(1.8, 3.2), | |
| size_start_range=(8.0, 18.0), | |
| size_end_range=(1.0, 3.0), | |
| color_start=(1.0, 0.9, 0.5, 1.0), | |
| color_end=(1.0, 0.35, 0.05, 0.0), | |
| particle_shape=pc.ParticleShape.Star4, | |
| size_curve=pc.CurveType.GrowAndFade, | |
| opacity_curve=pc.CurveType.GrowAndFade, | |
| seed=101, | |
| ) | |
| # Auxiliary System: Each falling firework spark leaves shimmering golden dust trails! | |
| engine_bounce.enable_aux_system( | |
| rate=25.0, # 25 child particles per second from each primary particle | |
| lifetime=1.4, | |
| size_range=(4.0, 0.5), | |
| color_start=(1.0, 0.85, 0.3, 0.95), | |
| color_end=(1.0, 0.2, 0.05, 0.0), | |
| inherit_color=True, | |
| velocity_inheritance=0.12, # Child inherits 12% parent speed | |
| spread=18.0, # Slight jitter | |
| particle_shape=pc.ParticleShape.Glitter, | |
| size_curve=pc.CurveType.Bell, # Peaks in middle, gentle fade | |
| opacity_curve=pc.CurveType.GrowAndFade, | |
| emit_at_death=8, # 8 sparks burst on particle death | |
| ) | |
| # Simulate 3.5 seconds | |
| print("Simulating physics & particle lifecycles...") | |
| engine_bounce.warmup(duration=3.5, step=1.0 / 60.0) | |
| frame_bounce = engine_bounce.render(blend_mode=pc.BlendMode.Additive, bloom=True, bloom_intensity=0.85, bloom_radius=8) | |
| pc.Exporter.save_image(frame_bounce, output_dir / "10_particular_aux_trails_bounce.png") | |
| print(f"Saved: {output_dir / '10_particular_aux_trails_bounce.png'}") | |
| print("\n--- 2. Generating Layer Mask / Logo Emitter Demo ---") | |
| engine_layer = pc.ParticleEngine(max_particles=30000, width=1920, height=1080) | |
| # Create a vibrant synthetic logo image mask (1920x1080) with PIL | |
| logo_img = Image.new("RGBA", (1920, 1080), (0, 0, 0, 0)) | |
| draw = ImageDraw.Draw(logo_img) | |
| # Draw central geometric glowing star emblem with gradient rings | |
| cx, cy = 960, 540 | |
| # Outer ring (Cyan / Teal) | |
| draw.ellipse([cx - 280, cy - 280, cx + 280, cy + 280], outline=(0, 220, 255, 255), width=8) | |
| # Middle ring (Magenta / Pink) | |
| draw.ellipse([cx - 200, cy - 200, cx + 200, cy + 200], outline=(255, 60, 180, 255), width=6) | |
| # Inner ring (Warm Gold) | |
| draw.ellipse([cx - 120, cy - 120, cx + 120, cy + 120], outline=(255, 215, 80, 255), width=5) | |
| # Central diamond star polygon | |
| def make_star(center_x, center_y, r_outer, r_inner, num_pts=8): | |
| pts = [] | |
| for i in range(num_pts * 2): | |
| r = r_outer if i % 2 == 0 else r_inner | |
| angle = i * np.pi / num_pts - np.pi / 2 | |
| pts.append((center_x + r * np.cos(angle), center_y + r * np.sin(angle))) | |
| return pts | |
| star_pts = make_star(cx, cy, 100, 35, num_pts=8) | |
| draw.polygon(star_pts, fill=(255, 240, 200, 255), outline=(255, 180, 50, 255)) | |
| # Add Layer Emitter to engine with automatic pixel color inheritance! | |
| mask_np = np.asarray(logo_img, dtype=np.float32) / 255.0 | |
| engine_layer.add_layer_emitter( | |
| image=mask_np, | |
| rate=2800.0, | |
| speed_range=(8.0, 45.0), | |
| lifetime_range=(1.2, 3.0), | |
| size_start_range=(5.0, 14.0), | |
| size_end_range=(0.0, 2.0), | |
| particle_shape=pc.ParticleShape.Star8, | |
| size_curve=pc.CurveType.Bell, | |
| opacity_curve=pc.CurveType.GrowAndFade, | |
| inherit_layer_color=True, | |
| drag=0.18, | |
| seed=777, | |
| ) | |
| # Add subtle vortex swirl around the logo | |
| engine_layer.add_vortex(center=(cx, cy), strength=70.0, radial_pull=-10.0, radius=600.0) | |
| engine_layer.add_curl_noise(seed=999, strength=50.0, frequency=0.003, speed=0.2) | |
| print("Simulating logo layer emission...") | |
| engine_layer.warmup(duration=2.5, step=1.0 / 60.0) | |
| frame_layer = engine_layer.render(blend_mode=pc.BlendMode.Screen, bloom=True, bloom_intensity=0.9, bloom_radius=7) | |
| pc.Exporter.save_image(frame_layer, output_dir / "10_particular_layer_mask_logo.png") | |
| print(f"Saved: {output_dir / '10_particular_layer_mask_logo.png'}") | |
| print("\nAll Trapcode Particular demos generated successfully!") | |