You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Godot中2D着色器与ParallaxBackground节点实现滚动星空?

问题分析

星星能显示但不滚动的核心原因有两点:

  1. 星空着色器依赖FRAGCOORD(画布绝对像素坐标)和SCREEN_UV(屏幕归一化坐标),这两个坐标完全不受ParallaxBackground的scroll_offset影响——Parallax的滚动是通过调整ParallaxLayer的变换实现的,但你的着色器未使用任何与节点变换相关的坐标(如UV、WORLD_POS)。
  2. 若ParallaxLayer的motion_scale未正确设置(默认应为(1,1)),也会导致滚动偏移无法作用于图层。

解决方案

方案1:修改着色器使用世界坐标(推荐)

将着色器中基于绝对坐标的计算替换为WORLD_POS(世界空间坐标),这样当ParallaxLayer随scroll_offset移动时,世界坐标会同步变化,星星自然会跟着滚动:

修改后的着色器代码:

shader_type canvas_item;

uniform vec4 bg_color: hint_color;

float rand(vec2 st) {
    return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
}

void fragment() {
    float size = 100.0;
    float prob = 0.9;
    // 使用世界空间坐标替代绝对画布坐标
    vec2 pos = floor(1.0 / size * WORLD_POS.xy);
    float color = 0.0;
    float starValue = rand(pos);

    if (starValue > prob)
    {
        vec2 center = size * pos + vec2(size, size) * 0.5;
        float t = 0.9 + 0.2 * sin(TIME * 8.0 + (starValue - prob) / (1.0 - prob) * 45.0);
        // 用世界坐标计算星星距离
        color = 1.0 - distance(WORLD_POS.xy, center) / (0.5 * size);
        color = color * t / (abs(WORLD_POS.y - center.y)) * t / (abs(WORLD_POS.x - center.x));
    }
    else if (rand(WORLD_POS.xy / 20.0) > 0.996)
    {
        float r = rand(WORLD_POS.xy);
        color = r * (0.85 * sin(TIME * (r * 5.0) + 720.0 * r) + 0.95);
    }
    COLOR = vec4(vec3(color),1.0) + bg_color;
}

方案2:给着色器传递滚动偏移参数

如果不想依赖世界坐标,可通过脚本将滚动偏移直接传递给着色器,让着色器基于偏移计算星星位置:

步骤1:修改ParallaxBackground脚本

extends ParallaxBackground

onready var stars_layer = $StarsLayer
onready var stars_material = $StarsLayer/Stars.material
var bg_offset = 0.0

func _ready():
    stars_layer.motion_mirroring = Vector2(0, Helpers.WINDOW_SIZE.y)
    // 初始化着色器的偏移参数
    stars_material.set_shader_param("scroll_offset", Vector2.ZERO)
    // 确保motion_scale生效(默认值,显式设置更稳妥)
    stars_layer.motion_scale = Vector2(1, 1)

func _process(delta):
    bg_offset += 30 * delta
    scroll_offset = Vector2(0, bg_offset)
    // 将偏移传递给着色器
    stars_material.set_shader_param("scroll_offset", Vector2(0, bg_offset))

步骤2:修改着色器添加偏移参数

shader_type canvas_item;

uniform vec4 bg_color: hint_color;
uniform vec2 scroll_offset; // 新增滚动偏移参数

float rand(vec2 st) {
    return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
}

void fragment() {
    float size = 100.0;
    float prob = 0.9;
    // 给画布坐标加上滚动偏移
    vec2 adjusted_coord = FRAGCOORD.xy + scroll_offset;
    vec2 pos = floor(1.0 / size * adjusted_coord);
    float color = 0.0;
    float starValue = rand(pos);

    if (starValue > prob)
    {
        vec2 center = size * pos + vec2(size, size) * 0.5;
        float t = 0.9 + 0.2 * sin(TIME * 8.0 + (starValue - prob) / (1.0 - prob) * 45.0);
        color = 1.0 - distance(adjusted_coord, center) / (0.5 * size);
        color = color * t / (abs(adjusted_coord.y - center.y)) * t / (abs(adjusted_coord.x - center.x));
    }
    else if (rand(adjusted_coord / 20.0) > 0.996)
    {
        float r = rand(adjusted_coord);
        color = r * (0.85 * sin(TIME * (r * 5.0) + 720.0 * r) + 0.95);
    }
    COLOR = vec4(vec3(color),1.0) + bg_color;
}

额外检查项
  • 确认ParallaxLayer的motion_scale设置为Vector2(1,1),该参数控制滚动偏移对图层的影响程度。
  • 将Stars节点的stretch_mode设置为Tile,确保星空滚动时能无缝重复显示。

内容的提问来源于stack exchange,提问作者MAGS94

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 03:15:52