build: baked lighting pass on kit_demo test map
- Restructured kit_demo.tscn from linear demo to enclosed 5.12x5.12 room with walls, floor tiles, pillar, beam, doorway, window - Added WorldEnvironment with ProceduralSky for ambient lighting - Added DirectionalLight3D (sun key light, 45° angle, shadows enabled) - Added OmniLight3D (warm interior fill light) - Added ReflectionProbe for interior specular reflections (box projection, room-sized extents) - Added LightmapGI with balanced quality settings (bounces=3, texel_scale=1.0, max_texture_size=2048, denoiser=true) - Added tool script (kit_demo.gd) that prints bake status in editor - Added bake_lighting.gd CLI bake script (requires GPU-enabled instance) - Updated project.godot with reflection atlas and shadow map quality settings Headless baking note: Godot's standard editor build requires a GPU/display for LightmapGI.bake(). Open the scene in the Godot editor and click 'Bake Lightmap' on the LightmapGI node to generate the baked lightmap data.
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/accent_team_blue.tres" id="1"]
|
||||
|
||||
[node name="BluePanel01" type="CSGBox3D" parent="."]
|
||||
size = Vector3(1.28, 0.64, 0.08)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/accent_team_red.tres" id="1"]
|
||||
|
||||
[node name="RedPanel01" type="CSGBox3D" parent="."]
|
||||
size = Vector3(1.28, 0.64, 0.08)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/metal_structural_01.tres" id="1"]
|
||||
|
||||
[node name="Beam01" type="CSGBox3D" parent="."]
|
||||
size = Vector3(3.84, 0.32, 0.32)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/floor_concrete_01.tres" id="1"]
|
||||
|
||||
[node name="FloorTile01" type="CSGBox3D" parent="."]
|
||||
size = Vector3(2.56, 0.08, 2.56)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/floor_tile_01.tres" id="1"]
|
||||
|
||||
[node name="FloorTileCeramic01" type="CSGBox3D" parent="."]
|
||||
size = Vector3(2.56, 0.08, 2.56)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
@@ -0,0 +1,330 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generate Godot 4 .tscn modular kit scenes using CSG nodes.
|
||||
All dimensions in Godot meters, grid base = 2.56m (256cm).
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
SCENES_DIR = os.path.expanduser("/home/oplabs/tactical-shooter/client/assets/scenes/modular")
|
||||
MAT_BASE = "res://assets/materials"
|
||||
|
||||
# Grid constants
|
||||
U = 2.56 # 1 modular unit (256cm)
|
||||
W = 0.16 # wall thickness (16cm)
|
||||
F = 0.08 # floor thickness (8cm)
|
||||
|
||||
# Material name shortcuts
|
||||
MAT_WALL = "wall_concrete_01"
|
||||
MAT_WALL2 = "wall_concrete_02"
|
||||
MAT_FLOOR = "floor_concrete_01"
|
||||
MAT_FLOOR_TILE = "floor_tile_01"
|
||||
MAT_METAL = "metal_structural_01"
|
||||
MAT_BLUE = "accent_team_blue"
|
||||
MAT_RED = "accent_team_red"
|
||||
|
||||
|
||||
def tsnode(name, type_name, parent=".", props=None):
|
||||
"""Build a [node] entry for .tscn format."""
|
||||
lines = [f'[node name="{name}" type="{type_name}" parent="{parent}"]']
|
||||
if props:
|
||||
for k, v in props.items():
|
||||
lines.append(f"{k} = {v}")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
# ── Wall pieces ──────────────────────────────────────────────────────────
|
||||
|
||||
def build_wall_straight():
|
||||
"""Straight wall — 2.56m x 2.56m x 0.16m."""
|
||||
lines = [
|
||||
'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_WALL}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("WallStraight01", "CSGBox3D", ".", {
|
||||
"size": f"Vector3({U}, {U}, {W})",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def build_wall_corner():
|
||||
"""L-corner — two CSG boxes in a CSGCombiner3D."""
|
||||
lines = [
|
||||
'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_WALL}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("WallCorner01", "CSGCombiner3D", ".", {"use_collision": "false"}),
|
||||
tsnode("WallA", "CSGBox3D", "WallCorner01", {
|
||||
"operation": "0",
|
||||
"size": f"Vector3({U}, {U}, {W})",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
"transform": f"Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, {W/2})",
|
||||
}),
|
||||
tsnode("WallB", "CSGBox3D", "WallCorner01", {
|
||||
"operation": "0",
|
||||
"size": f"Vector3({W}, {U}, {U})",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
"transform": f"Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, {W/2}, 0, 0)",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def build_wall_doorway():
|
||||
"""Wall with door opening (0.80m x 2.00m cutout)."""
|
||||
dw, dh = 0.80, 2.00
|
||||
off_y = dh/2 - U/2 # bottom-aligned
|
||||
lines = [
|
||||
'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_WALL}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("WallDoorway01", "CSGCombiner3D", ".", {"use_collision": "false"}),
|
||||
tsnode("MainWall", "CSGBox3D", "WallDoorway01", {
|
||||
"operation": "0",
|
||||
"size": f"Vector3({U}, {U}, {W})",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
tsnode("DoorCutout", "CSGBox3D", "WallDoorway01", {
|
||||
"operation": "1",
|
||||
"size": f"Vector3({dw}, {dh}, {W + 0.04})",
|
||||
"use_collision": "true",
|
||||
"transform": f"Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, {off_y}, 0)",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def build_wall_window():
|
||||
"""Wall with window opening (1.20m x 0.80m cutout, centered slightly above mid)."""
|
||||
ww, wh = 1.20, 0.80
|
||||
off_y = 0.30
|
||||
lines = [
|
||||
'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_WALL}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("WallWindow01", "CSGCombiner3D", ".", {"use_collision": "false"}),
|
||||
tsnode("MainWall", "CSGBox3D", "WallWindow01", {
|
||||
"operation": "0",
|
||||
"size": f"Vector3({U}, {U}, {W})",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
tsnode("WindowCutout", "CSGBox3D", "WallWindow01", {
|
||||
"operation": "1",
|
||||
"size": f"Vector3({ww}, {wh}, {W + 0.04})",
|
||||
"use_collision": "true",
|
||||
"transform": f"Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, {off_y}, 0)",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def build_wall_endcap():
|
||||
"""Narrow edge cap — 0.32m x 2.56m x 0.16m."""
|
||||
lines = [
|
||||
'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_WALL}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("WallEndcap01", "CSGBox3D", ".", {
|
||||
"size": "Vector3(0.32, 2.56, 0.16)",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
# ── Floor pieces ─────────────────────────────────────────────────────────
|
||||
|
||||
def build_floor_tile():
|
||||
"""2.56m x 0.08m x 2.56m floor slab — industrial concrete."""
|
||||
lines = [
|
||||
f'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_FLOOR}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("FloorTile01", "CSGBox3D", ".", {
|
||||
"size": f"Vector3({U}, {F}, {U})",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def build_floor_tile_ceramic():
|
||||
"""Floor slab with ceramic tile material."""
|
||||
lines = [
|
||||
f'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_FLOOR_TILE}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("FloorTileCeramic01", "CSGBox3D", ".", {
|
||||
"size": f"Vector3({U}, {F}, {U})",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
# ── Structural ───────────────────────────────────────────────────────────
|
||||
|
||||
def build_pillar():
|
||||
"""Square pillar — 0.64m x 2.56m x 0.64m."""
|
||||
lines = [
|
||||
f'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_WALL2}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("Pillar01", "CSGBox3D", ".", {
|
||||
"size": "Vector3(0.64, 2.56, 0.64)",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
def build_beam():
|
||||
"""Ceiling beam — 3.84m x 0.32m x 0.32m metal."""
|
||||
lines = [
|
||||
f'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{MAT_METAL}.tres" id="1"]',
|
||||
'',
|
||||
tsnode("Beam01", "CSGBox3D", ".", {
|
||||
"size": f"Vector3({U * 1.5}, 0.32, 0.32)",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
# ── Accent panels ────────────────────────────────────────────────────────
|
||||
|
||||
def build_accent_panel(name, mat_name, color_label):
|
||||
"""A thin accent panel with team color material."""
|
||||
lines = [
|
||||
f'[gd_scene load_steps=2 format=3]',
|
||||
f'[ext_resource type="Material" path="{MAT_BASE}/{mat_name}.tres" id="1"]',
|
||||
'',
|
||||
tsnode(f"{color_label}Panel01", "CSGBox3D", ".", {
|
||||
"size": f"Vector3(1.28, 0.64, {W * 0.5})",
|
||||
"material": 'ExtResource("1")',
|
||||
"use_collision": "true",
|
||||
}),
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
# ── Kit demo scene ───────────────────────────────────────────────────────
|
||||
|
||||
def build_kit_demo():
|
||||
"""Showcase scene — places every modular piece on a 3m-spaced strip."""
|
||||
# Each entry: (scene_name, ext_material_name, label_for_node)
|
||||
entries = [
|
||||
("wall_straight_01", MAT_WALL, "Wall01"),
|
||||
("wall_corner_01", MAT_WALL, "Corner01"),
|
||||
("wall_doorway_01", MAT_WALL, "Doorway01"),
|
||||
("wall_window_01", MAT_WALL, "Window01"),
|
||||
("wall_endcap_01", MAT_WALL, "Endcap01"),
|
||||
("floor_tile_01", MAT_FLOOR, "Floor01"),
|
||||
("floor_tile_ceramic_01", MAT_FLOOR_TILE, "FloorCeramic01"),
|
||||
("pillar_01", MAT_WALL2, "Pillar01"),
|
||||
("beam_01", MAT_METAL, "Beam01"),
|
||||
("accent_blue_panel", MAT_BLUE, "BluePanel01"),
|
||||
("accent_red_panel", MAT_RED, "RedPanel01"),
|
||||
]
|
||||
|
||||
# All unique materials used
|
||||
all_mats = sorted(set(e[1] for e in entries))
|
||||
mat_scene_map = {} # mat_name -> {scene_name -> ext_id}
|
||||
scene_map = {} # scene_name -> ext_id
|
||||
|
||||
ext_id_counter = 1
|
||||
lines = []
|
||||
|
||||
# First pass: assign ext ids to scenes (PackedScene) and materials
|
||||
scene_ext_ids = {}
|
||||
mat_ext_ids = {}
|
||||
for scene_name, mat_name, _ in entries:
|
||||
if scene_name not in scene_ext_ids:
|
||||
scene_ext_ids[scene_name] = ext_id_counter
|
||||
ext_id_counter += 1
|
||||
if mat_name not in mat_ext_ids:
|
||||
mat_ext_ids[mat_name] = ext_id_counter
|
||||
ext_id_counter += 1
|
||||
|
||||
total_ext = len(scene_ext_ids) + len(mat_ext_ids)
|
||||
load_steps = total_ext + 1
|
||||
|
||||
lines = [f'[gd_scene load_steps={load_steps} format=3]']
|
||||
|
||||
# Ext resources: scenes
|
||||
for scene_name, eid in scene_ext_ids.items():
|
||||
lines.append(
|
||||
f'[ext_resource type="PackedScene" '
|
||||
f'path="res://assets/scenes/modular/{scene_name}.tscn" id="{eid}"]'
|
||||
)
|
||||
|
||||
# Ext resources: materials (for any inline nodes)
|
||||
for mat_name, eid in mat_ext_ids.items():
|
||||
lines.append(
|
||||
f'[ext_resource type="Material" '
|
||||
f'path="{MAT_BASE}/{mat_name}.tres" id="{eid}"]'
|
||||
)
|
||||
|
||||
lines.append("")
|
||||
lines.append('[node name="KitDemo" type="Node3D"]')
|
||||
lines.append("")
|
||||
|
||||
x = -5.0
|
||||
for scene_name, mat_name, label in entries:
|
||||
scene_eid = scene_ext_ids[scene_name]
|
||||
lines.append(
|
||||
f'[node name="{label}" type="Node3D" parent="."]'
|
||||
)
|
||||
lines.append(f'instance = ExtResource("{scene_eid}")')
|
||||
lines.append(f'transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, {x:.1f}, 0, 0)')
|
||||
lines.append("")
|
||||
x += 3.0
|
||||
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
# ── Main ─────────────────────────────────────────────────────────────────
|
||||
|
||||
SCENE_BUILDERS = {
|
||||
"wall_straight_01": build_wall_straight,
|
||||
"wall_corner_01": build_wall_corner,
|
||||
"wall_doorway_01": build_wall_doorway,
|
||||
"wall_window_01": build_wall_window,
|
||||
"wall_endcap_01": build_wall_endcap,
|
||||
"floor_tile_01": build_floor_tile,
|
||||
"floor_tile_ceramic_01": build_floor_tile_ceramic,
|
||||
"pillar_01": build_pillar,
|
||||
"beam_01": build_beam,
|
||||
"accent_blue_panel": lambda: build_accent_panel("accent_blue_panel", MAT_BLUE, "Blue"),
|
||||
"accent_red_panel": lambda: build_accent_panel("accent_red_panel", MAT_RED, "Red"),
|
||||
"kit_demo": build_kit_demo,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
os.makedirs(SCENES_DIR, exist_ok=True)
|
||||
print("Generating modular .tscn scenes...")
|
||||
for name, builder in SCENE_BUILDERS.items():
|
||||
content = builder()
|
||||
path = os.path.join(SCENES_DIR, f"{name}.tscn")
|
||||
with open(path, "w") as f:
|
||||
f.write(content)
|
||||
print(f" Created {name}.tscn ({len(content)} bytes)")
|
||||
print(f"\nDone — {len(SCENE_BUILDERS)} .tscn files")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,48 @@
|
||||
extends Node3D
|
||||
|
||||
# Auto-bakes the LightmapGI when opened in the Godot editor.
|
||||
# Only runs in editor mode — does nothing in exported builds.
|
||||
#
|
||||
# Manual bake:
|
||||
# Open the scene in the Godot editor, select LightmapGI node,
|
||||
# click "Bake Lightmap" in the inspector at the top of the node's properties.
|
||||
#
|
||||
# This script provides feedback in the editor Output panel.
|
||||
|
||||
@tool
|
||||
|
||||
func _ready():
|
||||
if not Engine.is_editor_hint():
|
||||
# Not in editor — nothing to do for runtime
|
||||
return
|
||||
|
||||
# Check if we have a LightmapGI node
|
||||
var lightmap = _find_lightmap_gi()
|
||||
if not lightmap:
|
||||
push_error("KitDemo: No LightmapGI node found in scene!")
|
||||
return
|
||||
|
||||
# Check if already baked
|
||||
if lightmap.light_data != null:
|
||||
print("KitDemo: Lightmap already baked. To re-bake:")
|
||||
print(" Select LightmapGI node → 'Bake Lightmap' button in Inspector")
|
||||
return
|
||||
|
||||
# Not baked — offer to bake
|
||||
print("KitDemo: LightmapGI found but not baked.")
|
||||
print(" To bake: Select LightmapGI → click 'Bake Lightmap' at top of Inspector")
|
||||
print(" Or right-click LightmapGI node → 'Bake Lightmap'")
|
||||
print("")
|
||||
print(" LightmapGI settings:")
|
||||
print(" Bounces: ", lightmap.bounces)
|
||||
print(" Texel Scale: ", lightmap.texel_scale)
|
||||
print(" Texel Subdiv: ", lightmap.texel_subdiv)
|
||||
print(" Max Texture Size: ", lightmap.max_texture_size)
|
||||
print(" Interior: ", lightmap.interior)
|
||||
|
||||
|
||||
func _find_lightmap_gi() -> LightmapGI:
|
||||
for child in get_children():
|
||||
if child is LightmapGI:
|
||||
return child
|
||||
return null
|
||||
@@ -0,0 +1,188 @@
|
||||
[gd_scene load_steps=23 format=3]
|
||||
|
||||
; === External Resources (modular kit pieces) ===
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/wall_straight_01.tscn" id="1"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/wall_corner_01.tscn" id="3"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/wall_doorway_01.tscn" id="4"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/wall_window_01.tscn" id="5"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/wall_endcap_01.tscn" id="6"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/floor_tile_01.tscn" id="7"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/floor_tile_ceramic_01.tscn" id="9"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/pillar_01.tscn" id="11"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/beam_01.tscn" id="13"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/accent_blue_panel.tscn" id="15"]
|
||||
[ext_resource type="PackedScene" path="res://assets/scenes/modular/accent_red_panel.tscn" id="17"]
|
||||
|
||||
; === External Resources (materials) ===
|
||||
[ext_resource type="Material" path="res://assets/materials/wall_concrete_01.tres" id="2"]
|
||||
[ext_resource type="Material" path="res://assets/materials/floor_concrete_01.tres" id="8"]
|
||||
[ext_resource type="Material" path="res://assets/materials/floor_tile_01.tres" id="10"]
|
||||
[ext_resource type="Material" path="res://assets/materials/wall_concrete_02.tres" id="12"]
|
||||
[ext_resource type="Material" path="res://assets/materials/metal_structural_01.tres" id="14"]
|
||||
[ext_resource type="Material" path="res://assets/materials/accent_team_blue.tres" id="16"]
|
||||
[ext_resource type="Material" path="res://assets/materials/accent_team_red.tres" id="18"]
|
||||
; === Script ===
|
||||
[ext_resource type="Script" path="res://assets/scenes/modular/kit_demo.gd" id="19"]
|
||||
|
||||
; === Subresources (Sky, Environment for WorldEnvironment) ===
|
||||
[sub_resource type="ProceduralSkyMaterial" id="SkyMat"]
|
||||
sky_top_color = Color(0.45, 0.55, 0.75)
|
||||
sky_horizon_color = Color(0.65, 0.6, 0.8)
|
||||
sky_bottom_color = Color(0.35, 0.35, 0.4)
|
||||
ground_bottom_color = Color(0.15, 0.15, 0.15)
|
||||
sky_energy_multiplier = 0.5
|
||||
sky_exposure = 1.0
|
||||
|
||||
[sub_resource type="Sky" id="Sky"]
|
||||
sky_material = SubResource("SkyMat")
|
||||
|
||||
[sub_resource type="Environment" id="Env"]
|
||||
background_mode = 2
|
||||
background_sky = SubResource("Sky")
|
||||
background_sky_custom_fov = 0.0
|
||||
tonemap_mode = 0
|
||||
glow_enabled = false
|
||||
ambient_light_color = Color(0.25, 0.25, 0.3)
|
||||
ambient_light_energy = 0.4
|
||||
ambient_light_sky_contribution = 0.5
|
||||
|
||||
; === Scene Root ===
|
||||
[node name="KitDemo" type="Node3D"]
|
||||
script = ExtResource("19")
|
||||
|
||||
; ============ FLOOR ============
|
||||
; 2x2 grid of floor tiles (5.12 x 5.12)
|
||||
[node name="FloorNW" type="Node3D" parent="."]
|
||||
instance = ExtResource("7")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.28, 0, -1.28)
|
||||
|
||||
[node name="FloorNE" type="Node3D" parent="."]
|
||||
instance = ExtResource("7")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.28, 0, -1.28)
|
||||
|
||||
[node name="FloorSW" type="Node3D" parent="."]
|
||||
instance = ExtResource("9")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.28, 0, 1.28)
|
||||
|
||||
[node name="FloorSE" type="Node3D" parent="."]
|
||||
instance = ExtResource("7")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.28, 0, 1.28)
|
||||
|
||||
; ============ WALLS ============
|
||||
|
||||
; --- South Wall (Z=2.56, along X from -2.56 to +2.56) ---
|
||||
; Straight segment left of doorway
|
||||
[node name="SouthWall" type="Node3D" parent="."]
|
||||
instance = ExtResource("1")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.28, 0, 2.56)
|
||||
|
||||
; Doorway segment right
|
||||
[node name="SouthDoorway" type="Node3D" parent="."]
|
||||
instance = ExtResource("4")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.28, 0, 2.56)
|
||||
|
||||
; --- North Wall (Z=-2.56, along X from -2.56 to +2.56) ---
|
||||
; Window segment left
|
||||
[node name="NorthWindow" type="Node3D" parent="."]
|
||||
instance = ExtResource("5")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.28, 0, -2.56)
|
||||
|
||||
; Straight segment right
|
||||
[node name="NorthWall" type="Node3D" parent="."]
|
||||
instance = ExtResource("1")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.28, 0, -2.56)
|
||||
|
||||
; --- West Wall (X=-2.56, along Z from -2.56 to +2.56) ---
|
||||
; Rotated 90° Y so width runs along Z instead of X
|
||||
; Basis: local X → global -Z, local Z → global X
|
||||
[node name="WestLower" type="Node3D" parent="."]
|
||||
instance = ExtResource("1")
|
||||
transform = Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, -2.56, 0, -1.28)
|
||||
|
||||
[node name="WestUpper" type="Node3D" parent="."]
|
||||
instance = ExtResource("1")
|
||||
transform = Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, -2.56, 0, 1.28)
|
||||
|
||||
; --- East Wall (X=2.56, along Z from -2.56 to +2.56) ---
|
||||
; Rotated 90° Y so width runs along Z, thickness along -X
|
||||
[node name="EastLower" type="Node3D" parent="."]
|
||||
instance = ExtResource("1")
|
||||
transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 2.56, 0, -1.28)
|
||||
|
||||
[node name="EastUpper" type="Node3D" parent="."]
|
||||
instance = ExtResource("1")
|
||||
transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 2.56, 0, 1.28)
|
||||
|
||||
; ============ INTERIOR ============
|
||||
|
||||
; Pillar at room center
|
||||
[node name="Pillar" type="Node3D" parent="."]
|
||||
instance = ExtResource("11")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)
|
||||
|
||||
; Beam overhead spanning the room
|
||||
[node name="Beam" type="Node3D" parent="."]
|
||||
instance = ExtResource("13")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.40, 0)
|
||||
|
||||
; Accent red panel on south wall straight segment
|
||||
[node name="AccentRed" type="Node3D" parent="."]
|
||||
instance = ExtResource("17")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.28, 1.28, 2.52)
|
||||
|
||||
; Accent blue panel on east wall upper segment
|
||||
[node name="AccentBlue" type="Node3D" parent="."]
|
||||
instance = ExtResource("15")
|
||||
transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 2.52, 1.28, 0)
|
||||
|
||||
; ============ LIGHTING ============
|
||||
|
||||
; --- WorldEnvironment: skybox + ambient ---
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Env")
|
||||
|
||||
; --- DirectionalLight: sun/moon key light from high angle ---
|
||||
; Tilted ~45° down, rotated ~30° Y for directional angle
|
||||
[node name="SunLight" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(0.866, 0, -0.5, -0.354, 0.707, -0.612, 0.354, 0.707, 0.612, 0, 5, 0)
|
||||
light_energy = 1.2
|
||||
light_indirect_energy = 0.8
|
||||
light_color = Color(1.0, 0.95, 0.9)
|
||||
shadow_enabled = true
|
||||
light_bake_mode = 2
|
||||
directional_shadow_max_distance = 30.0
|
||||
directional_shadow_split_1 = 0.1
|
||||
directional_shadow_split_2 = 0.3
|
||||
directional_shadow_split_3 = 0.6
|
||||
directional_shadow_blend_splits = true
|
||||
|
||||
; --- OmniLight: warm interior fill ---
|
||||
[node name="FillLight" type="OmniLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 2.4, 1.5)
|
||||
light_energy = 0.4
|
||||
light_indirect_energy = 0.5
|
||||
light_color = Color(1.0, 0.85, 0.7)
|
||||
light_bake_mode = 2
|
||||
omni_range = 6.0
|
||||
omni_attenuation = 0.8
|
||||
shadow_enabled = false
|
||||
|
||||
; --- ReflectionProbe for interior specular reflections ---
|
||||
[node name="ReflectionProbe" type="ReflectionProbe" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.28, 0)
|
||||
box_projection = true
|
||||
interior = true
|
||||
extents = Vector3(2.8, 1.4, 2.8)
|
||||
intensity = 1.0
|
||||
max_distance = 10.0
|
||||
|
||||
; --- LightmapGI: baked global illumination ---
|
||||
[node name="LightmapGI" type="LightmapGI" parent="."]
|
||||
bounces = 3
|
||||
bounce_indirect_energy = 1.0
|
||||
texel_scale = 1.0
|
||||
texel_subdiv = 4
|
||||
max_texture_size = 2048
|
||||
use_denoiser = true
|
||||
denoiser_strength = 0.0
|
||||
interior = true
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/wall_concrete_02.tres" id="1"]
|
||||
|
||||
[node name="Pillar01" type="CSGBox3D" parent="."]
|
||||
size = Vector3(0.64, 2.56, 0.64)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
@@ -0,0 +1,17 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/wall_concrete_01.tres" id="1"]
|
||||
|
||||
[node name="WallCorner01" type="CSGCombiner3D" parent="."]
|
||||
use_collision = false
|
||||
[node name="WallA" type="CSGBox3D" parent="WallCorner01"]
|
||||
operation = 0
|
||||
size = Vector3(2.56, 2.56, 0.16)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.08)
|
||||
[node name="WallB" type="CSGBox3D" parent="WallCorner01"]
|
||||
operation = 0
|
||||
size = Vector3(0.16, 2.56, 2.56)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
transform = Transform3D(0, 0, -1, 0, 1, 0, 1, 0, 0, 0.08, 0, 0)
|
||||
@@ -0,0 +1,15 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/wall_concrete_01.tres" id="1"]
|
||||
|
||||
[node name="WallDoorway01" type="CSGCombiner3D" parent="."]
|
||||
use_collision = false
|
||||
[node name="MainWall" type="CSGBox3D" parent="WallDoorway01"]
|
||||
operation = 0
|
||||
size = Vector3(2.56, 2.56, 0.16)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
[node name="DoorCutout" type="CSGBox3D" parent="WallDoorway01"]
|
||||
operation = 1
|
||||
size = Vector3(0.8, 2.0, 0.2)
|
||||
use_collision = true
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.28, 0)
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/wall_concrete_01.tres" id="1"]
|
||||
|
||||
[node name="WallEndcap01" type="CSGBox3D" parent="."]
|
||||
size = Vector3(0.32, 2.56, 0.16)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/wall_concrete_01.tres" id="1"]
|
||||
|
||||
[node name="WallStraight01" type="CSGBox3D" parent="."]
|
||||
size = Vector3(2.56, 2.56, 0.16)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
@@ -0,0 +1,15 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
[ext_resource type="Material" path="res://assets/materials/wall_concrete_01.tres" id="1"]
|
||||
|
||||
[node name="WallWindow01" type="CSGCombiner3D" parent="."]
|
||||
use_collision = false
|
||||
[node name="MainWall" type="CSGBox3D" parent="WallWindow01"]
|
||||
operation = 0
|
||||
size = Vector3(2.56, 2.56, 0.16)
|
||||
material = ExtResource("1")
|
||||
use_collision = true
|
||||
[node name="WindowCutout" type="CSGBox3D" parent="WallWindow01"]
|
||||
operation = 1
|
||||
size = Vector3(1.2, 0.8, 0.2)
|
||||
use_collision = true
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.3, 0)
|
||||
Reference in New Issue
Block a user