Files
tactical-shooter/client/assets/materials/generate_materials.py
T
shawn d631ff784a 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.
2026-07-01 00:10:19 -04:00

145 lines
5.0 KiB
Python

#!/usr/bin/env python3
"""
Generate Godot 4 .tres material resource files for the modular art kit.
Godot 4 text resource format:
[ext_resource type="Texture2D" path="res://..." id="1"]
[resource]
property = value
"""
import os
MATERIALS_DIR = os.path.expanduser("/home/oplabs/tactical-shooter/client/assets/materials")
TEX_BASE = "res://assets/textures"
def make_tres(name, props):
textures = props.get("textures", {})
load_steps = 1 + len(textures)
lines = [
f'[gd_resource type="StandardMaterial3D" load_steps={load_steps} format=3]',
]
ext_id = 1
ext_map = {}
for slot, rel_path in textures.items():
eid = str(ext_id)
path = f"{TEX_BASE}/{name}/{rel_path}"
lines.append(f'[ext_resource type="Texture2D" path="{path}" id="{eid}"]')
ext_map[slot] = eid
ext_id += 1
lines.append("")
lines.append("[resource]")
# Albedo
if "albedo" in ext_map:
lines.append(f'albedo_texture = ExtResource("{ext_map["albedo"]}")')
# Normal map
if "normal" in ext_map:
lines.append("normal_enabled = true")
lines.append(f'normal_texture = ExtResource("{ext_map["normal"]}")')
if "normal_scale" in props:
lines.append(f"normal_scale = {props['normal_scale']}")
# Roughness
lines.append(f"roughness = {props.get('roughness', 0.5)}")
if "roughness" in ext_map:
lines.append(f'roughness_texture = ExtResource("{ext_map["roughness"]}")')
# Metallic
lines.append(f"metallic = {props.get('metallic', 0.0)}")
if "metallic" in ext_map:
lines.append(f'metallic_texture = ExtResource("{ext_map["metallic"]}")')
# Texture filter (1 = linear)
if "texture_filter" in props:
lines.append(f"texture_filter = {props['texture_filter']}")
# UV tiling
if "uv_scale" in props:
s = props["uv_scale"]
lines.append(f'uv1_scale = Vector3({s[0]}, {s[1]}, {s[2]})')
content = "\n".join(lines) + "\n"
path = os.path.join(MATERIALS_DIR, f"{name}.tres")
with open(path, "w") as f:
f.write(content)
print(f" Created {name}.tres ({len(textures)} textures, {load_steps} steps)")
def generate():
os.makedirs(MATERIALS_DIR, exist_ok=True)
print("Generating material .tres files...")
# 1 - Wall concrete 01: primary wall, clean light concrete
make_tres("wall_concrete_01", {
"textures": {"albedo": "basecolor.png", "normal": "normal.png",
"roughness": "roughness.png", "metallic": "metallic.png"},
"roughness": 0.85, "metallic": 0.0, "normal_scale": 0.5,
"texture_filter": 1,
"uv_scale": (1.0, 1.0, 1.0),
})
# 2 - Wall concrete 02: darker accent concrete
make_tres("wall_concrete_02", {
"textures": {"albedo": "basecolor.png", "normal": "normal.png",
"roughness": "roughness.png", "metallic": "metallic.png"},
"roughness": 0.75, "metallic": 0.0, "normal_scale": 0.4,
"texture_filter": 1,
"uv_scale": (1.0, 1.0, 1.0),
})
# 3 - Floor tile 01: ceramic tile interior
make_tres("floor_tile_01", {
"textures": {"albedo": "basecolor.png", "normal": "normal.png",
"roughness": "roughness.png", "metallic": "metallic.png"},
"roughness": 0.6, "metallic": 0.0, "normal_scale": 1.0,
"texture_filter": 1,
"uv_scale": (2.0, 2.0, 1.0), # repeat to show tile grid
})
# 4 - Floor concrete 01: industrial floor
make_tres("floor_concrete_01", {
"textures": {"albedo": "basecolor.png", "normal": "normal.png",
"roughness": "roughness.png", "metallic": "metallic.png"},
"roughness": 0.9, "metallic": 0.0, "normal_scale": 0.8,
"texture_filter": 1,
"uv_scale": (2.0, 2.0, 1.0),
})
# 5 - Metal structural 01: structural beams
make_tres("metal_structural_01", {
"textures": {"albedo": "basecolor.png", "normal": "normal.png",
"roughness": "roughness.png", "metallic": "metallic.png"},
"roughness": 0.3, "metallic": 1.0, "normal_scale": 0.3,
"texture_filter": 1,
"uv_scale": (1.0, 1.0, 1.0),
})
# 6 - Accent team blue: CT-side colored panels
make_tres("accent_team_blue", {
"textures": {"albedo": "basecolor.png", "normal": "normal.png",
"roughness": "roughness.png", "metallic": "metallic.png"},
"roughness": 0.35, "metallic": 0.5, "normal_scale": 0.3,
"texture_filter": 1,
"uv_scale": (1.0, 1.0, 1.0),
})
# 7 - Accent team red: T-side colored panels
make_tres("accent_team_red", {
"textures": {"albedo": "basecolor.png", "normal": "normal.png",
"roughness": "roughness.png", "metallic": "metallic.png"},
"roughness": 0.35, "metallic": 0.5, "normal_scale": 0.3,
"texture_filter": 1,
"uv_scale": (1.0, 1.0, 1.0),
})
print("\nDone — 7 material .tres files created.")
if __name__ == "__main__":
generate()