Tour de luzes
A mesma geometria e o mesmo material branco três vezes. Uma cull mask dá a cada luz o seu terço da cena.
O editor acima está rodando este projeto. Mude uma linha e ele recarrega.
Classes do Godot usadas
OmniLight3DSpotLight3DDirectionalLight3D
O código
scripts/main.gd
extends Node
const STATIONS: Array[Dictionary] = [
{at = -8.0, title = 'OmniLight3D', color = '#8da5f3'},
{at = 0.0, title = 'SpotLight3D', color = '#8eef97'},
{at = 8.0, title = 'DirectionalLight3D', color = '#f3d48d'},
]
func _ready() -> void:
_add_environment()
for i in STATIONS.size():
var station: Dictionary = STATIONS[i]
var mask: int = 1 << i
_add_station(station.at, station.title, mask)
_add_light(i, station, mask)
var camera: Camera3D = Camera3D.new()
camera.fov = 56.0
camera.position = Vector3(0, 6.0, 13.5)
add_child(camera)
camera.look_at(Vector3(0, 1.6, 0), Vector3.UP)
camera.current = true
print('same geometry and same white material three times, only the light node changes')
func _add_light(index: int, station: Dictionary, mask: int) -> void:
var light: Light3D
if index == 0:
var omni: OmniLight3D = OmniLight3D.new()
omni.position = Vector3(station.at, 3.4, 1.2)
omni.omni_range = 11.0
omni.light_energy = 5.0
light = omni
elif index == 1:
var spot: SpotLight3D = SpotLight3D.new()
spot.position = Vector3(station.at, 6.4, 0.6)
spot.rotation_degrees = Vector3(-90, 0, 0)
spot.spot_range = 16.0
spot.spot_angle = 26.0
spot.spot_angle_attenuation = 0.6
spot.light_energy = 9.0
light = spot
else:
var sun: DirectionalLight3D = DirectionalLight3D.new()
sun.rotation_degrees = Vector3(-48, -32, 0)
sun.light_energy = 1.5
light = sun
# without a cull mask the directional light would wash out the other two stations
light.light_cull_mask = mask
light.light_color = Color(station.color)
add_child(light)
func _add_station(at: float, title: String, mask: int) -> void:
_add_mesh(_slab(), Vector3(at, -0.2, 0), mask)
_add_mesh(_ball(), Vector3(at - 1.7, 0.9, 0.7), mask)
_add_mesh(_block(), Vector3(at + 1.6, 0.7, -0.6), mask)
_add_mesh(_post(), Vector3(at + 0.1, 1.1, 1.7), mask)
var label: Label3D = Label3D.new()
label.text = title
label.font_size = 60
label.pixel_size = 0.007
label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
label.alpha_cut = Label3D.ALPHA_CUT_DISCARD
label.modulate = Color('#c8ccd8')
label.outline_size = 14
label.outline_modulate = Color(0, 0, 0, 0.9)
label.position = Vector3(at, 4.2, 0)
add_child(label)
func _add_mesh(mesh: Mesh, at: Vector3, mask: int) -> void:
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color('#d6dae4')
material.roughness = 0.55
var instance: MeshInstance3D = MeshInstance3D.new()
instance.mesh = mesh
instance.material_override = material
instance.position = at
instance.layers = mask
add_child(instance)
func _slab() -> BoxMesh:
var mesh: BoxMesh = BoxMesh.new()
mesh.size = Vector3(6.4, 0.4, 6.4)
return mesh
func _ball() -> SphereMesh:
var mesh: SphereMesh = SphereMesh.new()
mesh.radius = 0.9
mesh.height = 1.8
return mesh
func _block() -> BoxMesh:
var mesh: BoxMesh = BoxMesh.new()
mesh.size = Vector3(1.4, 1.4, 1.4)
return mesh
func _post() -> CylinderMesh:
var mesh: CylinderMesh = CylinderMesh.new()
mesh.top_radius = 0.5
mesh.bottom_radius = 0.5
mesh.height = 2.2
return mesh
func _add_environment() -> void:
var env: Environment = Environment.new()
env.background_mode = Environment.BG_COLOR
env.background_color = Color(0.03, 0.035, 0.06)
env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
env.ambient_light_color = Color(0.4, 0.45, 0.62)
env.ambient_light_energy = 0.18
var world: WorldEnvironment = WorldEnvironment.new()
world.environment = env
add_child(world)