# 食材方柱 Web 展示

入口：`/declarative-chart3d/model-experiments/food-texture-columns/web/`。沿用根目录 `serve.py`、Three.js 0.186.0 和共享实验导航，无需新增依赖或服务。

## 操作与支持范围

- 鼠标拖动旋转；滚轮、双指或 ± 按钮缩放。
- 参考、立体、俯视三种相机预设；视角复位只恢复相机。
- 六根柱体可单独查看，选中后自动居中并重新取景。
- 柱高范围 45%–150%；单选时只修改当前柱，全部模式统一设置六根。底部保持在地面。切回全部保留单柱修改。
- 排列间距 65%–140%，单柱模式下禁用。
- 自动旋转、照片色彩／影棚重新布光切换、恢复全部设置。
- 初始禁用控制，提供加载进度；GLB、纹理、WebGL 初始化或图形上下文错误会显示重试入口。

`column-controller.js` 显式实现层级查找、显示隔离、间距布局、底部锚定缩放、材质切换与复位；不依赖 Blender 脚本在 GLB 中执行。不含数据绑定、声明式接口注册、内部食材组织生成或拓扑重建。柱高使用 Y 轴缩放，纹理和倒角也会随高度一起拉伸，未实现恒定倒角或纹理物理尺度。

## 模型与材质迁移

`../blender/export_web.py` 经 Blender MCP 执行，只导出活动场景内选中的总根节点、6 个柱体根节点和6个网格，共13个节点、6个网格。相机、灯光、地面及其他场景不进入 GLB。Z-up 转换为 Y-up，保留底部原点、名称、父级、UV、法线；导出时应用倒角。原材质和选择状态在 finally 中恢复，不保存或覆盖 Blender 源工程。

GLB 内嵌一张 4096 × 1365 PNG 图集，取自原始参考图的降采样；另存 `assets/food-atlas.png` 方便检查。浏览器使用 GLTFLoader 加载内嵌图像，不依赖额外图片请求。原始照片仍保存在 `../blender/reference.png`。

Blender 的 Light Path、Mix Shader 和相机射线分支无法直接转成 glTF 标准材质。因此导出用图像纹理连接标准 Principled BSDF 的基础色；网页重新建立两种 MeshStandardMaterial 配置：

- **照片色彩**：基础色系数 0.12，发光纹理复用同一图集，强度 0.88。近似 Blender 对相机射线保留照片颜色的混合。Three.js 的发光不会向地面发射间接光。
- **影棚重新布光**：基础色系数 1，关闭发光；网页的主光、半球补光和 RoomEnvironment 共同照明。照片内已有阴影仍然存在，不能视为真实反照率。

网页统一控制正交相机、环境、主光、柔化阴影与接影平面。与 Blender Cycles 的光照积分和颜色响应存在差异；照片模式优先接近参考色彩。无法从单张参考恢复的背面、底面、内部结构限制沿用 Blender README。

## 文件与验证

- `index.html` / `style.css` / `app.js`：界面、响应式布局和 Three.js 场景。
- `column-controller.js`：可测试的模型交互逻辑。
- `assets/food-columns.glb`：独立模型；`model-info.json`：结构摘要。
- `assets/blender-preview.png`：首页封面与材质比较参考。
- `../tests/model.test.js`：真实 GLB 的导出范围、纹理尺寸、几何/UV、原点、隔离、柱高、间距、材质、复位和非法参数验证。Node 环境跳过图片解码，纹理像素尺寸直接检查二进制 PNG 头；浏览器实际验证纹理显示。
- 根目录 `tests/test_routes.py`：首页入口、直接访问、目录跳转、共享模块和模型资源。

运行：在根目录执行 `npm test`。单独模型检查：`node --test declarative-chart3d/model-experiments/food-texture-columns/tests/*.test.js`。

## 本次验收记录（2026-09-29）

- 全部 185 项 Node 模型／运行时测试通过；8 项 HTTP 路由测试通过。HTTP 测试因沙箱禁止绑定端口，改为在获准的沙箱外环境执行。
- 实际使用 Chrome 从首页卡片进入，并直接输入独立地址访问；看到 GLB 加载进度及成功状态、完整六柱纹理。
- 实测三文鱼单柱查看、柱高降至 46%、切回全部保留不同柱高、间距调至 140%、两种材质模式、三种视角、缩放、拖动旋转、自动旋转、视角复位与全部复位。拖动会停止自动旋转。
- 检查 390 × 844 响应式视口：完整排列、紫甘蓝单柱和纵向控制区正常显示；页面主体没有横向溢出，顶部导航沿用共享横向滚动方式。
- 浏览器截图：`screenshots/desktop.png`、`screenshots/mobile-390.png`、`screenshots/mobile-controls.png`。
- 未进行真机触摸或跨浏览器测试；WebGL 错误恢复分支已实现，未注入 GPU 故障。
