Sólido com SurfaceTool
O mesmo sólido gerado duas vezes pelo SurfaceTool, plano e suave. Só o grupo de suavização muda.
O editor acima está rodando este projeto. Mude uma linha e ele recarrega.
Classes do Godot usadas
SurfaceToolArrayMeshLabel3D
O código
scripts/main.gd
extends Node
const SEGMENTS: int = 14
const TOP: Vector3 = Vector3(0, 1.5, 0)
const BOTTOM: Vector3 = Vector3(0, -1.5, 0)
const UPPER: float = 0.55
const LOWER: float = -0.2
var solids: Array[MeshInstance3D] = []
func _ready() -> void:
_add_environment()
_add_light()
for entry in [{smooth = false, at = -1.7, label = 'set_smooth_group(-1)'}, {smooth = true, at = 1.7, label = 'set_smooth_group(0)'}]:
var solid: MeshInstance3D = MeshInstance3D.new()
solid.mesh = _make_gem(entry.smooth)
solid.position = Vector3(entry.at, 0, 0)
add_child(solid)
solids.append(solid)
var caption: Label3D = Label3D.new()
caption.text = entry.label
caption.pixel_size = 0.009
caption.modulate = Color('#dfe6ff')
caption.position = Vector3(entry.at, -2.1, 0)
add_child(caption)
var camera: Camera3D = Camera3D.new()
camera.position = Vector3(0, 1.5, 5.6)
add_child(camera)
camera.look_at(Vector3(0, -0.1, 0), Vector3.UP)
camera.current = true
print('same vertices, same generate_normals call, only the smooth group changes')
func _process(delta: float) -> void:
for solid in solids:
solid.rotate_y(delta * 0.5)
func _make_gem(smooth: bool) -> ArrayMesh:
var tool: SurfaceTool = SurfaceTool.new()
tool.begin(Mesh.PRIMITIVE_TRIANGLES)
tool.set_smooth_group(0 if smooth else -1)
for i in SEGMENTS:
var upper_a: Vector3 = _ring(i, 0.95, UPPER)
var upper_b: Vector3 = _ring(i + 1, 0.95, UPPER)
var lower_a: Vector3 = _ring(i, 1.2, LOWER)
var lower_b: Vector3 = _ring(i + 1, 1.2, LOWER)
for vertex in [TOP, upper_a, upper_b, upper_a, lower_a, lower_b, upper_a, lower_b, upper_b, BOTTOM, lower_b, lower_a]:
tool.add_vertex(vertex)
tool.generate_normals()
tool.set_material(_make_material())
return tool.commit()
func _ring(index: int, radius: float, height: float) -> Vector3:
var angle: float = TAU * index / SEGMENTS
return Vector3(cos(angle) * radius, height, sin(angle) * radius)
func _make_material() -> StandardMaterial3D:
var material: StandardMaterial3D = StandardMaterial3D.new()
material.albedo_color = Color('#8da5f3')
material.metallic = 0.35
material.roughness = 0.28
return material
func _add_environment() -> void:
var sky_material: ProceduralSkyMaterial = ProceduralSkyMaterial.new()
sky_material.sky_top_color = Color(0.04, 0.05, 0.1)
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
# a sky ambient leaves the faces under the gem unlit against a black ground
env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
env.ambient_light_color = Color('#3b4560')
env.ambient_light_energy = 1.1
var world: WorldEnvironment = WorldEnvironment.new()
world.environment = env
add_child(world)
func _add_light() -> void:
var light: DirectionalLight3D = DirectionalLight3D.new()
light.rotation_degrees = Vector3(-40, -35, 0)
light.light_energy = 1.6
add_child(light)