0% found this document useful (0 votes)
9 views18 pages

Blender Material and Building Script

The document is a Blender Python script that creates a 3D scene, including a building, towers, gates, and flags, while applying various materials to these objects. It defines functions for creating materials, geometry, and scene setup, and utilizes Blender's API to manipulate objects and their properties. The script also includes functionality for adding details like windows and entrances, and it ensures that materials are assigned correctly to the corresponding objects.

Uploaded by

goat835628
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views18 pages

Blender Material and Building Script

The document is a Blender Python script that creates a 3D scene, including a building, towers, gates, and flags, while applying various materials to these objects. It defines functions for creating materials, geometry, and scene setup, and utilizes Blender's API to manipulate objects and their properties. The script also includes functionality for adding details like windows and entrances, and it ensures that materials are assigned correctly to the corresponding objects.

Uploaded by

goat835628
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

import bpy

import math
from mathutils import Vector

# ---------------------------
# Utility: Create/Reuse Material
# ---------------------------
def ensure_material(name, setup_fn):
mat = [Link](name)
if mat is None:
mat = [Link](name)
mat.use_nodes = True
nt = mat.node_tree
nodes = [Link]
links = [Link]
for n in nodes:
[Link](n)
output = [Link]("ShaderNodeOutputMaterial")
bsdf = [Link]("ShaderNodeBsdfPrincipled")
[Link] = (-200, 0)
[Link]([Link]["BSDF"], [Link]["Surface"])
setup_fn(nt, bsdf, output)
return mat

# ---------------------------
# Materials
# ---------------------------

def mat_wall():
def setup(nt, bsdf, output):
[Link]["Base Color"].default_value = (0.8, 0.75, 0.7, 1.0)
[Link]["Roughness"].default_value = 0.8
return ensure_material("MAT_Wall", setup)

def mat_roof():
def setup(nt, bsdf, output):
[Link]["Base Color"].default_value = (0.2, 0.05, 0.05, 1.0)
[Link]["Roughness"].default_value = 0.6
return ensure_material("MAT_Roof", setup)

def mat_wood():
def setup(nt, bsdf, output):
tex = [Link]("ShaderNodeTexNoise")
[Link] = (-400, 0)
[Link]["Scale"].default_value = 10
[Link]([Link]["Color"], [Link]["Base Color"])
[Link]["Roughness"].default_value = 0.5
return ensure_material("MAT_Wood", setup)

def mat_metal_dark():
def setup(nt, bsdf, output):
[Link]["Base Color"].default_value = (0.08, 0.08, 0.08, 1.0)
[Link]["Metallic"].default_value = 0.7
[Link]["Roughness"].default_value = 0.35
return ensure_material("MAT_MetalDark", setup)

def mat_target_paint():
def setup(nt, bsdf, output):
wave = [Link]("ShaderNodeTexWave")
[Link] = (-500, 0)
wave.wave_type = "RINGS"
wave.rings_direction = "SPHERICAL" # ✅ Blender 4.5-safe
[Link]["Scale"].default_value = 3.5

ramp = [Link]("ShaderNodeValToRGB")
[Link] = (-250, 0)
ramp.color_ramp.elements[0].color = (0.05, 0.85, 0.05, 1)
ramp.color_ramp.elements[1].color = (0.25, 0.25, 0.25, 1)
ramp.color_ramp.elements[1].position = 0.55

[Link]([Link]["Color"], [Link]["Fac"])
[Link]([Link]["Color"], [Link]["Base Color"])
[Link]["Roughness"].default_value = 0.6
return ensure_material("MAT_TargetPaint", setup)

# ---------------------------
# Geometry Builders
# ---------------------------

def create_building():
[Link].primitive_cube_add(size=2, location=(0, 1, 1))
b = [Link].active_object
[Link] = (6, 6, 3)
[Link](mat_wall())

# Roof
[Link].primitive_cone_add(vertices=4, radius1=8, depth=2, location=(0, 1,
4.5))
r = [Link].active_object
r.rotation_euler = (0, 0, [Link](45))
[Link](mat_roof())

def create_tower(x, y):


[Link].primitive_cylinder_add(vertices=16, radius=1.2, depth=8,
location=(x, y, 4))
t = [Link].active_object
[Link](mat_wall())
# Roof
[Link].primitive_cone_add(vertices=16, radius1=1.5, depth=2, location=(x,
y, 8))
roof = [Link].active_object
[Link](mat_roof())

def create_gate():
[Link].primitive_cube_add(size=2, location=(0, -6, 2))
g = [Link].active_object
[Link] = (4, 1, 3)
[Link](mat_wood())

def create_target(x, y):


[Link].primitive_cylinder_add(vertices=32, radius=0.7, depth=0.2,
location=(x, y, 1))
tgt = [Link].active_object
[Link](mat_target_paint())

# ---------------------------
# Scene Setup
# ---------------------------
def clear_scene():
[Link].select_all(action='SELECT')
[Link](use_global=False)

def build_academy():
clear_scene()
create_building()
create_tower(8, 8)
create_tower(-8, 8)
create_tower(8, -6)
create_tower(-8, -6)
create_gate()
create_target(3, -10)
create_target(-3, -10)

# Lights
[Link].light_add(type="SUN", radius=1, location=(10, -10, 15))
sun = [Link].active_object
[Link] = 5

# Camera
[Link].camera_add(location=(20, -20, 12), rotation=([Link](60),
0, [Link](45)))
cam = [Link].active_object
[Link] = cam

# Render engine
[Link] = "BLENDER_EEVEE_NEXT" # ✅ Blender 4.5 safe

# ---------------------------
# Run
# ---------------------------
build_academy()

import bpy
import math

# =========================
# MATERIALS
# =========================
def create_material(name, base_color, metallic=0.0, roughness=0.5):
mat = [Link](name)
mat.use_nodes = True
bsdf = mat.node_tree.nodes["Principled BSDF"]
[Link]["Base Color"].default_value = (*base_color, 1)
[Link]["Metallic"].default_value = metallic
[Link]["Roughness"].default_value = roughness
return mat

# Define materials
wall_mat = create_material("Wall_Mat", (0.95, 0.75, 0.55), 0.0, 0.7) # Sandy
walls
roof_mat = create_material("Roof_Mat", (0.8, 0.1, 0.1), 0.1, 0.4) # Red
roof
stone_mat = create_material("Stone_Mat", (0.4, 0.4, 0.45), 0.0, 0.6) # Grey
stone
flag_mat = create_material("Flag_Mat", (1.0, 0.1, 0.1), 0.0, 0.3) # Red
flags
# =========================
# FLAGS
# =========================
def add_flag(location, height=6):
# Flag pole
[Link].primitive_cylinder_add(radius=0.05, depth=height,
location=location)
pole = [Link].active_object
[Link](stone_mat)

# Flag (plane)
[Link].primitive_plane_add(size=2, location=(location[0]+1, location[1],
location[2]+height/2))
flag = [Link].active_object
[Link](flag_mat)
[Link][1] = 0.3 # make it rectangular

# Add wave modifier (cloth effect look)


[Link](name="Wave", type="WAVE")

# =========================
# WINDOWS
# =========================
def add_window(location, size=(1, 0.1, 1.5)):
[Link].primitive_cube_add(location=location)
window = [Link].active_object
[Link] = size
[Link](stone_mat)

# =========================
# APPLY MATERIALS TO OBJECTS
# =========================
def apply_materials():
for obj in [Link]:
if "Cube" in [Link]: # Main building
[Link](wall_mat)
elif "Cone" in [Link]: # Roofs
[Link](roof_mat)
elif "Cylinder" in [Link]: # Towers
[Link](stone_mat)

# =========================
# BUILD DETAILS
# =========================
def add_details():
# Apply materials
apply_materials()

# Add flags on two towers


add_flag(location=(6, 6, 12))
add_flag(location=(-6, 6, 12))

# Add windows
add_window(location=(0, 2.6, 3))
add_window(location=(0, -2.6, 3))

# Add ground plane


[Link].primitive_plane_add(size=60, location=(0,0,0))
ground = [Link].active_object
[Link](create_material("Ground_Mat", (0.2, 0.6, 0.2),
0.0, 0.8)) # Green grass

# =========================
# RUN
# =========================
add_details()

import bpy

# =========================
# ENTRANCE CUT (BOOLEAN)
# =========================
def add_entrance(building_name="Cube"):
# Create entrance shape (cube)
[Link].primitive_cube_add(size=2, location=(0, 2.6, 1.5))
entrance = [Link].active_object
[Link][0] = 1.5 # width
[Link][1] = 0.2 # depth
[Link][2] = 2.0 # height
[Link] = "Entrance_Cutter"

# Select building
building = [Link](building_name)
if building:
mod_bool = [Link](name="Entrance_Hole", type="BOOLEAN")
mod_bool.operation = 'DIFFERENCE'
mod_bool.object = entrance
[Link].view_layer.[Link] = building
[Link].modifier_apply(modifier=mod_bool.name)

# Delete cutter cube


[Link](entrance, do_unlink=True)

# =========================
# FLAGS
# =========================
def add_flag(location, height=6):
# Flag pole
[Link].primitive_cylinder_add(radius=0.05, depth=height,
location=location)
pole = [Link].active_object
[Link] = "FlagPole"

# Flag banner
[Link].primitive_plane_add(size=2, location=(location[0]+1, location[1],
location[2]+height/2))
flag = [Link].active_object
[Link] = "Flag"
[Link][1] = 0.3

# Add waving effect


[Link](name="Wave", type="WAVE")

# =========================
# RUN SCRIPT
# =========================
# Cut entrance in the front cube (main building usually named "Cube")
add_entrance("Cube")

# Add two flags on the towers


add_flag(location=(6, 6, 12))
add_flag(location=(-6, 6, 12))

import bpy

# =========================
# MATERIAL CREATOR
# =========================
def make_material(name, color):
mat = [Link](name=name)
mat.use_nodes = True
bsdf = mat.node_tree.nodes["Principled BSDF"]
[Link]["Base Color"].default_value = (*color, 1) # RGBA
[Link]["Roughness"].default_value = 0.6
return mat

# =========================
# CREATE MATERIALS
# =========================
mat_wall = make_material("Wall_Mat", (0.95, 0.85, 0.7)) # beige walls
mat_roof = make_material("Roof_Mat", (0.8, 0.2, 0.05)) # red roof
mat_wood = make_material("Wood_Mat", (0.3, 0.15, 0.05)) # dark brown
mat_flag = make_material("Flag_Mat", (0.8, 0.1, 0.1)) # bright red
mat_ground = make_material("Ground_Mat", (0.4, 0.6, 0.3)) # green grass

# =========================
# ASSIGN MATERIALS
# =========================
def assign_material(obj_name, mat):
obj = [Link](obj_name)
if obj:
if [Link]:
[Link][0] = mat
else:
[Link](mat)

# Assign to main building


assign_material("Cube", mat_wall)

# Assign to towers
for obj_name in ["Cylinder", "Cylinder.001", "Cylinder.002", "Cylinder.003"]:
if [Link](obj_name):
assign_material(obj_name, mat_wall)

# Assign to roofs (cones)


for obj_name in ["Cone", "Cone.001", "Cone.002", "Cone.003"]:
if [Link](obj_name):
assign_material(obj_name, mat_roof)

# Assign entrance frame (optional if exists)


assign_material("Entrance_Frame", mat_wood)

# Assign flags
for obj_name in ["Flag", "Flag.001"]:
if [Link](obj_name):
assign_material(obj_name, mat_flag)
# Assign ground
assign_material("Plane", mat_ground)
assign_material("Plane.002", mat_ground)

import bpy

# =========================
# MATERIAL CREATOR
# =========================
def make_material(name, color):
if name in [Link]:
return [Link][name]
mat = [Link](name=name)
mat.use_nodes = True
bsdf = mat.node_tree.nodes["Principled BSDF"]
[Link]["Base Color"].default_value = (*color, 1) # RGBA
[Link]["Roughness"].default_value = 0.6
return mat

# =========================
# CREATE MATERIALS
# =========================
mat_wall = make_material("Wall_Mat", (0.95, 0.85, 0.7)) # beige walls
mat_roof = make_material("Roof_Mat", (0.8, 0.2, 0.05)) # red roof
mat_wood = make_material("Wood_Mat", (0.3, 0.15, 0.05)) # dark brown
mat_flag = make_material("Flag_Mat", (0.8, 0.1, 0.1)) # bright red
mat_ground = make_material("Ground_Mat", (0.4, 0.6, 0.3)) # green grass

# =========================
# AUTO ASSIGN MATERIALS
# =========================
for obj in [Link]:
if [Link] == 'MESH':
name = [Link]()
if "cone" in name: # roofs
[Link]()
[Link](mat_roof)
elif "cylinder" in name: # towers
[Link]()
[Link](mat_wall)
elif "cube" in name: # main building blocks
[Link]()
[Link](mat_wall)
elif "plane" in name: # ground
[Link]()
[Link](mat_ground)
elif "flag" in name: # flags
[Link]()
[Link](mat_flag)

# =========================
# SWITCH TO MATERIAL PREVIEW MODE
# =========================
for area in [Link]:
if [Link] == 'VIEW_3D':
for space in [Link]:
if [Link] == 'VIEW_3D':
[Link] = 'MATERIAL' # switch viewport shading
import bpy

# Delete old objects


[Link].select_all(action='SELECT')
[Link](use_global=False)

# Ground plane
[Link].primitive_plane_add(size=40, location=(0,0,0))
ground = [Link].active_object
mat_ground = [Link]("Ground")
mat_ground.diffuse_color = (0.1, 0.5, 0.1, 1) # green grass
[Link](mat_ground)

# Tower base + tiers


heights = [6, 5, 4, 3] # heights of each tier
radii = [6, 5, 4, 3] # radius of each tier
z = 0
for i, (h, r) in enumerate(zip(heights, radii)):
[Link].primitive_cylinder_add(vertices=32, radius=r, depth=h,
location=(0,0,z+h/2))
cyl = [Link].active_object
mat = [Link](f"Tier{i}")
mat.diffuse_color = (0.9, 0.9, 0.9, 1) # off-white
[Link](mat)

# Roof
[Link].primitive_cone_add(vertices=32, radius1=r*1.2, depth=1.5,
location=(0,0,z+h+0.75))
roof = [Link].active_object
mat_roof = [Link](f"Roof{i}")
mat_roof.diffuse_color = (0.8, 0.2, 0.1, 1) # red-orange
[Link](mat_roof)

z += h
import bpy
import math

# Cleanup old academy objects if re-run


for obj in [Link]:
if [Link]("Academy") or [Link]("Entrance") or
[Link]("Window") or [Link]("Banner"):
[Link](obj, do_unlink=True)

# --- Materials ---


def get_material(name, color):
if name not in [Link]:
mat = [Link](name)
mat.use_nodes = True
bsdf = mat.node_tree.[Link]("Principled BSDF")
[Link]["Base Color"].default_value = (*color, 1)
return mat
return [Link][name]

mat_wall = get_material("MAT_Wall", (0.95, 0.8, 0.6)) # light beige


mat_roof = get_material("MAT_Roof", (0.8, 0.1, 0.1)) # red roof
mat_trim = get_material("MAT_Trim", (0.7, 0.3, 0.1)) # wooden trim
mat_glass = get_material("MAT_Glass", (0.4, 0.6, 0.9)) # window
mat_grass = get_material("MAT_Grass", (0.1, 0.5, 0.1)) # ground
# --- Main Base Building ---
[Link].primitive_cylinder_add(radius=6, depth=8, location=(0,0,4))
main = [Link].active_object
[Link] = "Academy_Main"
[Link](mat_wall)

# --- Roof on top ---


[Link].primitive_cone_add(radius1=7, depth=2, location=(0,0,9))
roof = [Link].active_object
[Link] = "Academy_Roof"
[Link](mat_roof)

# --- Roof Overhang trim ---


[Link].primitive_torus_add(major_radius=6.8, minor_radius=0.2,
location=(0,0,8))
trim = [Link].active_object
[Link] = "Academy_RoofTrim"
[Link](mat_trim)

# --- Entrance arch ---


[Link].primitive_cube_add(size=2, location=(0, -6, 1.5))
door_cut = [Link].active_object
door_cut.name = "Entrance_Cutter"
mod = [Link]("DoorBoolean", 'BOOLEAN')
[Link] = 'DIFFERENCE'
[Link] = door_cut
[Link].view_layer.[Link] = main
[Link].modifier_apply(modifier=[Link])
[Link](door_cut, do_unlink=True)

# --- Entrance Banner ---


[Link].primitive_plane_add(size=3, location=(0,-6.1,4))
banner = [Link].active_object
[Link] = "Entrance_Banner"
[Link][1] = 0.5
[Link](mat_roof)

# --- Windows (around cylinder) ---


for i in range(0, 360, 45):
rad = [Link](i)
x = 5.5 * [Link](rad)
y = 5.5 * [Link](rad)
z = 4
[Link].primitive_plane_add(size=1, location=(x,y,z))
win = [Link].active_object
[Link] = f"Window_{i}"
win.rotation_euler[2] = rad
[Link](mat_glass)

# --- Ground plane with grass ---


[Link].primitive_plane_add(size=40, location=(0,0,0))
ground = [Link].active_object
[Link] = "Academy_Ground"
[Link](mat_grass)

# Add a little noise for grass variation


ground_mod = [Link]("Displace", 'DISPLACE')
tex = [Link]("GrassNoise", 'CLOUDS')
ground_mod.texture = tex
ground_mod.strength = 0.3

import bpy
import math

# --- Cleanup previous objects ---


for obj in [Link]:
if [Link](("Entrance", "BannerArch", "NarutoBanner")):
[Link](obj, do_unlink=True)

# Re-get main building reference


main = [Link]("Academy_Main")

# --- Materials ---


def get_material(name, color, texture=False):
if name not in [Link]:
mat = [Link](name)
mat.use_nodes = True
bsdf = mat.node_tree.[Link]("Principled BSDF")
[Link]["Base Color"].default_value = (*color, 1)
if texture:
tex_img = mat.node_tree.[Link]("ShaderNodeTexImage")
# placeholder image slot for Naruto logo
mat.node_tree.[Link](tex_img.outputs["Color"], [Link]["Base
Color"])
return mat
return [Link][name]

mat_banner = get_material("MAT_Banner", (0.8, 0.1, 0.1)) # red banner

# --- Arch Entrance (instead of cube) ---


[Link].primitive_cylinder_add(vertices=32, radius=1.2, depth=0.5,
location=(0,-6,1.2))
arch_cut = [Link].active_object
arch_cut.name = "Entrance_ArchCutter"
arch_cut.scale[2] = 1.8

# Boolean difference for arch hole


mod = [Link]("ArchBoolean", 'BOOLEAN')
[Link] = 'DIFFERENCE'
[Link] = arch_cut
[Link].view_layer.[Link] = main
[Link].modifier_apply(modifier=[Link])
[Link](arch_cut, do_unlink=True)

# --- Naruto Banner on Tower ---


[Link].primitive_plane_add(size=4, location=(0, -5.9, 6))
banner = [Link].active_object
[Link] = "NarutoBanner"
[Link][0] = 1.2 # wide
[Link][1] = 0.05 # thin depth
banner.rotation_euler[0] = [Link](90)

[Link](mat_banner)

# Optional: slight wave effect to look like cloth


mod = [Link]("Wave", "WAVE")
[Link] = 0.1
[Link] = 1.5
[Link] = 0.5

import bpy

# --- find the main building ---


main = [Link]("Academy_Main")
if not main:
raise RuntimeError("Academy_Main not found. Run your base building script
first.")

# delete old entrance cutter if exists


if "EntranceCutter" in [Link]:
[Link]([Link]["EntranceCutter"], do_unlink=True)

# dimensions
building_width = [Link].x
building_depth = [Link].y
building_height = [Link].z

# entrance proportions (adjustable)


door_width = building_width * 0.35 # 35% of width
door_height = building_height * 0.45 # 45% of height
door_depth = building_depth * 0.6 # cut deep enough

# add cube as cutter


[Link].primitive_cube_add(size=1, location=(0, building_depth/2 -
door_depth/2, door_height/2))
cutter = [Link].active_object
[Link] = "EntranceCutter"
[Link] = (door_width/2, door_depth/2, door_height/2)

# apply boolean modifier to main building


bool_mod = [Link](name="Entrance_Boolean", type='BOOLEAN')
bool_mod.operation = 'DIFFERENCE'
bool_mod.object = cutter

# apply modifier permanently


[Link].view_layer.[Link] = main
[Link].modifier_apply(modifier=bool_mod.name)

# delete cutter cube


[Link](cutter, do_unlink=True)

print("✅ Entrance hole added to the front of the building.")

import bpy

# --- find the main building ---


main = [Link]("Academy_Main")
if not main:
raise RuntimeError("Academy_Main not found. Run your base building script
first.")

# delete old entrance cutter if exists


if "EntranceCutter" in [Link]:
[Link]([Link]["EntranceCutter"], do_unlink=True)
if "EntranceFrame" in [Link]:
[Link]([Link]["EntranceFrame"], do_unlink=True)
# dimensions
building_width = [Link].x
building_depth = [Link].y
building_height = [Link].z

# entrance proportions (adjustable)


door_width = building_width * 0.35
door_height = building_height * 0.45
door_depth = building_depth * 0.6

# --- Cut entrance hole ---


[Link].primitive_cube_add(size=1, location=(0, building_depth/2 -
door_depth/2, door_height/2))
cutter = [Link].active_object
[Link] = "EntranceCutter"
[Link] = (door_width/2, door_depth/2, door_height/2)

# Boolean difference
bool_mod = [Link](name="Entrance_Boolean", type='BOOLEAN')
bool_mod.operation = 'DIFFERENCE'
bool_mod.object = cutter
[Link].view_layer.[Link] = main
[Link].modifier_apply(modifier=bool_mod.name)

# remove cutter
[Link](cutter, do_unlink=True)

# --- Add Entrance Frame ---


frame_thickness = 0.15 # adjust thickness
[Link].primitive_cube_add(size=1, location=(0, building_depth/2 + 0.01,
door_height/2))
frame = [Link].active_object
[Link] = "EntranceFrame"
[Link] = (door_width/2 + frame_thickness, 0.1, door_height/2 +
frame_thickness)

# make frame hollow (boolean again)


[Link].primitive_cube_add(size=1, location=(0, building_depth/2 + 0.02,
door_height/2))
inner = [Link].active_object
[Link] = "FrameInner"
[Link] = (door_width/2, 0.15, door_height/2)

bool_mod2 = [Link](name="Frame_Hollow", type='BOOLEAN')


bool_mod2.operation = 'DIFFERENCE'
bool_mod2.object = inner
[Link].view_layer.[Link] = frame
[Link].modifier_apply(modifier=bool_mod2.name)
[Link](inner, do_unlink=True)

# --- Material for frame ---


mat_frame = [Link](name="FrameMaterial")
mat_frame.diffuse_color = (0.1, 0.05, 0.02, 1.0) # dark brown/black wood
[Link](mat_frame)

print("✅ Entrance hole with visible frame added.")

import bpy
# --- Parameters for steps ---
step_count = 4 # number of steps
step_depth = 0.4 # how far each step extends
step_height = 0.15 # height of each step
step_width_factor = 1.2 # how much wider than the entrance

# find building & entrance frame


main = [Link]("Academy_Main")
frame = [Link]("EntranceFrame")

if not main or not frame:


raise RuntimeError("Academy_Main or EntranceFrame not found. Run previous
scripts first.")

# get entrance dimensions from frame


door_width = [Link].x
door_bottom = [Link].z - [Link].z/2

# --- Create steps ---


for i in range(step_count):
[Link].primitive_cube_add(size=1,
location=(0, [Link].y/2 + (i+0.5)*step_depth,
door_bottom - (i+0.5)*step_height))
step = [Link].active_object
[Link] = f"DoorStep_{i+1}"
[Link] = (door_width/2 * step_width_factor, step_depth/2, step_height/2)

# assign stone material


if "StepMaterial" not in [Link]:
mat_step = [Link](name="StepMaterial")
mat_step.diffuse_color = (0.6, 0.6, 0.6, 1.0) # light stone gray
else:
mat_step = [Link]["StepMaterial"]
[Link](mat_step)

print("✅ Doorsteps added in front of entrance.")

import bpy

# Get or create a more realistic stone material


mat_name = "RealisticStone"
if mat_name not in [Link]:
mat = [Link](mat_name)
mat.use_nodes = True

# Clear default nodes


nodes = mat.node_tree.nodes
for node in nodes:
[Link](node)

# Create nodes
output = [Link](type="ShaderNodeOutputMaterial")
principled = [Link](type="ShaderNodeBsdfPrincipled")
noise = [Link](type="ShaderNodeTexNoise")
bump = [Link](type="ShaderNodeBump")
color_ramp = [Link](type="ShaderNodeValToRGB")

# Place nodes neatly


[Link] = (0, 0)
[Link] = (200, 0)
[Link] = (-600, 0)
color_ramp.location = (-400, 0)
[Link] = (-200, -200)

# Setup Noise Texture (rocky detail)


[Link]["Scale"].default_value = 20.0
[Link]["Detail"].default_value = 8.0
[Link]["Roughness"].default_value = 0.6

# Setup Color Ramp (gray variation)


color_ramp.color_ramp.elements[0].position = 0.3
color_ramp.color_ramp.elements[0].color = (0.5, 0.5, 0.5, 1) # dark gray
color_ramp.color_ramp.elements[1].position = 0.7
color_ramp.color_ramp.elements[1].color = (0.8, 0.8, 0.8, 1) # light gray

# Setup Principled BSDF


[Link]["Roughness"].default_value = 0.9
[Link]["Specular"].default_value = 0.2

# Link nodes
links = mat.node_tree.links
[Link]([Link]["Fac"], color_ramp.inputs["Fac"])
[Link](color_ramp.outputs["Color"], [Link]["Base Color"])
[Link]([Link]["Fac"], [Link]["Height"])
[Link]([Link]["Normal"], [Link]["Normal"])
[Link]([Link]["BSDF"], [Link]["Surface"])

else:
mat = [Link][mat_name]

# Apply to all steps


for obj in [Link]:
if [Link]("DoorStep_"):
if len([Link]) == 0:
[Link](mat)
else:
[Link][0] = mat

print("✅ Realistic stone material applied to steps.")

import bpy

# === Function to create a material ===


def create_material(name, setup_func):
if name not in [Link]:
mat = [Link](name)
mat.use_nodes = True
nodes = mat.node_tree.nodes
for node in nodes:
[Link](node)
setup_func(mat)
return [Link][name]

# === Wall Material (Stucco/Plaster) ===


def setup_wall(mat):
nodes = mat.node_tree.nodes
links = mat.node_tree.links

output = [Link]("ShaderNodeOutputMaterial")
principled = [Link]("ShaderNodeBsdfPrincipled")
noise = [Link]("ShaderNodeTexNoise")
bump = [Link]("ShaderNodeBump")
colorramp = [Link]("ShaderNodeValToRGB")

[Link] = (0,0)
[Link] = (200,0)
[Link] = (-600,0)
[Link] = (-400,0)
[Link] = (-200,-200)

# Noise for plaster


[Link]["Scale"].default_value = 8.0
[Link]["Detail"].default_value = 5.0

# Stucco color
colorramp.color_ramp.elements[0].color = (0.9, 0.85, 0.75, 1) # light beige
colorramp.color_ramp.elements[1].color = (0.75, 0.7, 0.6, 1) # dirtier beige

[Link]["Roughness"].default_value = 0.8
[Link]["Specular"].default_value = 0.25

[Link]([Link]["Fac"], [Link]["Fac"])
[Link]([Link]["Color"], [Link]["Base Color"])
[Link]([Link]["Fac"], [Link]["Height"])
[Link]([Link]["Normal"], [Link]["Normal"])
[Link]([Link]["BSDF"], [Link]["Surface"])

# === Roof Material (Ceramic Tiles) ===


def setup_roof(mat):
nodes = mat.node_tree.nodes
links = mat.node_tree.links

output = [Link]("ShaderNodeOutputMaterial")
principled = [Link]("ShaderNodeBsdfPrincipled")
wave = [Link]("ShaderNodeTexWave")
bump = [Link]("ShaderNodeBump")
colorramp = [Link]("ShaderNodeValToRGB")

[Link] = (0,0)
[Link] = (200,0)
[Link] = (-600,0)
[Link] = (-400,0)
[Link] = (-200,-200)

# Wavy roof tiles


[Link]["Scale"].default_value = 3.0
[Link]["Distortion"].default_value = 0.2

# Tile colors
colorramp.color_ramp.elements[0].color = (0.6, 0.1, 0.05, 1) # dark red
colorramp.color_ramp.elements[1].color = (0.8, 0.2, 0.1, 1) # lighter red

[Link]["Roughness"].default_value = 0.5
[Link]["Specular"].default_value = 0.3
[Link]([Link]["Color"], [Link]["Fac"])
[Link]([Link]["Color"], [Link]["Base Color"])
[Link]([Link]["Fac"], [Link]["Height"])
[Link]([Link]["Normal"], [Link]["Normal"])
[Link]([Link]["BSDF"], [Link]["Surface"])

# === Wooden Entrance Material ===


def setup_wood(mat):
nodes = mat.node_tree.nodes
links = mat.node_tree.links

output = [Link]("ShaderNodeOutputMaterial")
principled = [Link]("ShaderNodeBsdfPrincipled")
wave = [Link]("ShaderNodeTexWave")
bump = [Link]("ShaderNodeBump")
colorramp = [Link]("ShaderNodeValToRGB")

[Link] = (0,0)
[Link] = (200,0)
[Link] = (-600,0)
[Link] = (-400,0)
[Link] = (-200,-200)

[Link]["Scale"].default_value = 20.0
[Link]["Distortion"].default_value = 1.5

colorramp.color_ramp.elements[0].color = (0.3, 0.15, 0.05, 1) # dark brown


colorramp.color_ramp.elements[1].color = (0.6, 0.3, 0.1, 1) # lighter wood

[Link]["Roughness"].default_value = 0.7
[Link]["Specular"].default_value = 0.2

[Link]([Link]["Fac"], [Link]["Fac"])
[Link]([Link]["Color"], [Link]["Base Color"])
[Link]([Link]["Fac"], [Link]["Height"])
[Link]([Link]["Normal"], [Link]["Normal"])
[Link]([Link]["BSDF"], [Link]["Surface"])

# === Create Materials ===


wall_mat = create_material("StuccoWall", setup_wall)
roof_mat = create_material("CeramicRoof", setup_roof)
wood_mat = create_material("WoodEntrance", setup_wood)

# === Apply to Objects ===


for obj in [Link]:
if [Link]("Building"):
[Link]()
[Link](wall_mat)
elif [Link]("Tower"):
[Link]()
[Link](wall_mat)
elif [Link]("Roof"):
[Link]()
[Link](roof_mat)
elif "Entrance" in [Link] or "Door" in [Link]:
[Link]()
[Link](wood_mat)

print("✅ Applied realistic materials to Academy (walls, roof, entrance).")

import bpy

# ----------------------------
# Helper for materials
# ----------------------------
def ensure_mat(name, rgba, rough=0.6, metallic=0.0):
m = [Link](name)
if not m:
m = [Link](name=name)
m.use_nodes = True
bsdf = m.node_tree.[Link]("Principled BSDF")
[Link]["Base Color"].default_value = (*rgba[:3], 1.0)
[Link]["Roughness"].default_value = rough
[Link]["Metallic"].default_value = metallic
return m

# ----------------------------
# Materials
# ----------------------------
mat_tower = ensure_mat("MAT_Tower", (0.75, 0.65, 0.5)) # stone / brown
mat_roof = ensure_mat("MAT_TowerRoof", (0.8, 0.1, 0.1)) # red cone top

# ----------------------------
# Main building (must exist already)
# ----------------------------
main = [Link]("Academy_Main")
if not main:
raise RuntimeError("Academy_Main not found. Run base building script first.")

# ----------------------------
# Tower dimensions
# ----------------------------
tower_radius = [Link].x * 0.22 # slightly slimmer
tower_height = [Link].z * 1.6 # taller than before

# Towers closer (reduce side offset)


side_offset = tower_radius * 0.8

# Z base
base_z = [Link].z - [Link].z * 0.5 + tower_height * 0.5

# ----------------------------
# Left Tower
# ----------------------------
tower_x_left = [Link].x - [Link].x * 0.5 - side_offset
tower_y = [Link].y
[Link].primitive_cylinder_add(radius=tower_radius, depth=tower_height,
location=(tower_x_left, tower_y, base_z))
tower_left = [Link].active_object
tower_left.name = "Academy_Tower_Left"
tower_left.[Link](mat_tower)

# Add cone roof to left tower


roof_height = tower_height * 0.4
[Link].primitive_cone_add(radius1=tower_radius * 1.1, depth=roof_height,
location=(tower_x_left, tower_y, base_z +
tower_height * 0.5 + roof_height * 0.5))
roof_left = [Link].active_object
roof_left.name = "Academy_TowerRoof_Left"
roof_left.[Link](mat_roof)

# ----------------------------
# Right Tower
# ----------------------------
tower_x_right = [Link].x + [Link].x * 0.5 + side_offset
[Link].primitive_cylinder_add(radius=tower_radius, depth=tower_height,
location=(tower_x_right, tower_y, base_z))
tower_right = [Link].active_object
tower_right.name = "Academy_Tower_Right"
tower_right.[Link](mat_tower)

# Add cone roof to right tower


[Link].primitive_cone_add(radius1=tower_radius * 1.1, depth=roof_height,
location=(tower_x_right, tower_y, base_z +
tower_height * 0.5 + roof_height * 0.5))
roof_right = [Link].active_object
roof_right.name = "Academy_TowerRoof_Right"
roof_right.[Link](mat_roof)

print("✅ Taller, closer towers with red cone rooftops created.")

You might also like