SDF和Web端存档机制

Polygon2D

shader_type canvas_item;
render_mode unshaded;

uniform vec4 color : source_color; 
uniform float angle : hint_range(0,360); 
uniform float max_dist : hint_range(0,1000) = 100; 
uniform sampler2D gradientTexture;

vec4 get_gradient_color(float position) { 
    return texture(gradientTexture, vec2(position, 0.5)); 
}

void fragment() { 
    float ang_rad = angle * 3.1416 / 180.0;
    vec2 dir = vec2(sin(ang_rad),cos(ang_rad)); 
    vec2 at = screen_uv_to_sdf(SCREEN_UV); 
    float accum = 0.0;
    while(accum < max_dist) {
        float d = texture_sdf(at);
        accum+=d;
        if (d < 0.01) {
            break;
        }
        at += d * dir;
    }
    float alpha = 1.0-min(1.0,accum/max_dist);
    
    // the gradient controls the falloff of the shadow
    alpha = get_gradient_color(alpha).r;
    
    COLOR = vec4(color.rgb,alpha * color.a);
}
平台渲染模式SDF支持原因
桌面Forward Plus/Vulkan完全支持
WebWebGL 2SDF作为普通纹理上传
WebWebGL 1 (gl_compatibility)⚠️可能受限,但Godot 4.x默认用WebGL 2
┌──────────────────────────────┐
│                    帧渲染流程                               │
├──────────────────────────────┤
│  1. CPU收集所有OccluderPolygon2D                            │
│                         ↓                                  │
│  2. CPU软件计算生成SDF纹理(距离场)                        │
│                         ↓                                  │
│  3. 将SDF纹理上传到GPU作为普通纹理                          │
│                         ↓                                  │
│  4. 着色器执行光线步进算法:                                │
│     - screen_uv_to_sdf() 转换坐标                           │
│     - texture_sdf() 采样距离值                              │
│     - 沿光线方向累加距离直到碰到遮挡物                      │
│                         ↓                                  │
│  5. 根据累计距离计算阴影透明度                              │
└──────────────────────────────┘

这个项目能在Web上运行的核心原因是:

  1. Godot 4.x默认使用WebGL 2,而非WebGL 1的gl_compatibility模式
  2. SDF数据是CPU预先计算后作为普通纹理上传的,不依赖GPU的特殊SDF支持
  3. 着色器只需要普通的纹理采样能力,这在所有WebGL环境中都支持

只要确保项目设置为WebGL 2渲染模式(Godot 4.x默认),就能正常运行这个阴影效果。

Web 平台文件系统限制 + 资源路径读写规则

res:// 路径在 Web 端是只读的

Web 导出后,res:// 是打包后的压缩资源包不能创建文件夹、不能写入文件,这是最根本的原因。

DirAccess 操作res://在 Web 端无权限

浏览器环境不允许 JS 修改原始资源包,你的make_dir、文件保存都会静默失败。 Web 端唯一可写入路径:user:// Godot 所有平台(Web/PC/ 移动端

唯一通用的可读写路径是 user://,Web 端会映射到浏览器的本地存储(IndexedDB)。

我想知道你改的这个存档逻辑是新建存档放在user里面,然后加载的时候从user拿存档加载到res?

新存档:
res://resources/bag.tres (源资源,模板)
↓ 深拷贝/取空实例
{archives_dir}/{slot}/bag.tres ← 我改了:web 走 user://web_archives/

加载存档:
res://resources/bag.tres (源)
{archives_dir}/{slot}/bag.tres (存档)
↓ 把存档的值覆盖到源资源 (in-memory)
res://resources/bag.tres (源,已覆盖)
↓ ResourceSaver.save 写回磁盘
res://resources/bag.tres ← !! 这里又写回 res:// 了,我没改

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇