shader_type spatial; // unshaded matches the pixel-art look of the rest of the game. // Opaque render mode guarantees the floor draws before any transparent Sprite3D / // AnimatedSprite3D, which are always sorted into the transparent queue after opaque geo. render_mode unshaded, depth_draw_opaque, cull_back; // Texture carried over from the TrenchBroom surface material by acidarea.gd. // hint_default_white means a flat white is used if nothing is assigned, so // acid_color alone still produces a visible result. uniform sampler2D albedo_tex : source_color, filter_nearest, repeat_enable, hint_default_white; // Grayscale noise for UV distortion and bubble pulse. Falls back to white (no distortion). uniform sampler2D noise_tex : hint_default_white, filter_linear_mipmap, repeat_enable; uniform vec4 acid_color : source_color = vec4(0.2, 0.85, 0.1, 1.0); uniform vec2 flow_direction = vec2(0.3, 0.15); // How strongly the noise warps the UV coords uniform float distortion_strength = 0.04; // Additive glow tint strength (0 = no glow) uniform float emission_energy = 0.4; void fragment() { vec2 uv = UV; float t = TIME; // Sample noise at two offsets to build a swirling distortion field vec2 noise_uv_a = uv * 0.5 + vec2(t * 0.05, t * 0.03); vec2 noise_uv_b = uv * 0.5 + vec2(-t * 0.04, t * 0.06); float noise_a = texture(noise_tex, noise_uv_a).r; float noise_b = texture(noise_tex, noise_uv_b).r; vec2 distortion = vec2(noise_a, noise_b) * 2.0 - 1.0; vec2 scrolled_uv = uv + flow_direction * t + distortion * distortion_strength; vec4 tex_color = texture(albedo_tex, scrolled_uv); vec3 final_color = tex_color.rgb * acid_color.rgb; // Subtle additive glow pulsing with noise so the surface looks alive float bubble_pulse = texture(noise_tex, uv * 0.3 + vec2(t * 0.1)).r; final_color += final_color * emission_energy * (0.7 + 0.3 * bubble_pulse); ALBEDO = final_color; }