particri / examples /08_reference_replica_grid.py
ArifiIslam's picture
Release Particri v1.0.0 - High-Performance C++ & Python Particle Engine
b234338 verified
Raw History Blame Contribute Delete
5.81 kB
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
def create_checkerboard(w: int, h: int, grid_size: int = 16) -> Image.Image:
"""Creates a transparent checkerboard background like Photoshop."""
img = Image.new("RGBA", (w, h), (200, 200, 200, 255))
draw = ImageDraw.Draw(img)
for y in range(0, h, grid_size):
for x in range(0, w, grid_size):
if (x // grid_size + y // grid_size) % 2 == 0:
draw.rectangle([x, y, x + grid_size, y + grid_size], fill=(240, 240, 240, 255))
return img
def main():
print("Synthesizing Complete Multi-Panel Reference Replica...")
out_dir = Path(__file__).resolve().parent.parent / "output"
out_dir.mkdir(exist_ok=True)
panel_w, panel_h = 480, 270
scale = panel_w / 1920.0 # 0.25 scale factor
# 1. Panel 1: Light Streaks
e1 = particri.Presets.light_streaks(width=panel_w, height=panel_h, density=0.8, seed=303)
e1.warmup(1.5)
p1_rgba = e1.render(bloom=True, bloom_intensity=0.8, bloom_radius=5)
img1 = Image.new("RGBA", (panel_w, panel_h), (2, 8, 12, 255))
img1.paste(Image.fromarray(p1_rgba), mask=Image.fromarray(p1_rgba).split()[3])
# 2. Panel 2: Golden Sparkles on Checkerboard
e2 = particri.ParticleEngine(max_particles=10000, width=panel_w, height=panel_h)
e2.add_curl_noise(seed=42, strength=25.0, frequency=0.005, speed=0.15)
e2.add_brownian(10.0, seed=43)
# Bokeh
e2.add_emitter(
shape=particri.EmitterShape.Box,
position=(panel_w * 0.5, panel_h * 0.5),
size=(panel_w, panel_h),
rate=40.0,
speed_range=(3.0, 10.0),
size_start_range=(5.0, 12.0),
size_end_range=(1.0, 4.0),
color_start=(1.0, 0.85, 0.38, 0.85),
color_end=(1.0, 0.65, 0.15, 0.0),
particle_shape=particri.ParticleShape.Bokeh,
seed=50,
)
# Stars
e2.add_emitter(
shape=particri.EmitterShape.Box,
position=(panel_w * 0.5, panel_h * 0.5),
size=(panel_w, panel_h),
rate=35.0,
speed_range=(4.0, 15.0),
size_start_range=(10.0, 24.0),
size_end_range=(0.0, 3.0),
color_start=(1.0, 0.95, 0.75, 1.0),
color_end=(1.0, 0.55, 0.1, 0.0),
particle_shape=particri.ParticleShape.Star4,
twinkle_speed_range=(4.0, 14.0),
seed=60,
)
e2.warmup(1.5)
p2_rgba = e2.render(bloom=True, bloom_intensity=0.7, bloom_radius=5)
img2 = create_checkerboard(panel_w, panel_h, grid_size=12)
img2.paste(Image.fromarray(p2_rgba), mask=Image.fromarray(p2_rgba).split()[3])
# 3. Panel 3: Starburst Cluster on Checkerboard
e3 = particri.ParticleEngine(max_particles=10000, width=panel_w, height=panel_h)
e3.add_drag(0.3)
e3.add_curl_noise(seed=101, strength=20.0, frequency=0.006, speed=0.2)
# Concentrated center starburst
e3.add_emitter(
shape=particri.EmitterShape.Circle,
position=(panel_w * 0.5, panel_h * 0.5),
size=(35.0, 35.0),
rate=90.0,
speed_range=(5.0, 35.0),
size_start_range=(8.0, 18.0),
size_end_range=(0.0, 2.0),
color_start=(1.0, 0.98, 0.88, 1.0),
color_end=(1.0, 0.65, 0.2, 0.0),
particle_shape=particri.ParticleShape.Star8,
twinkle_speed_range=(6.0, 20.0),
radial_velocity=True,
seed=110,
)
# Outer sparkles
e3.add_emitter(
shape=particri.EmitterShape.Circle,
position=(panel_w * 0.5, panel_h * 0.5),
size=(70.0, 70.0),
rate=70.0,
speed_range=(5.0, 20.0),
size_start_range=(5.0, 12.0),
size_end_range=(0.0, 2.0),
color_start=(1.0, 0.88, 0.45, 1.0),
color_end=(1.0, 0.5, 0.1, 0.0),
particle_shape=particri.ParticleShape.Star4,
twinkle_speed_range=(4.0, 14.0),
radial_velocity=True,
seed=120,
)
e3.warmup(1.5)
p3_rgba = e3.render(bloom=True, bloom_intensity=0.75, bloom_radius=5)
img3 = create_checkerboard(panel_w, panel_h, grid_size=12)
img3.paste(Image.fromarray(p3_rgba), mask=Image.fromarray(p3_rgba).split()[3])
# 4. Panel 4: Cosmic Nebula
e4 = particri.Presets.cosmic_nebula(width=panel_w, height=panel_h, density=0.8, seed=202)
e4.warmup(2.0)
p4_rgba = e4.render(bloom=True, bloom_intensity=0.8, bloom_radius=5)
img4 = Image.new("RGBA", (panel_w, panel_h), (4, 2, 10, 255))
img4.paste(Image.fromarray(p4_rgba), mask=Image.fromarray(p4_rgba).split()[3])
# Stitch top row: 4 panels
spacing = 8
top_w = panel_w * 4 + spacing * 3
top_h = panel_h
# Bottom banner: Glitter field
e_bot = particri.Presets.glitter_field(width=top_w, height=120, density=1.5, seed=404)
e_bot.warmup(1.5)
bot_rgba = e_bot.render(bloom=True, bloom_intensity=0.8, bloom_radius=6)
img_bot = Image.new("RGBA", (top_w, 120), (14, 10, 8, 255))
img_bot.paste(Image.fromarray(bot_rgba), mask=Image.fromarray(bot_rgba).split()[3])
# Canvas
total_w = top_w + 32
total_h = top_h + 120 + spacing + 32
canvas = Image.new("RGBA", (total_w, total_h), (25, 27, 34, 255))
# Paste top 4 panels
canvas.paste(img1, (16, 16))
canvas.paste(img2, (16 + panel_w + spacing, 16))
canvas.paste(img3, (16 + (panel_w + spacing) * 2, 16))
canvas.paste(img4, (16 + (panel_w + spacing) * 3, 16))
# Paste bottom banner
canvas.paste(img_bot, (16, 16 + panel_h + spacing))
showcase_path = out_dir / "reference_replica_showcase.png"
canvas.save(str(showcase_path))
print(f"Saved complete reference replica showcase to: {showcase_path}")
if __name__ == "__main__":
main()