본문으로 건너뛰기
cccskills
무료GitHub에 공개

falling-leaves

Build falling leaves or petals with visible front-and-back tumbling and sideways motion tied to rotation. Covers 2D canvas and 3D implementations, depth layers, particle density, rendering costs, and reduced-motion support.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

원문원문 설명 보기

Build falling leaves that read as leaves, with each one tumbling on its own axis so it presents a face, thins to an edge, and opens out again, and with its sideways slip driven by that same tumble. Covers the 2-D canvas build and the instanced-3-D variant, where leaves are recycled from, density-versus-count maths, depth layering, colour under a tone-mapped composite, reduced motion, and visibility pausing. Use for autumn maple, sakura petals, blossom, ash, snowfall shapes, or any drifting foliage where a generic particle field reads as confetti.

설치 방법 보기

이럴 때 유용합니다

  • Add autumn leaves to a web page
  • Animate drifting cherry blossom petals
  • Create layered foliage in a 3D scene
  • Provide a still composition for reduced motion

포함된 파일(5)

  • SKILL.md7.7 KB
  • agents/openai.yaml258 B
  • demo/index.html17.2 KB
  • demo/preview.jpg67.1 KB
  • demo/PROMPT.md2.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Falling Leaves

Make the falling thing read as a leaf. Reach for ambient-section-particles when you want a bounded atmosphere of generic motes. Reach for this when the shape has to be recognisable.

Build the tumble first

Turn each leaf about its own long axis so it shows its face, thins to nothing edge-on, then opens out on the other side. That instant of near-disappearance is what the eye reads as "leaf". A sprite that only spins in the picture plane reads as confetti, a coin, or a paper scrap, however good the artwork is.

On 2-D canvas the tumble is a horizontal scale that crosses zero:

ctx.save();
ctx.translate(l.x, l.y);
ctx.rotate(l.roll);              // long axis drifting in-plane
ctx.scale(Math.cos(l.spin), 1);  // the tumble: cos crosses 0, edge-on
ctx.globalAlpha = l.alpha;
ctx.drawImage(sprite, -w / 2, -h / 2, w, h);
ctx.restore();

Drive two axes, not one. roll turns the leaf within the picture plane; spin turns it through the plane. Give each its own rate per leaf, or the motion reads as mechanical however you ease it.

In 3-D, instance quads, never point sprites. A point sprite always faces the camera and can never turn away, so it can never go edge-on. That single constraint decides the whole implementation.

Couple the slip to the tumble

Drive lateral motion from the same angle as the tumble, ninety degrees out of phase. A leaf slides sideways when it knifes through the air edge-on and stalls when it presents its face flat:

l.x += Math.sin(l.spin) * l.slip * dt;   // fastest when cos(spin) ≈ 0
l.y += l.fall * dt;

Do not put an independent sine on x. It reads as wind or as an easing bug. This coupling costs one term and is what makes the path look aerodynamic.

Bake both faces

Bake two sprites per colour and pick by the sign of the tumble:

const img = Math.cos(l.spin) < 0 ? sprite.back : sprite.face;

Make the back duller and paler than the front. Without this the leaf reads as a flat cut-out spinning; with it, as a solid object with a front and a back. It is the cheapest realism in the system.

Vary every parameter per leaf

Randomise fall speed, tumble rate, roll rate, slip amount, phase, scale, and opacity at spawn. Share any one of them and the field stops being leaves and becomes a texture scrolling down the screen. The eye finds the common rhythm in about two seconds.

Choose where leaves come back from

This decides how many leaves are actually on screen.

In 2-D, recycle across the viewport. When a leaf passes the bottom, respawn it above the top at a new random x. Wrap x as well, so wind does not empty one side.

In 3-D, recycle ahead of the camera, not around it. A band centred on the camera spends nearly all its volume behind and beside the frustum; on a 36° camera, a couple of hundred leaves put barely a dozen in frame. Drop them into a disc hung down the camera's own sight line instead and the same count appears several times over:

camera.getWorldDirection(fwd); fwd.y = 0; fwd.normalize();
const cx = camera.position.x + fwd.x * AHEAD;
const cz = camera.position.z + fwd.z * AHEAD;
const a = Math.random() * TAU, r = Math.sqrt(Math.random()) * SPREAD;
l.x = cx + Math.cos(a) * r;  l.z = cz + Math.sin(a) * r;  l.y = camera.position.y + 16;

Keep a far wrap as a backstop for a camera that walks out from under its own weather, and put it well outside the fog so nothing is seen to jump.

Set density by band area, not by count

On-screen density goes as count ÷ band area. Tighten the band before raising the count:

  • Halving the recycle radius quadruples on-screen density at the same count.
  • Doubling the count doubles draw cost for the same on-screen gain.

Scale an authored count by viewport area rather than taking it literally, or a figure that reads as a drift on desktop arrives as a blizzard on a phone:

const k = clamp(Math.sqrt((W * H) / (1440 * 900)), .5, 1.3);
const n = Math.round(authored * layerShare * k);

Layer for depth

Use two or three layers, each with its own scale, speed, opacity, and blur:

layerscalefallopacitynote
far0.3–0.5slow0.22–0.40drawn first, may sit behind content
mid0.5–0.85medium0.46–0.78the body of the effect
near1.05–1.9fast0.50–0.82few, optionally blurred, drawn over content

Cross the near layer in front of the type. That crossing is the depth cue. Use two or three leaves there, not a curtain.

Handle colour and light

  • Sample each leaf from a small ramp — deep oxblood through vermilion to dry amber — and vary saturation per leaf. One red for every leaf is the giveaway.
  • Alpha-test rather than alpha-blend for 3-D leaves so they sort correctly at any angle without a per-frame depth sort.
  • An emissive red comes back out of a tone-mapped composite pink. If leaves self-illuminate in a dark scene, drive green and blue to zero (0x780200, not 0x8c1410), or the whole fall turns candy-coloured.

Budget the cost

The per-leaf update is free; a few hundred leaves of trigonometry does not register above a CPU profiler's sampling floor. The cost is fill and draw:

  • 2-D canvas: one drawImage per leaf. Pre-render the sprite once at the largest size you will draw. Never re-path the leaf per frame.
  • 3-D: one InstancedMesh, matrices composed into a shared Matrix4. Hoist scratch Matrix4/Quaternion/Euler/Vector3 to module scope.
  • Alpha-tested leaves lose early-Z, so they cost more per pixel than their triangle count suggests. Prefer more, smaller leaves to fewer huge ones.

Stop invisible work

  • Pause on document.hidden and when the section leaves the viewport (IntersectionObserver). Reset lastTime on resume so the first frame after does not integrate the whole pause.
  • Clamp dt to about 1/30 s so a stall does not teleport the field.
  • Cap device pixel ratio at 2.
  • Size from a ResizeObserver on the root element, not from a one-shot measurement at script time. A page laid out later leaves the canvas 0×0 forever, because the resize event it was waiting for has already fired.
  • Guard the build against a zero viewport. Controls that wire up by running once reach the builder before first layout and otherwise spawn the whole field stacked at the origin.

Respect the reader

Under prefers-reduced-motion: reduce, render one still, well-composed frame and do not animate. Do not simply hide the leaves; the composition was designed with them in it. Redraw that still when a control changes so the controls still do something.

Verify

  • Tumble crosses edge-on; leaves visibly thin and vanish once per turn
  • Slip is driven by the tumble angle, not an independent sine
  • Front and back faces differ
  • Every parameter varies per leaf
  • Recycle band is as tight as the composition allows before count goes up
  • 3-D: recycled ahead of the camera, not around it
  • 3-D: emissive reds have green and blue at zero
  • Count scales with viewport area; the readout reports what was actually built
  • Paused when hidden or off-screen; dt clamped; DPR capped at 2
  • A designed still frame under reduced motion
  • Console clean at 390px and 1440px

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Build woven fabric in Three.js with visible threads, realistic sheen, seams, and thick hems. The skill covers folds that preserve texture proportions, light passing through thin cloth, and variations in dye and wear.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Creating backlit curtains
  • Differentiating linen, silk, and wool
  • Adding hems and stitches for close-up views
MengTo/Skills6.9천2026년 10월 18일 업데이트

Build falling leaves in Three.js and similar 3D scenes, with visible front, edge, and back views as they tumble and drift. Coordinate wind, scene depth, camera-aware recycling, and performance checks for a convincing autumn effect.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Adding falling autumn leaves to a 3D scene
  • Coordinating leaf tumble, sideways drift, and wind
  • Managing leaves around buildings and camera movement
MengTo/Skills6.9천2026년 10월 18일 업데이트

Add coordinated seasonal transitions to an existing 3D scene. Blend foliage, lighting, sky, ground, snow, and particles from one shared state while preserving camera controls and interactions, so the same place remains recognizable throughout spring, summer, fall, and winter.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Add a four-season selector to an outdoor 3D scene
  • Show seasonal changes in an architectural walkthrough
  • Coordinate foliage, sunlight, sky, and ground appearance
MengTo/Skills6.9천2026년 10월 18일 업데이트

Create or integrate detailed 3D models with smooth outlines and believable edges for close-up views. Prepare lower-detail versions for distant viewing, prioritize loading, and measure rendering costs in the actual scene.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Creating a detailed 3D model for close-up views
  • Replacing visibly faceted curves with smoother geometry
  • Preparing detailed architectural assets for rendering
MengTo/Skills6.9천2026년 10월 18일 업데이트

Prepare detailed 3D materials that remain clear in close-up views. The skill guides texture resolution, physically based material maps, surface mapping, filtering, and progressive loading while checking download size and GPU memory use.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Prepare wood, stone, and fabric materials for close-up views
  • Fix texture seams, grain direction, and normal map orientation
  • Preserve floor and foliage detail at oblique or distant views
MengTo/Skills6.9천2026년 10월 18일 업데이트

Create realistic metal surfaces in Three.js by combining structured reflections, studio lighting, scratches, fingerprints, and beveled edges. Includes polished, brushed, and aged finishes for objects such as tools, rings, and metal product parts.

한국어 요약은 준비 중입니다. 영어 요약을 표시하고 있습니다.

  • Fixing metal that looks like gray plastic
  • Creating polished or brushed metal finishes
  • Adding patina and worn edges
MengTo/Skills6.9천2026년 10월 18일 업데이트

MengTo의 스킬 모두 보기

이 스킬의 문제 신고