Bases de Transform
Cinq boîtes et cinq Transform3D écrits à la main : identité, origine, Basis tournée, Basis mise à l'échelle et les trois combinés. Un fantôme marque où se trouve l'identité.
L'éditeur ci-dessus fait tourner ce projet. Changez une ligne et il se recharge.
Classes Godot utilisées
Transform3DBasisMeshInstance3D
Le code
scripts/main.gd
extends Node
const STEPS: Array[String] = ['IDENTITY', 'origin', 'Basis rotated', 'Basis scaled', 'all three']
const SPACING: float = 3.2
const SIZE: float = 1.3
var boxes: Array[MeshInstance3D] = []
var elapsed: float = 0.0
func _ready() -> void:
_add_environment()
_add_light()
_add_ground()
for i in STEPS.size():
var slot: Node3D = Node3D.new()
slot.position = Vector3((i - 2) * SPACING, 1.0, 0)
add_child(slot)
slot.add_child(_make_ghost())
var box: MeshInstance3D = _make_box(float(i) / STEPS.size())
slot.add_child(box)
boxes.append(box)
_add_label(STEPS[i], slot.position + Vector3(0, -1.4, 0))
var camera: Camera3D = Camera3D.new()
camera.fov = 52.0
camera.position = Vector3(0, 2.2, 11.5)
add_child(camera)
camera.look_at(Vector3(0, 1.3, 0), Vector3.UP)
camera.current = true
_apply()
print('every box gets a Transform3D written by hand, and the wire ghost marks where IDENTITY sits')
func _process(delta: float) -> void:
elapsed += delta
_apply()
func _apply() -> void:
var turn: float = elapsed * 0.55
var lift: float = 0.9 + sin(elapsed * 1.6) * 0.6
var pulse: float = 1.0 + cos(elapsed * 1.5) * 0.38
boxes[0].transform = Transform3D.IDENTITY
boxes[1].transform = Transform3D(Basis.IDENTITY, Vector3(0, lift, 0))
boxes[2].transform = Transform3D(Basis(Vector3.UP, turn), Vector3.ZERO)
boxes[3].transform = Transform3D(Basis.from_scale(Vector3(pulse, 1.0, pulse)), Vector3.ZERO)
# Basis.scaled premultiplies, so a non uniform scale after a rotation comes out sheared
boxes[4].transform = Transform3D(Basis(Vector3.UP, turn).scaled(Vector3(pulse, pulse, pulse)), Vector3(0, lift, 0))
func _make_box(hue: float) -> MeshInstance3D:
var mesh: BoxMesh = BoxMesh.new()
mesh.size = Vector3(SIZE, SIZE, SIZE)
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color.from_hsv(hue * 0.45 + 0.08, 0.5, 0.95)
material.roughness = 0.4
var box: MeshInstance3D = MeshInstance3D.new()
box.mesh = mesh
box.material_override = material
return box
func _make_ghost() -> MeshInstance3D:
var mesh: BoxMesh = BoxMesh.new()
mesh.size = Vector3(SIZE, SIZE, SIZE) * 1.01
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color(0.6, 0.68, 0.9, 0.14)
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
material.cull_mode = BaseMaterial3D.CULL_FRONT
var ghost: MeshInstance3D = MeshInstance3D.new()
ghost.mesh = mesh
ghost.material_override = material
return ghost
func _add_label(text: String, at: Vector3) -> void:
var label: Label3D = Label3D.new()
label.text = text
label.font_size = 56
label.pixel_size = 0.006
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 = at
add_child(label)
func _add_ground() -> void:
var mesh: PlaneMesh = PlaneMesh.new()
mesh.size = Vector2(400, 400)
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color('#242938')
material.roughness = 0.95
var ground: MeshInstance3D = MeshInstance3D.new()
ground.mesh = mesh
ground.material_override = material
ground.position = Vector3(0, -0.6, 0)
add_child(ground)
func _add_environment() -> void:
var sky_material: ProceduralSkyMaterial = ProceduralSkyMaterial.new()
sky_material.sky_top_color = Color(0.06, 0.08, 0.16)
sky_material.sky_horizon_color = Color(0.22, 0.25, 0.36)
sky_material.ground_bottom_color = Color(0.15, 0.17, 0.23)
sky_material.ground_horizon_color = Color(0.16, 0.18, 0.25)
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.9
var world: WorldEnvironment = WorldEnvironment.new()
world.environment = env
add_child(world)
func _add_light() -> void:
var light: DirectionalLight3D = DirectionalLight3D.new()
light.rotation_degrees = Vector3(-52, -38, 0)
light.light_energy = 1.3
add_child(light)