Shader de céu
Um pôr do sol procedural com estrelas, escrito como shader_type sky. O disco do sol segue o nó de luz.
O editor acima está rodando este projeto. Mude uma linha e ele recarrega.
Classes do Godot usadas
SkyShaderMaterialDirectionalLight3D
O código
scripts/main.gd
extends Node
var sun: DirectionalLight3D
var elapsed: float = 0.0
func _ready() -> void:
var material: ShaderMaterial = ShaderMaterial.new()
material.shader = Get.shader('sky')
var sky: Sky = Sky.new()
sky.sky_material = material
var env: Environment = Environment.new()
env.background_mode = Environment.BG_SKY
env.sky = sky
env.ambient_light_source = Environment.AMBIENT_SOURCE_SKY
env.ambient_light_energy = 1.0
var world: WorldEnvironment = WorldEnvironment.new()
world.environment = env
add_child(world)
sun = DirectionalLight3D.new()
sun.light_energy = 1.2
add_child(sun)
_add_ground()
for i in 5:
_add_rock(Vector3(cos(i * 1.3) * (3.0 + i), 0.4, sin(i * 1.3) * (3.0 + i)))
var camera: Camera3D = Camera3D.new()
camera.position = Vector3(0, 1.6, 9)
add_child(camera)
camera.look_at(Vector3(0, 2.4, 0), Vector3.UP)
camera.current = true
print('the sky is a shader, and the sun disc follows the DirectionalLight3D')
func _process(delta: float) -> void:
elapsed += delta
sun.rotation_degrees = Vector3(-8.0 - 22.0 * sin(elapsed * 0.25), -40.0 + elapsed * 6.0, 0)
func _add_ground() -> void:
var mesh: PlaneMesh = PlaneMesh.new()
mesh.size = Vector2(60, 60)
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color('#1b2030')
material.roughness = 0.9
var ground: MeshInstance3D = MeshInstance3D.new()
ground.mesh = mesh
ground.material_override = material
add_child(ground)
func _add_rock(at: Vector3) -> void:
var mesh: PrismMesh = PrismMesh.new()
mesh.size = Vector3(1.6, 2.2, 1.6)
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color('#232a3d')
material.roughness = 0.8
var rock: MeshInstance3D = MeshInstance3D.new()
rock.mesh = mesh
rock.material_override = material
rock.position = at + Vector3(0, 1.1, 0)
add_child(rock)shaders/sky.gdshader
shader_type sky;
uniform vec3 zenith_color: source_color = vec3(0.05, 0.12, 0.35);
uniform vec3 horizon_color: source_color = vec3(0.85, 0.45, 0.3);
uniform vec3 ground_color: source_color = vec3(0.03, 0.03, 0.05);
uniform vec3 sun_color: source_color = vec3(1.0, 0.85, 0.6);
uniform float sun_size = 400.0;
uniform float star_amount = 0.6;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}
void sky() {
float height = EYEDIR.y;
vec3 color = mix(horizon_color, zenith_color, pow(clamp(height, 0.0, 1.0), 0.45));
if (height < 0.0) {
color = mix(horizon_color, ground_color, clamp(-height * 3.0, 0.0, 1.0));
}
vec2 star_uv = floor(EYEDIR.xz / max(abs(EYEDIR.y), 0.05) * 90.0);
float star = step(1.0 - star_amount * 0.02, hash(star_uv));
color += vec3(star) * clamp(height, 0.0, 1.0);
if (LIGHT0_ENABLED) {
float sun = pow(max(dot(EYEDIR, LIGHT0_DIRECTION), 0.0), sun_size);
color += sun_color * sun * LIGHT0_ENERGY;
}
COLOR = color;
}