Reflection probe
Des sphères métalliques réfléchissant une pièce colorée sans réflexions en espace écran. Trois valeurs de rugosité montrent à quelle vitesse le miroir devient flou.
L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.
Classes Godot utilisées
ReflectionProbeStandardMaterial3DCamera3D
Le code
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)