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

4.5 KiB
Raw Blame History

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,太阳落到地平线以下会自动淡入星空,还没实测过夜景。