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)

Más ejemplos de Escena 3D