Reflection probe
Esferas metálicas reflejando una sala de colores sin reflejos en espacio de pantalla. Tres valores de rugosidad muestran lo rápido que el espejo se vuelve borrón.
El editor de arriba está ejecutando este proyecto. Cambia una línea y se recarga.
Clases de Godot usadas
ReflectionProbeStandardMaterial3DCamera3D
El código
scripts/main.gd
extends Node
const ROOM: float = 12.0
const WALL: float = 0.5
const HEIGHT: float = 9.0
const RING: float = 5.6
var camera: Camera3D
var angle: float = 0.0
func _ready() -> void:
_add_environment()
_add_room()
_add_spheres()
var lamp: OmniLight3D = OmniLight3D.new()
lamp.position = Vector3(0, HEIGHT - 2.0, 1.5)
lamp.light_energy = 3.4
lamp.omni_range = 40.0
add_child(lamp)
# UPDATE_ALWAYS bakes a black cubemap in gl_compatibility, so the probe has to be added last
var probe: ReflectionProbe = ReflectionProbe.new()
probe.size = Vector3(ROOM * 2.0, HEIGHT, ROOM * 2.0)
probe.position = Vector3(0, HEIGHT * 0.5, 0)
probe.update_mode = ReflectionProbe.UPDATE_ONCE
probe.box_projection = true
probe.max_distance = 60.0
add_child(probe)
camera = Camera3D.new()
add_child(camera)
camera.current = true
_place_camera()
print('the camera circles the room and each sphere mirrors the four wall colors, without SSR')
func _process(delta: float) -> void:
angle += delta * 0.08
_place_camera()
func _place_camera() -> void:
camera.position = Vector3(sin(angle), 0, cos(angle)) * 11.0 + Vector3(0, 4.5, 0)
camera.look_at(Vector3(0, 1.9, 0), Vector3.UP)
func _add_spheres() -> void:
var roughness: Array[float] = [0.02, 0.18, 0.4]
for i in roughness.size():
var turn: float = deg_to_rad(90.0 + i * 120.0)
var mesh: SphereMesh = SphereMesh.new()
mesh.radius = 1.3
mesh.height = 2.6
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color('#c8ccd8')
material.metallic = 1.0
material.roughness = roughness[i]
var sphere: MeshInstance3D = MeshInstance3D.new()
sphere.mesh = mesh
sphere.material_override = material
sphere.position = Vector3(cos(turn), 0, sin(turn)) * RING + Vector3(0, 1.5, 0)
add_child(sphere)
func _add_room() -> void:
var span: float = ROOM * 2.0
_add_slab(Vector3(span, WALL, span), Vector3(0, -WALL * 0.5, 0), '#2a2f3d')
_add_slab(Vector3(span, WALL, span), Vector3(0, HEIGHT, 0), '#f3d48d')
_add_slab(Vector3(span, HEIGHT, WALL), Vector3(0, HEIGHT * 0.5, -ROOM), '#8da5f3')
_add_slab(Vector3(span, HEIGHT, WALL), Vector3(0, HEIGHT * 0.5, ROOM), '#f3d48d')
_add_slab(Vector3(WALL, HEIGHT, span), Vector3(-ROOM, HEIGHT * 0.5, 0), '#fc7f7f')
_add_slab(Vector3(WALL, HEIGHT, span), Vector3(ROOM, HEIGHT * 0.5, 0), '#8eef97')
func _add_slab(size: Vector3, at: Vector3, hex: String) -> void:
var mesh: BoxMesh = BoxMesh.new()
mesh.size = size
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color(hex)
material.roughness = 0.85
var slab: MeshInstance3D = MeshInstance3D.new()
slab.mesh = mesh
slab.material_override = material
slab.position = at
add_child(slab)
func _add_environment() -> void:
var sky_material: ProceduralSkyMaterial = ProceduralSkyMaterial.new()
sky_material.sky_top_color = Color(0.05, 0.06, 0.12)
sky_material.sky_horizon_color = Color(0.12, 0.14, 0.22)
sky_material.ground_bottom_color = Color(0.02, 0.02, 0.04)
sky_material.ground_horizon_color = Color(0.09, 0.1, 0.15)
var sky: Sky = Sky.new()
sky.sky_material = sky_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 = 0.4
var world: WorldEnvironment = WorldEnvironment.new()
world.environment = env
add_child(world)