Files
agame/.workbuddy-ai/memory/2026-09-21.md
T
2026-09-22 00:07:58 +08:00

71 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 2026-09-21
## 程序化卡通天空(world/sky/)
新增 `res://world/sky/cartoon_sky.gdshader` + `cartoon_sky.tres`(Sky 资源,内含调好的 ShaderMaterial),
并让 `world/main.tscn` 的 WorldEnvironment 改用它;同时把 `Sun` 的 light_color 调成暖白
(1.0, 0.97, 0.90),项目设置开了 `rendering/anti_aliasing/quality/use_debanding`。
渲染顺序:渐变天空 → 地面半球 → 星空 → 太阳 → 云 → 地平线雾霭。
全部由噪声现场生成,无贴图。参数按 Gradient / Sun / Stars / Clouds / Haze 分组暴露在 Inspector。
### Godot shader 踩坑(重要,下次直接避开)
1. **`mat2(a,b,c,d)` 不合法**。Godot 着色器语言只接受列向量构造:`mat2(vec2, vec2)`。
同理 mat3 要用三个 vec3。报错形式是
`Invalid arguments for the built-in function: "mat2(float,float,float,float)"`。
2. **天空着色器的编译错误不在 `logs_read(source="editor")` 里**,除非触发一次编译。
可靠的取错方式:改完 → `filesystem_manage(op="scan")` → `project_run` →
`logs_read(source="editor", include_details=true)`。game 日志只给一行
`version_get_shader: Parameter "version" is null`,没用。
3. **`smoothstep(edge0, edge1, x)` 不要写 edge0 > edge1**,改成 `1.0 - smoothstep(...)`。
4. 变量重名(同一函数内二次声明)会报 `Redefinition of 'x'`,直接让整个 shader 编译失败。
5. shader 编译失败时天空渲染成**纯黑**,不是品红 —— 别以为是资源没挂上。
6. **编辑器里的 Shader 面板会缓存旧的编译报错**。外部改完 .gdshader + scan 之后,
面板可能仍显示上一次失败的 `mat2(float,float,float,float)` 之类信息,
而 Debugger → Errors 已经是空的。判定方法:看 `logs_read(source="editor")` 是否为空,
再 `project_run` 一次看天空是否正常。**不要照着这条过期报错去改代码。**
注意:如果 Shader 标签页里留着一份旧的未保存副本,从面板里保存会把我改好的文件覆盖回去。
### 云的形态(花了最多时间)
- **别用「水平云平面」投影 `uv = dir.xz / dir.y`**:低仰角处透视压缩成 10:1,
云被拉成细条;若再对 dir.y 做硬 clamp,被钉死的距离会让噪声只随方位角变化,
直接拉出**竖条拖影**。
- **也别用方位角等距投影**(`uv = normalize(dir.xz) * acos(dir.y)`):天顶是极点,
云会全部朝圆心收拢,抬头就看得见。
- **正解是球极投影 `uv = dir.xz / (1.0 + dir.y)`**:保角 → 形状不拉伸;
天顶只是圆盘圆心而非收缩极点;方位角天然无缝;角尺寸从地平线到天顶只放大 2 倍,
接近真实透视。这个投影配 2D Perlin 出图最好。
- **噪声用 Perlin 梯度噪声,不要 value noise**:value noise 在格点处梯度为零,
阈值化后会切出一块块多边形的棱角("晶体"感)。
- **三维 Perlin 在这台机器上不行**:sin 系哈希(`fract(sin(dot(p,k))*43758)`)在大坐标
(fbm 第 3~4 个倍频时 dot 可达 1e4)下掉精度,高频倍频退化成纯噪声 → 云变成细丝。
Hoskins 的 fract 系哈希精度安全,但出图仍偏块状。最终放弃 3D,回到 2D Perlin。
- **阈值要压在 fbm 分布均值之上**。阈值贴着均值时等值线本身就很纠结,
云会变成一张"蛛网";抬到 +0.5σ 以上才是干净的团块。
### 当前调好的参数
coverage 0.33 / scale 5.0 / edge 0.16 / warp 0.30 / horizon_fade 0.18 / speed 0.01,
云影色 (0.45,0.62,0.88),边缘辉光 (1,0.93,0.76)。
## Sun 阴影(当天稍后)
`/Main/Sun` 开了 `shadow_enabled = true`;同时把 `directional_shadow_max_distance`
从默认 100 收到 40(场景只有 40×40,收窄后阴影贴图分辨率集中到实际范围,边缘干净很多),
并开 `directional_shadow_blend_splits` 消除 split 之间的接缝。
### 又一个 Godot MCP 坑
`node_set_property` 写 **bool** 属性会失败:`true` 和 `1` 都被序列化成 String,
报 `WRONG_TYPE: Cannot write String to a bool property`。
**bool 属性只能直接改 .tscn,再 `scene_open(force_reload=true)`。**
(Color / Vector3 用 dict 传是正常的,`light_color` 就是这么改的。)
## 待办 / 可选后续
- 地面还是灰白色 (0.55,0.58,0.62),被天空的蓝色环境光染成了淡紫。
换成草绿之类的固有色会协调很多 —— 这是目前画面里最突兀的一处。
- `star_amount` 默认 0,太阳落到地平线以下会自动淡入星空,还没实测过夜景。