Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore unversioniert; letztere sind unter ../backups gesichert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
4 KiB
Python
61 lines
4 KiB
Python
"""Render authored, periodic 4D wood grain at native 4096px in Blender.
|
|
This is a procedural material bake, not an enlargement of a bitmap.
|
|
The torus coordinate mapping makes the material seamless on all four edges.
|
|
"""
|
|
import bpy, math, json
|
|
from pathlib import Path
|
|
PROJECT=Path(__file__).resolve().parents[2]
|
|
out=PROJECT/'assets/materials/phase10'
|
|
scene=bpy.data.scenes.new('Bark_PBR_4K');bpy.context.window.scene=scene
|
|
scene.render.engine='CYCLES';scene.cycles.samples=1
|
|
scene.render.resolution_x=4096;scene.render.resolution_y=4096;scene.render.resolution_percentage=100
|
|
scene.render.image_settings.file_format='PNG';scene.render.image_settings.color_mode='RGB';scene.render.image_settings.color_depth='8'
|
|
scene.render.image_settings.compression=90;scene.render.dither_intensity=0
|
|
scene.view_settings.view_transform='Standard';scene.view_settings.look='None'
|
|
scene.render.film_transparent=False
|
|
bpy.ops.mesh.primitive_plane_add(size=2)
|
|
plane=bpy.context.object;plane.name='Bark_material_bake_surface'
|
|
mat=bpy.data.materials.new('SW_4K_Sculpted_Oak');mat.use_nodes=True;plane.data.materials.append(mat)
|
|
n=mat.node_tree.nodes;n.clear();links=mat.node_tree.links
|
|
def node(kind): return n.new(kind)
|
|
def mathnode(op,a,b=None):
|
|
obj=node('ShaderNodeMath');obj.operation=op
|
|
if isinstance(a,(float,int)): obj.inputs[0].default_value=a
|
|
else: links.new(a,obj.inputs[0])
|
|
if b is not None:
|
|
if isinstance(b,(float,int)):obj.inputs[1].default_value=b
|
|
else:links.new(b,obj.inputs[1])
|
|
return obj.outputs[0]
|
|
uv=node('ShaderNodeTexCoord');split=node('ShaderNodeSeparateXYZ');links.new(uv.outputs['UV'],split.inputs[0])
|
|
u=mathnode('MULTIPLY',split.outputs['X'],math.tau)
|
|
v=mathnode('MULTIPLY',split.outputs['Y'],math.tau)
|
|
co=node('ShaderNodeCombineXYZ')
|
|
links.new(mathnode('MULTIPLY',mathnode('COSINE',u),10),co.inputs['X'])
|
|
links.new(mathnode('MULTIPLY',mathnode('SINE',u),10),co.inputs['Y'])
|
|
links.new(mathnode('MULTIPLY',mathnode('COSINE',v),.7),co.inputs['Z'])
|
|
grain=node('ShaderNodeTexNoise');grain.noise_dimensions='4D'
|
|
links.new(co.outputs[0],grain.inputs['Vector']);links.new(mathnode('MULTIPLY',mathnode('SINE',v),.7),grain.inputs['W'])
|
|
grain.inputs['Scale'].default_value=2.6;grain.inputs['Detail'].default_value=7;grain.inputs['Roughness'].default_value=.73
|
|
height=node('ShaderNodeValToRGB')
|
|
height.color_ramp.elements[0].position=.27;height.color_ramp.elements[0].color=(.07,.07,.07,1)
|
|
height.color_ramp.elements[1].position=.67;height.color_ramp.elements[1].color=(.8,.8,.8,1)
|
|
height.color_ramp.elements.new(.43).color=(.14,.14,.14,1)
|
|
height.color_ramp.elements.new(.51).color=(.55,.55,.55,1)
|
|
links.new(grain.outputs['Fac'],height.inputs[0])
|
|
emit=node('ShaderNodeEmission');output=node('ShaderNodeOutputMaterial');links.new(emit.outputs[0],output.inputs['Surface'])
|
|
links.new(height.outputs[0],emit.inputs['Color'])
|
|
bpy.ops.object.camera_add(location=(0,0,3));camera=bpy.context.object;camera.data.type='ORTHO';camera.data.ortho_scale=2;scene.camera=camera
|
|
scene.render.filepath=str(out/'oak-height-4k.png');bpy.ops.render.render(write_still=True)
|
|
colors=node('ShaderNodeValToRGB')
|
|
def linear(hexcolor):
|
|
rgb=[int(hexcolor[i:i+2],16)/255 for i in (0,2,4)]
|
|
return tuple(c/12.92 if c<=.04045 else ((c+.055)/1.055)**2.4 for c in rgb)+(1,)
|
|
colors.color_ramp.elements[0].position=.0;colors.color_ramp.elements[0].color=linear('302B23')
|
|
colors.color_ramp.elements[1].position=1;colors.color_ramp.elements[1].color=linear('B09A6D')
|
|
colors.color_ramp.elements.new(.18).color=linear('4B3C2A')
|
|
colors.color_ramp.elements.new(.51).color=linear('766041')
|
|
colors.color_ramp.elements.new(.74).color=linear('94855D')
|
|
links.new(height.outputs[0],colors.inputs[0]);links.new(colors.outputs[0],emit.inputs['Color'])
|
|
scene.render.filepath=str(out/'oak-albedo-4k.png');bpy.ops.render.render(write_still=True)
|
|
bpy.data.libraries.write(str(PROJECT/'assets-source/phase10/oak-material-4k.blend'),{scene},fake_user=True,compress=True)
|
|
print('PBR_BAKE_PASS: two native 4096 x 4096 8-bit runtime maps; original seamless procedural material.')
|