// world.gdshader // shader for earth globe with heightmap and color texture shader_type spatial; uniform sampler2D height_map : hint_default_white; uniform sampler2D earth_texture : hint_default_white; uniform float height_scale : hint_range(0.0, 0.2) = 0.02; uniform bool apply_height = true; uniform bool show_height_debug = false; // convert point on unit sphere to lat/lon uv coordinates vec2 point_to_uv(vec3 point) { float latitude = asin(point.y); float longitude = atan(point.x, -point.z); // optional : move seam by rotating longitude (0 = current) float lon_offset = 0.0; longitude += lon_offset; float u = (longitude + PI) / (2.0 * PI); float v = (latitude + PI / 2.0) / PI; return vec2(u, v); } void vertex() { // get point on unit sphere (normalized vertex position) vec3 sphere_point = normalize(VERTEX); // convert to uv using lat/lon projection vec2 tex_coord = point_to_uv(sphere_point); // sample heightmap // apply height displacement along normal if (apply_height) { float height = texture(height_map, tex_coord).r; VERTEX = sphere_point * (1.0 + height * height_scale); NORMAL = normalize(VERTEX); } // pass uv to fragment shader UV = tex_coord; } void fragment() { // sample earth texture using lat/lon uv vec4 earth_color = texture(earth_texture, UV); if (show_height_debug) { // debug: show heightmap as grayscale float height = texture(height_map, UV).r; ALBEDO = vec3(height); } else { // normal rendering: show earth texture ALBEDO = earth_color.rgb; } // basic lighting ROUGHNESS = 0.8; METALLIC = 0.0; }