shadow-puppet-animation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

皮影戏动画(代码生成)

Shadow Puppetry Animation (Code-Generated)

适用:用户想做一段皮影戏动画(历史串讲、故事短片等),要求“皮影要精致”、有字幕和配乐,最终要能播放和下载。
整体流程(按顺序,每步都有用户确认点):
  1. 写逐镜头脚本(Docs 文档)
  2. 定画风:程序渲染 1–2 张样张给用户确认
  3. 全片编排:逐幕画面 + 字幕
  4. 逐镜头审片:重点查遮挡
  5. 配乐:采样乐器离线混音
  6. 交付:网页播放器(Artifact)+ MP4 视频

Applicable: When the user wants a shadow puppetry animation, such as a historical explainer or story short, with the requirement that “the shadow figures must be exquisite,” along with subtitles and music, and a final result that can be played and downloaded.
Overall workflow (in order, with a user confirmation checkpoint at every step):
  1. Write a shot-by-shot script (Docs document)
  2. Establish the visual style: have the program render 1–2 sample images for user approval
  3. Arrange the full film: act-by-act visuals + subtitles
  4. Review every shot, with particular attention to occlusion
  5. Add music: mix sampled instruments offline
  6. Deliver: web player (Artifact) + MP4 video

1. 脚本:必须逐镜头,不能只写分幕概述

1. Script: It Must Be Shot by Shot, Not Just a Summary of Each Act

用户若给了参考视频,先用 ffmpeg 抽帧(
fps=1,tile=4x2
)和裁出字幕条看清它的结构,再动笔。
脚本写成 Docs 文档,包含:
  • 作品概况表(片名、时长、镜头数、视觉参考、叙事方式、主线意象)。
  • 贯穿角色:一个好奇的小角色(提问、惊叹)+ 一个引路者(讲述)。字幕一律是“角色名 + 台词”,不用脱离画面的旁白。
  • 每一幕:标题行带时间段,下面先写「本幕音乐」(主奏乐器、调式、BPM/拍子、情绪、参考曲),再写镜头表:镜号 | 时间 | 镜头景别 | 画面与皮影动作 | 字幕(角色 · 台词)| 音效。
  • 字幕每条不超过约 22 字,停留时间不少于 2 秒。
  • 历史人物尽量用真实名句;编写的台词在回复里说明是戏剧化处理。
  • 首尾呼应的意象(如灯的点亮与熄灭、月亮的盈缺)。
3 分钟大约 14 幕、50 个镜头。
If the user provides a reference video, first use ffmpeg to extract frames (
fps=1,tile=4x2
) and crop out the subtitle bar to understand its structure before writing.
Write the script as a Docs document containing:
  • A production overview table: title, duration, shot count, visual references, narrative approach, and central imagery.
  • Recurring characters: one curious little character who asks questions and exclaims, plus one guide who tells the story. Subtitles should always use “Character Name + Dialogue,” with no narration detached from the action on screen.
  • Each act: a title line with its time range, followed first by “Music for This Act” (lead instrument, mode, BPM/meter, mood, reference track), and then a shot table: Shot No. | Time | Shot Size | Visual and Shadow Puppet Action | Subtitles (Character · Dialogue) | SFX.
  • Each subtitle should be no longer than approximately 22 Chinese characters and remain on screen for at least 2 seconds.
  • For historical figures, use authentic quotations whenever possible. Clearly identify any invented dialogue as dramatized in the response.
  • Use imagery that bookends the piece, such as a lamp lighting and going out or the waxing and waning of the moon.
A 3-minute film should have approximately 14 acts and 50 shots.

2. 画风:先出样张,用户确认后再做全片

2. Visual Style: Produce Sample Images First and Wait for Approval Before Creating the Full Film

皮影 ≠ 扁平彩色矢量人物。 用户会拿真实皮影照片纠正。要点:
  • 幕:一块纯色透光橙黄幕布,中央是油灯热点,四角压暗(radial gradient + 纸纹 overlay + 暗角)。不要画写实山水背景。
  • 皮子:以深色牛皮为底,红、绿、黄、蓝只是半透明染色块,颜色要偏深(如红 #7a120a、绿 #114428、黄 #946414)。
  • 真镂空:花纹是刻穿的孔,透出后面的幕光。做法是给每种“颜色 × 纹样”生成一个 CanvasPattern 贴图:先填染色,再在孔的位置描一圈深色刀口,最后用
    destination-out
    刻穿。纹样包括 flower、lattice、stripe(百褶)、tri(锯齿)、cloud、wave、scale、coin、dense。
  • 阳刻边线:每块皮子 clip 到自身路径后,依次描三道:深色宽线(bw×2)→ 透光细缝(bw×1.25)→ 深色(bw×0.95),形成“深-亮-深”的双线边,外缘再描一道墨线。
  • 比例:身形修长,头身比约 1:9(全身约 470 单位)。躯干窄直,下裳加百褶裙摆、蔽膝前襟、腰带玉佩流苏;女角加云肩、披帛、水袖。
  • 空脸:脸部刻空,只留侧面轮廓线(额头到鼻梁近乎一条线,用 bezier 画平滑),脸内基本透明。帝王、武将可用“实脸”(填深色,眉眼用透光色描)。
  • 眼睛必须精致:不能用等粗线条。
    • 柳叶眉 / 剑眉做成两头尖、中间厚的填充形。
    • 丹凤眼的上眼睑是填充形:内眼角细、中段粗、眼尾上挑入鬓,上方加一道细双眼皮线,下眼睑用细线。
    • 黑瞳贴着上睑,瞳上刻一个透光高光点。
    • 补鼻翼、唇线;女角加红唇和额间花钿;鬓角加发丝刻线。
    • 每次都单独渲染一张放大近景给用户检查眉眼。
  • 头饰:凤冠、冕旒、软脚幞头、展脚幞头/乌纱、方巾、双丫髻、盔+翎子、戏曲盔头等,都用镂空皮子画。
  • 关节与签子:关节处画铆钉(深色圆 + 透光小孔);每个人偶画三根签子(脖颈一根、两手各一根),斜伸到幕下画外。
  • 景片:楼阁、树、祥云、船、城门等同样是镂空皮子刻法。离幕的远景画到半分辨率缓冲上再模糊、调淡,表现“离幕变虚”。
  • 幕后柔影:所有皮影先画到一个 layer,把 layer 缩小到 1/4、
    source-in
    染深,放大后错位一点画在下面当作柔影,再叠上 layer。不要对整幅用
    ctx.filter blur
    ,太慢。
  • 字幕条:深褐色渐变横条,两端金色卷草和火焰纹;角色名用金色、台词用米白色,字体用 Noto Serif SC。
样张的做法:选一个代表性镜头(例如李白邀月)渲染全景一张、近景一张,用 SendUserFile 发出,并列出可调的项(明暗、花纹密度、身形瘦长),等用户确认后再往下做。
Shadow puppetry ≠ flat, colored vector characters. Users may correct the result by comparing it with real shadow puppet photographs. Key points:
  • Screen: a solid, translucent orange-yellow screen with an oil-lamp hotspot in the center and darkened corners (radial gradient + paper texture overlay + vignette). Do not paint realistic landscape backgrounds.
  • Leather: use dark cowhide as the base. Red, green, yellow, and blue should appear only as translucent dyed areas and should remain dark, such as red
    #7a120a
    , green
    #114428
    , and yellow
    #946414
    .
  • True cutouts: the patterns are holes cut all the way through, allowing the light from the screen to show through. For each color × pattern combination, generate a CanvasPattern texture: first fill in the dye, then trace a dark knife edge around each opening, and finally cut through the holes with
    destination-out
    . Patterns include flower, lattice, stripe (pleats), tri (zigzag), cloud, wave, scale, coin, and dense.
  • Yang-carved outlines: after clipping each piece of leather to its own path, draw three strokes in sequence: a wide dark line (
    bw×2
    ) → a thin translucent slit (
    bw×1.25
    ) → a dark line (
    bw×0.95
    ). This creates a dark–light–dark double outline. Add one more ink line around the outer edge.
  • Proportions: use slender figures with a head-to-body ratio of approximately 1:9 (about 470 units tall). The torso should be narrow and straight. The lower garment should have a pleated skirt hem, a front lapel covering the knees, and a belt with a jade pendant and tassels. Female characters should have cloud shoulders, a flowing shawl, and water sleeves.
  • Open face: carve out the face and retain only the side-profile contour, from the forehead to the bridge of the nose as an almost continuous line smoothed with bezier. The interior of the face should remain mostly transparent. Emperors and military figures may use a solid face, with the brows and eyes traced in translucent color.
  • The eyes must be exquisite; do not draw them with lines of uniform thickness.
    • Render willow-leaf eyebrows and sword eyebrows as filled shapes that taper at both ends and are thicker in the middle.
    • For phoenix eyes, make the upper eyelid a filled shape: thin at the inner corner, thickest in the middle, and sweeping upward into the temple at the outer corner. Add a fine double-eyelid line above it and a thin lower-eyelid line.
    • Place the black pupil against the upper eyelid and cut out a translucent highlight inside it.
    • Add the nostril and lip contours. Female characters should have red lips and a forehead huadian, with fine hair-strand cuts at the temples.
    • Render a separate enlarged close-up of the brows and eyes for the user to inspect every time.
  • Headwear: phoenix crowns, mianliu, soft-foot futou, winged futou or wusha, square headscarves, double buns, helmets with plumes, and opera headdresses should all be rendered as cut-out leather.
  • Joints and control rods: draw rivets at the joints (a dark circle with a small translucent hole). Give each puppet three control rods: one at the neck and one in each hand, extending diagonally down beyond the bottom edge of the screen.
  • Scenery pieces: pavilions, trees, auspicious clouds, boats, and city gates should use the same cut-out leather treatment. Render distant scenery to a half-resolution buffer, then blur and fade it to create the effect of objects receding into the distance.
  • Soft shadows behind the screen: first draw all shadow puppets onto a layer, scale that layer to 1/4, darken it with
    source-in
    , then enlarge and offset it slightly beneath the main layer to create a soft shadow. Do not apply
    ctx.filter blur
    to the entire image because it is too slow.
  • Subtitle bar: use a dark-brown gradient bar with gold scrollwork and flame motifs at both ends. Set character names in gold and dialogue in off-white, using Noto Serif SC.
How to create the samples: select a representative shot, such as Li Bai Inviting the Moon, and render one full shot and one close-up. Send them with SendUserFile, list the adjustable options, such as lighting, pattern density, and body slenderness, and wait for the user's approval before continuing.

3. 全片编排(Canvas 2D,1920×1080)

3. Full-Film Arrangement (Canvas 2D, 1920×1080)

文件结构(最后拼接成单个 HTML):
  • core.js
    :数学工具、纸纹、暗角、光尘、火焰、字幕条。
  • puppet.js
    :镂空皮料、人偶装配、头茬、帽冠、手持道具。
  • scenery.js
    :幕布、远景模糊层、人偶层、屋顶、楼阁、树、云、月、投影。
  • props.js
    :各朝代的景片和道具。
  • acts.js
    :角色预设表 CH、每幕的 draw(ctx, 幕内时间, 全局时间)、字幕表 SUBS。
  • engine.js
    :按时间取幕、幕间 0.5 秒交叉淡化、后期处理、字幕。
编排要点:
  • 人偶的姿态参数:手臂角度(从下垂算起,向前为正)、肘弯、头部倾角、身体前倾、走路相位。用
    mk(base, override)
    合并角色预设。
  • 渲染必须是时间的纯函数(粒子用 hash),这样可以任意跳转,也能逐帧导出。
  • 用无头 Chromium(Playwright)调用
    renderAt(t)
    截图,按每 3 张拼成一张总览图来检查。
File structure, eventually assembled into a single HTML file:
  • core.js
    : math utilities, paper texture, vignette, dust motes, flames, and subtitle bar.
  • puppet.js
    : cut-out leather, puppet assembly, head pieces, hats and crowns, and handheld props.
  • scenery.js
    : screen, blurred distant layer, puppet layer, rooftops, pavilions, trees, clouds, moon, and projections.
  • props.js
    : scenery pieces and props for each dynasty.
  • acts.js
    : character preset table
    CH
    , each act's
    draw(ctx, act-local time, global time)
    , and subtitle table
    SUBS
    .
  • engine.js
    : select the act by time, apply a 0.5-second crossfade between acts, and handle post-processing and subtitles.
Arrangement guidelines:
  • Puppet pose parameters include arm angle (measured from hanging downward, with forward being positive), elbow bend, head tilt, forward body lean, and walking phase. Use
    mk(base, override)
    to merge character presets.
  • Rendering must be a pure function of time. Use a hash for particles so the animation can be seeked to any point and exported frame by frame.
  • Use headless Chromium (Playwright) to call
    renderAt(t)
    and take screenshots. Combine every three frames into a single overview image for review.

4. 审片:遮挡规则(用户明确提过这个问题)

4. Review: Occlusion Rules (the User Has Explicitly Raised This Issue)

每个镜头的中点各渲染一帧,逐张检查:
  • 人物背后只能是空幕,或者模糊变淡的远景。深色建筑或景片压在人物身后,会显得人被挡住或融在一起。
  • 建筑放到两侧或远景层;人物之间、人物与道具之间要留出间距;行走的路线要错开。
  • 不要用 clip 把人物下半身藏进车里、骆驼上或马背上(用户会认为是被遮挡)。改成人物站在车台上,或者在牲口前面步行。
  • 两组以上人物同框时,检查整个时间段内会不会走到一起重叠。
Render one frame at the midpoint of every shot and inspect each one:
  • Behind a character, there should only be an empty screen or blurred, faded distant scenery. A dark building or scenery piece placed behind a character can make the character appear blocked or visually merged with it.
  • Place buildings on either side or in the distant layer. Leave space between characters and between characters and props. Offset their walking paths.
  • Do not use clip to hide a character's lower body inside a cart, camel, or horse, because users interpret this as occlusion. Instead, have the character stand on the cart platform or walk in front of the animal.
  • When more than one group of characters shares the frame, check whether they will walk into each other and overlap at any point during the shot.

5. 配乐:用采样乐器,不要振荡器硬合成

5. Music: Use Sampled Instruments Instead of Harsh Oscillator Synthesis

用 WebAudio 振荡器合成的民乐,用户评价“不好听”。正确做法:
  1. 从 GitHub 下载 MIDI.js 音源(MusyngKite 质量较好),每个音一个 mp3:
    https://raw.githubusercontent.com/gleitz/midi-js-soundfonts/gh-pages/MusyngKite/<乐器>-mp3/<音名>.mp3
    音名写作 C4、Db4、Eb4……,只下载需要的音区,用
    xargs -P 16
    并行。
  2. 乐器对照:
    • 板胡、京胡 → fiddle;二胡 → violin;马头琴 → cello
    • 埙 → ocarina;箫 → shakuhachi;笛子 → flute;骨笛、羌笛 → pan_flute
    • 唢呐 → shanai;筚篥 → oboe;胡笳 → english_horn;笙 → reed_organ
    • 古筝、秦筝 → koto;琵琶、三弦 → shamisen(琵琶轮指用快速重复音);古琴 → acoustic_guitar_nylon(低八度,加滑音和吟猱)
    • 编钟 → tubular_bells;石磬 → kalimba
    • 战鼓 → taiko_drum;手鼓、羯鼓 → melodic_tom;拍板 → woodblock;驼铃 → agogo / tinkle_bell
    • 弦乐铺底 → string_ensemble_1;号角 → french_horn
    • 音效采样:seashore(水)、applause(喝彩)、gunshot(炮声)、bird_tweet
    • 锣、钹、火柴、裂纹等用 numpy 合成(非谐波分音、滤波噪声)。
  3. 用 Python(numpy + scipy)离线混音:
    • 用 ffmpeg 把每个 mp3 解码成 44.1k float32。
    • 这些采样都是固定 3.1 秒长。持续音超过长度时,用 0.45–2.2 秒段交叉淡化循环延长。
    • 用时变重采样做滑音(从下方滑入)和揉弦。
    • 每个乐器设置音量、声像、混响量;混响用 fftconvolve 和生成的指数衰减脉冲响应。
    • 最后高通、tanh 软限幅,再用
      ffmpeg loudnorm=I=-17:TP=-1.5
      。
  4. 写谱:用简谱字符串 DSL(
    3 5 6 1'- | 6 5 3 2--
    ,' 表示高八度、, 表示低八度、- 加一拍、_ 减半),配合
    mel()
    、
    arp()
    、
    perc()
    、
    roll()
    、
    tremolo()
    等函数。
  5. 编曲:
    • 全片一个主题动机贯穿(序幕独奏 → 高潮全奏 → 升调全奏 → 尾声独奏)。
    • 每幕三层:主奏旋律 + 伴奏(拨弦琶音或弦乐铺底)+ 打击乐。
    • 音乐卡点对齐画面事件(编钟逐个敲响、炮声、火箭等),整片只留一处 2 秒静默。
    • 用频谱图(ffmpeg showspectrumpic)和分段 RMS 检查各段电平是否均衡。
  6. 编码成 mp3(160k)后 base64 内嵌进页面。页面加载时就 decodeAudioData,播放时用 BufferSource.start(when, offset) 精确对齐画面;拖动进度时重新 start。
WebAudio oscillator-based synthesis of folk music was judged “bad-sounding.” The correct approach is:
  1. Download a MIDI.js soundfont from GitHub; MusyngKite provides better quality. Use one mp3 per note:
    https://raw.githubusercontent.com/gleitz/midi-js-soundfonts/gh-pages/MusyngKite/<instrument>-mp3/<note>.mp3
    Write note names as C4, Db4, Eb4, and so on. Download only the required registers and use
    xargs -P 16
    for parallel downloads.
  2. Instrument mapping:
    • Banhu and jinghu → fiddle; erhu → violin; matouqin → cello
    • Xun → ocarina; xiao → shakuhachi; dizi → flute; bone flute and qiangdi → pan_flute
    • Suona → shanai; bili → oboe; hujia → english_horn; sheng → reed_organ
    • Guzheng and qinzheng → koto; pipa and sanxian → shamisen; use rapid repeated notes for pipa tremolo; guqin → acoustic_guitar_nylon, one octave lower with slides and vibrato ornaments
    • Bianzhong → tubular_bells; shiqing → kalimba
    • War drums → taiko_drum; hand drums and jiegu → melodic_tom; clappers → woodblock; camel bells → agogo / tinkle_bell
    • String background → string_ensemble_1; horns → french_horn
    • Sound effects: seashore for water, applause for cheering, gunshot for cannon fire, and bird_tweet
    • Synthesize gongs, cymbals, match strikes, cracking sounds, and similar effects with numpy, using inharmonic partials and filtered noise.
  3. Mix offline with Python (numpy + scipy):
    • Use ffmpeg to decode every mp3 into 44.1k float32 audio.
    • All samples are exactly 3.1 seconds long. When a note needs to last longer, loop it using 0.45–2.2-second segments with crossfades.
    • Use time-varying resampling to create slides into notes and vibrato.
    • Set the volume, pan, and reverb amount for each instrument. Generate reverb using fftconvolve and a synthesized exponentially decaying impulse response.
    • Finally, apply a high-pass filter and tanh soft limiting, then run
      ffmpeg loudnorm=I=-17:TP=-1.5
      .
  4. Write the score using a numbered-notation string DSL (
    3 5 6 1'- | 6 5 3 2--
    ), where
    '
    indicates the higher octave,
    ,
    indicates the lower octave,
    -
    adds one beat, and
    _
    subtracts half a beat. Use functions such as
    mel()
    ,
    arp()
    ,
    perc()
    ,
    roll()
    , and
    tremolo()
    .
  5. Arrange the music:
    • Use one thematic motif throughout the film: prelude solo → full ensemble at the climax → full ensemble transposed upward → coda solo.
    • Give every act three layers: lead melody + accompaniment (plucked arpeggios or a string background) + percussion.
    • Align musical cues with visual events, such as bells chiming one by one, cannon fire, and rockets. Leave only one 2-second silence in the entire film.
    • Use a spectrogram (
      ffmpeg showspectrumpic
      ) and segmented RMS analysis to verify that the levels are balanced throughout.
  6. Encode the result as a 160k mp3 and embed it in the page as base64. When the page loads, call decodeAudioData. During playback, use
    BufferSource.start(when, offset)
    to align the audio precisely with the visuals, and restart the source when the user seeks.

6. 交付

6. Delivery

  • 网页播放器(Artifact):标题 + 16:9 画布 + 首帧海报(选一个好看的镜头,中间放“开始放映”大按钮)+ 控制条(播放/暂停、时间、带幕刻度的进度条、当前幕名、静音、全屏)+ 十四幕章节按钮。单一深色剧场风格,手机宽度下章节改为 2 列。
  • MP4:
    • 用 Playwright 多页并行导出帧:
      renderAt(f/30)
      后取 canvas 的
      toDataURL('image/jpeg', .92)
      。双核机器 5400 帧约 8 分钟。
    • 用 ffmpeg 合成:
      -c:v libx264 -crf 20 -pix_fmt yuv420p -c:a aac -movflags +faststart
      。
    • 1080p 约 115 MB,超过 SendUserFile 的 30 MB 上限。要另外两遍编码一个 720p 版:
      scale=1280:720
      ,视频
      -b:v 1150k
      ,音频 112k,约 28 MB,发给用户下载。
    • 告诉用户还有 1080p 高清版,需要的话可以分段发。
  • Web player (Artifact): title + 16:9 canvas + first-frame poster (choose an attractive shot and place a large “Start Playback” button in the center) + control bar (play/pause, time, progress bar with act tick marks, current act name, mute, fullscreen) + 14 act chapter buttons. Use a consistent dark theater style, and switch the chapter buttons to 2 columns at mobile widths.
  • MP4:
    • Export frames in parallel with multiple Playwright pages: call
      renderAt(f/30)
      , then obtain
      canvas.toDataURL('image/jpeg', .92)
      . On a dual-core machine, 5,400 frames take approximately 8 minutes.
    • Composite the frames with ffmpeg:
      -c:v libx264 -crf 20 -pix_fmt yuv420p -c:a aac -movflags +faststart
      .
    • The 1080p version is approximately 115 MB, exceeding SendUserFile's 30 MB limit. Run two additional encoding passes to produce a 720p version:
      scale=1280:720
      , video bitrate
      -b:v 1150k
      , and audio bitrate 112k, resulting in approximately 28 MB for delivery.
    • Tell the user that a 1080p HD version also exists and can be sent in segments if needed.

常见坑

Common Pitfalls

  • 对 layer 或人偶使用
    ctx.filter
    (blur、brightness)会让单帧耗时到数秒。模糊一律走“缩小缓冲 + 放大”或预渲染的 sprite(例如持签的手)。
  • 修改场景函数时,不要整段替换到文件末尾,否则会误删后面的函数(如 crescent)。每次构建后都要跑全片截图检查。
  • 预览环境连不上 Google Fonts,字体栈里要有本地兜底(Noto Serif CJK SC)。
  • 镜像翻转(scale(-1,1))带文字的景片时,文字会反过来,应该在另一侧单独再画一个。
  • Applying
    ctx.filter
    to a layer or puppet, such as blur or brightness, can make a single frame take several seconds. Always blur by downscaling a buffer and scaling it back up, or by using a pre-rendered sprite, such as a hand holding a control rod.
  • When modifying scene functions, do not replace an entire section through the end of the file, or later functions, such as
    crescent
    , may be accidentally deleted. After every build, run a full-film screenshot check.
  • If the preview environment cannot connect to Google Fonts, include a local fallback in the font stack, such as Noto Serif CJK SC.
  • Mirroring scenery that contains text with
    scale(-1,1)
    reverses the text. Instead, draw a separate version on the other side.

参考资料(references/ 目录)

References (
references/
Directory)

动手定画风之前,先用 Read 看一遍这些图:
  • references/皮影实物参考/
    :真实皮影照片,是画风的标准。
    • 01:持签操偶的女角,能看清签子的位置和透光效果。
    • 02:镂空透光的王冠女角,看百褶裙摆和空脸。
    • 03:双人对戏,楼阁和树是镂空景片。
    • 04:黑皮镂空的群像,以黑皮为主、刻工很密。
  • references/参考视频/
    :用户给的参考短片(暖金画面、带角色名的字幕条),以及它的抽帧图和字幕条截图。字幕条样式按这个来。
  • references/samples/
    :用户确认过的画面。
    • ref_01.png
      、
      ref_02.png
      :明暗和眉眼刻工按这两张来。
    • 第一版_偏亮_未采用.png
      :反例,整体太亮,眉眼太粗。
Before establishing the visual style, use Read to review all of these images:
  • references/皮影实物参考/
    : real shadow puppet photographs, which are the standard for the visual style.
    • 01: a female puppeteer holding control rods, clearly showing the rod positions and translucent-light effect.
    • 02: a female figure with a translucent cut-out crown, showing the pleated skirt hem and open face.
    • 03: a scene with two characters, where the pavilion and trees are cut-out scenery pieces.
    • 04: a group scene made primarily from black cut-out leather, with dense carving.
  • references/参考视频/
    : the user's reference short film, featuring warm gold visuals and a subtitle bar with character names, together with extracted frames and subtitle-bar screenshots. Match the subtitle-bar style to this reference.
  • references/samples/
    : visuals approved by the user.
    • ref_01.png
      and
      ref_02.png
      : follow these images for lighting, contrast, and the carving of the brows and eyes.
    • 第一版_偏亮_未采用.png
      : a rejected example. It is too bright overall, and the brows and eyes are too heavy.