polywright 是做什么的?
3D模型工作的中心枢纽。它决定模型如何制作,将每个资产保存在一个带清单的文件夹中,并用数字和图片验证每一步。子技能包含深度细节。
脚本:此技能文件夹中的 scripts/pw.py(Python 3.9+,标准库,每个命令一个JSON对象;scripts/pw_bpy.py 是其Blender部分,切勿手动运行)。
每次会话运行一次 python <此文件夹>/scripts/pw.py doctor:它会找到Blender(任何操作系统)、Python网格库、切片器及ComfyUI主机,并报告缺失项。完整命令列表:references/cli.md。
第一步:简报(只问无法推断的内容)
- 什么:物体或地点,真实的或想象的,以及它的可识别程度。
- 目标:
pw.py check --list中的一个或多个(game-roblox, game-unity, game-unreal, web-threejs, ar-usdz, commerce-gltf, print-fdm, print-resin, video-blockout, cad-step)。目标设定预算。 - 实际尺寸(以米为单位):长凳长1.8米;人身高1.7至1.8米。错误的比例是最常见的静默错误;
check --real-size-m可捕捉它。 - 输入:提示词、照片、草图、测量值、地图位置、现有网格。
- 保真度和预算:块体布局、游戏就绪、英雄;托管生成器可能消耗多少时间或金钱。
搭建:pw.py new <dir> --name <Name> --kind real|imagined|hybrid --route <route> --targets a,b --real-size-m X。
文件夹:refs/(参考文件,每条记录为一个来源),work/(.blend、中间文件),out/(每个目标一个交付物),renders/(审阅图表),brief.md,manifest.json。其他插件的契约:references/contract.md。
第二步:选择路径(满足简报的最便宜方式)
| 情况 | 路径 | 技能 |
|---|---|---|
| 常见物体;许可证允许复用 | 查找:Poly Haven、Kenney、Quaternius(CC0)、Sketchfab及打印站点(检查每份许可证) | 本技能,references/routes.md |
| 有尺寸、配合部件、锐利边缘(支架、机箱、建筑、家具) | 编写代码(--route procedural):bpy、build123d/CadQuery/OpenSCAD | polywright-generate、polywright-blender |
| 真实地点(公园、街道、校园、地形) | 地点:OSM + 高程(pw.py place) | polywright-capture |
| 可拍照或扫描的真实物体 | 捕捉:摄影测量、splat、扫描仪或按测量值建模 | polywright-capture |
| 想象中的有机物体或一次性物体(雕像、生物、道具) | 生成:参考图,然后图转3D | polywright-references、polywright-generate |
| 变形的英雄角色 | 生成或雕刻为基础,然后重拓扑和绑定 | polywright-generate、polywright-finish |
大多数好的结果混合了路径:一个OSM公园配上生成的英雄道具,一个代码构建的房子配上生成的雕像。在清单中记录每个部件的路径。
第三步:几何之前先有参考
对于任何不是现成找到的东西,先收集或生成参考(polywright-references):在共享地平线上带有高度标尺的正交视图、材质样本、比例参考。生成的输入决定了图转3D结果的大部分。
第四步:构建,然后验证(每条路径)
- 先进行块体布局:按真实尺寸用基本体确定轮廓和比例。在此处修正比例;现在成本很低。
- 数值:
pw.py inspect <file>:三角形数、对象数、尺寸、材质、纹理、UV、水密性、部件数。在每个破坏性步骤前后读取它。 - 图片:
pw.py render <file> --out renders/<step>:六个视图和一个sheet.png。读取图表,而不是六张截图。与参考图对比:轮廓、比例、缺失或漂浮的部件、着色尖峰、错误的轴(侧躺)、错误的比例。 - 目标:
pw.py check <file> --target <t> --real-size-m X。失败意味着在交付前修复;警告意味着在交接中说明。 - 记录:
pw.py manifest <dir> --add-output out/<file> --target <t> --inspect,每个来源使用--add-source <url> --licence <l> --author <a>,然后--validate。
计划、执行和批评是独立的步骤:构建后,像批评家一样看图表,列出缺陷后再声称完成。值得修复两次回溯;之后,重新考虑方法。每个里程碑保存一个带编号的 .blend(work/<name>_v03.blend),以便长时间工作可以从磁盘重启。
将模型合成到图片中
当图像或视频模型不断错误绘制设计好的道具(分镜图、场景参考、海报)时,从图片中提取构图,从模型中提取形状:
- 仅选择用于构图的图片:人物站立位置、光线、目的。一个简单的替代道具即可。
pw.py match model.blend --still pic.png --out work/match.png --anchor-px X,Y --anchor-local=X,Y,Z --aim-px X,Y --aim-local=X,Y,Z --depth M --horizon ROW --hide BOX --mask-add BOX:模型的锚点(手柄)落在手上,目标点(尖端)落在精确像素上,使用图片的镜头和地平线渲染RGBA。设置--depth使其宽度像素与替代品匹配(宽度 = f_px x 直径 / 深度;f_px在结果中)。--hide将部件放在手后面;--mask-add将手添加到遮罩中。- 以3倍裁剪读取
match_paste.png:形状、在画面中的大小、目标点。修正深度和像素,重新运行(几秒钟)。 - 在
match_mask.png内使用低去噪图像编辑(FLUX.2 Klein 或任何内绘模型:去噪0.3至0.5,低cfg)进行混合,然后通过遮罩将结果贴回,使外部的每个像素保持图片原始状态。全图编辑会重绘所有内容(HDR颜色、更大的道具)。 - 以全尺寸检查;保留两个或更多种子。
道具的参考图也来自模型(polywright-references,第2b步)。
从模型生成游戏精灵
当图像模型在游戏精灵中不断搞错机械结构(不圆的轮子、屋顶上的叶片)时,构建模型,通过游戏自身的相机渲染它,并让图像模型仅负责上色:
pw.py spritecam <registry.json> --like <sprite> --out camera.json:根据游戏的地面菱形(L-014)拟合正交相机。设置其中的tile_m为模型的每瓷砖米数。- 使用每个对象的部分前缀(
wheel_、roof_...)构建模型,放在场景属性sprite_parts中,运动部件放在以枢轴空间构建的枢轴空对象下,运动放在场景属性loop中。 pw.py sprite model.blend --camera camera.json --out renders/L1 --scale 10.6667(1024像素对应96像素的精灵):以sheet样式读取通道和最终渲染,与游戏精灵1:1对比;--frames N --frame-passes id,pos用于动画部件,--hide wheel_用于去掉轮子的图板。 然后在上色前检查大小是否与游戏中的邻居匹配:aw.py sprite <96像素的最终渲染> --refs <同类精灵>如果覆盖率低于它们中位数的0.9则失败。菱形拟合设定了地面比例,而不是建筑看起来有多大:首先添加体量和道具(更高的墙、披屋、院子),然后提高px_per_tile并移动footprint_centre_px,使边界框像邻居一样跨越画布(L-016)。避免圆柱体轮廓上的细梁:斜坡导轨上的水平原木看起来像是穿过它们上方和下方(L-017)。- 使用粘土材质的Canny边缘作为控制(带有ControlNet的图像模型)对最终渲染上色,用渲染的alpha通道裁剪,使框架和
groundBase保持精确,然后根据sprite.json中的ID和边缘数据检查上色效果。
从模型生成场景插画
加载屏幕、关键艺术或封面,围绕已存在的模型(建筑、机器)构建场景,让图像模型上色,以确保机械结构和布局正确。
- 在模型中用场景属性
scene_parts中每个对象的部分前缀构建场景,轮子和圆盘放在rings中,关键点或路径放在scene_points中。沿路径的堤岸、堤坝和墙壁每个都是一个sweep(在pw.py bpy脚本中从scripts/pw_scene.py导入),而不是一排盒子(L-020)。 pw.py framecam problem.json --out cameras.json:包含屏幕框的世界点、保持在画面内且不遮挡UI文本区域的关键点、要最大化的尺寸度量;打印最佳相机作为预设。从实际UI文件中获取文本区域(其内边距和锚点),而不是经验法则(L-018)。pw.py scene scene.blend --cameras cameras.json --camera framecam_1 --out renders/v1 --size 1280x720(上色工作流的首遍大小):粘土、最终渲染、深度、法线、ID、线条和scene.json。首先读取粘土和深度;除非预设需要固定,否则将深度范围留给场景自身的测量(L-019)。- 使用控制(深度或线条)上色,然后根据
scene.json门控上色:环边缘、点、ID颜色。
人群和战斗块体布局(AI视频)
视频模型处理人群有困难;Blender不会。让Blender布置军队,让视频模型绘制外观:
pw.py crowd --out work/crowd --action clash --preview(或march、advance、charge、hold;--view、--lens、--move),然后读取work/crowd/sheet.png。- 删除
--preview以生成完整镜头:depth.mp4(主要控制)、pose.mp4(前排)、mask.mp4、clay.mp4、camera.json;默认832x480,81帧,16 fps(Wan)。 - 将粘土第一帧重绘为已批准的起始静帧;使用深度视频和该静帧驱动 Wan VACE 或 Wan 2.2 Fun Control。提示词描述服装、每侧颜色、光线和雾霾,而不是人数。
详细信息和未测试内容:references/crowd-blockouts.md。镜头规划属于cinewright。
两名战士:pw.py duel shot.json --preview 将两个人体模型摆放在场景中的标记位置,通过镜头的相机(examples/duel.json);读取 sheet.png,然后删除 --preview 以生成每个控制的mp4。更多信息:crowd-blockouts.md,“两名战士”。
小规模的真实人物或玩具演员(交换了边、额外角色、标记丢失):从照片中每个网格化,使用 pw.py mark 修复颜色和绘制标记,给视频模型提供 pw.py turnaround 图片作为参考,以及 pw.py lineup(团队在固定侧、深度和遮罩)作为开场:references/figures-for-video.md。
电影镜头的场景和道具:references/film-and-video.md。
第五步:完成和交接
每个目标的完成(UV、LOD、法线贴图约定、轴和单位转换、压缩)属于polywright-finish;打印(水密实体、墙壁、底座、拆分、3MF)属于polywright-print。将文件夹交给使用它的插件:three.js页面(threewright)、电影和视频(cinewright)、Roblox场所(roblox-agent)、Unity项目(unity-agent)、打印设置用的打印机特定或切片器技能、更多图片用的图像技能。它们读取 manifest.json 和 out/。
交接消息:
Model: <名称> (<路径>) -> out/<文件> for <目标>: <三角形数> tris, <尺寸> m, <水密/部件数>
Check: <目标> pass|warn (<规则>) Review: renders/<步骤>/sheet.png
Sources: <数量> 带许可证; AI-made parts: <哪些, 哪个模型> Owed: <未完成的内容>
规则
- Blender和glTF中的实际尺寸以米为单位(Blender中+Z向上,glTF中+Y向上);仅在打印文件中使用毫米。
- 切勿仅凭文件名或生成器的说辞就认为网格是好的:检查、渲染、验证。
- 每个下载或生成的输入都包含一条带许可证的来源记录。商店和打印站点(Fab、Unity Asset Store、Sketchfab、MakerWorld、Printables、Steam)要求披露AI生成内容;清单会记录。
- Blender通过MCP桥接运行任意Python:优先在副本上使用
pw.py bpy;仅当用户监督时才使用实时MCP会话(polywright-blender)。 - Google Photorealistic 3D Tiles 可以查看,但绝不可导出、缓存或追踪(遵循其条款)。
维护
Evergreen单元,fast层级(生成器和Blender每月更新)。伴侣文件:RESEARCH.md、CHANGELOG.md、LEARNINGS.md、TESTS.md(带evals/evals.json)、MAINTENANCE.md、状态在 evergreen.json 中。每次使用时读取 evergreen.json;如果到期,先完成任务,然后刷新(evergreen-refresh)。在发生时就写入LEARNINGS.md。