diff --git a/data/simulation/debug/render.png b/data/simulation/debug/render.png index 4f030cf..09abcc6 100644 Binary files a/data/simulation/debug/render.png and b/data/simulation/debug/render.png differ diff --git a/setup/generateSets/render_robot.py b/setup/generateSets/render_robot.py index a72f12d..41dc6e3 100644 --- a/setup/generateSets/render_robot.py +++ b/setup/generateSets/render_robot.py @@ -1,3 +1,5 @@ +from unicodedata import name + import bpy import math import mathutils @@ -154,6 +156,65 @@ def create_or_get_material(name: str, fallback: str = "defaultPlastic") -> bpy.t bsdf.inputs["Base Color"].default_value = spec["baseColor"] bsdf.inputs["Roughness"].default_value = spec["roughness"] bsdf.inputs["Metallic"].default_value = spec["metallic"] + + if name == "wood" and mat.node_tree.nodes.get("WoodGrainMix") is None: + nodes = mat.node_tree.nodes + links = mat.node_tree.links + + texcoord = nodes.new("ShaderNodeTexCoord") + mapping = nodes.new("ShaderNodeMapping") + noise = nodes.new("ShaderNodeTexNoise") + wave = nodes.new("ShaderNodeTexWave") + ramp = nodes.new("ShaderNodeValToRGB") + mix = nodes.new("ShaderNodeMixRGB") + + texcoord.name = "WoodTexCoord" + mapping.name = "WoodMapping" + noise.name = "WoodNoise" + wave.name = "WoodWave" + ramp.name = "WoodRamp" + mix.name = "WoodGrainMix" + + texcoord.location = (-900, 0) + mapping.location = (-700, 0) + noise.location = (-700, -220) + wave.location = (-500, 0) + ramp.location = (-260, 0) + mix.location = (-60, 0) + + # statt extrem hoch: + mapping.inputs["Scale"].default_value = (1000.0, 1000.0, 1000.0) + wave.inputs["Scale"].default_value = 1.0 + noise.inputs["Scale"].default_value = 6.0 + wave.inputs["Distortion"].default_value = 3.0 + + # und wichtig: Wave Fac statt Color verwenden + links.new(wave.outputs["Fac"], ramp.inputs["Fac"]) + + bump = nodes.new("ShaderNodeBump") + bump.location = (120, -160) + bump.inputs["Strength"].default_value = 0.4 + + links.new(ramp.outputs["Color"], bump.inputs["Height"]) + links.new(bump.outputs["Normal"], bsdf.inputs["Normal"]) + + ramp.color_ramp.elements[0].position = 0.53 + ramp.color_ramp.elements[1].position = 0.58 + + mix.blend_type = "MIX" + mix.inputs["Fac"].default_value = 0.08 + mix.inputs["Color1"].default_value = spec["baseColor"] + mix.inputs["Color2"].default_value = (0.74, 0.58, 0.50, 1.0) + + + links.new(texcoord.outputs["Object"], mapping.inputs["Vector"]) + links.new(mapping.outputs["Vector"], noise.inputs["Vector"]) + links.new(noise.outputs["Fac"], wave.inputs["Distortion"]) + links.new(mapping.outputs["Vector"], wave.inputs["Vector"]) + links.new(wave.outputs["Color"], ramp.inputs["Fac"]) + links.new(ramp.outputs["Color"], mix.inputs["Fac"]) + links.new(mix.outputs["Color"], bsdf.inputs["Base Color"]) + return mat def import_stl(filepath: str) -> List[bpy.types.Object]: @@ -290,27 +351,55 @@ scene.render.film_transparent = False bpy.ops.mesh.primitive_plane_add(size=2.0, location=(0, 0, mm_to_m(-28.0))) floor = bpy.context.active_object -checker_mat = bpy.data.materials.new(name="Checkerboard") -checker_mat.use_nodes = True -nodes = checker_mat.node_tree.nodes -links = checker_mat.node_tree.links -nodes.clear() -output_node = nodes.new(type="ShaderNodeOutputMaterial") -bsdf_node = nodes.new(type="ShaderNodeBsdfPrincipled") -checker_node = nodes.new(type="ShaderNodeTexChecker") -mapping_node = nodes.new(type="ShaderNodeMapping") -texcoord_node = nodes.new(type="ShaderNodeTexCoord") +floor_tex_path = Path(ROBOT_JSON_FILE).parent / "surfaces" / "boden.jpg" -checker_node.inputs["Color1"].default_value = (0.82, 0.82, 0.82, 1.0) -checker_node.inputs["Color2"].default_value = (0.18, 0.18, 0.18, 1.0) -mapping_node.inputs["Scale"].default_value = (20.0, 20.0, 20.0) +if floor_tex_path.exists(): + floor_mat = bpy.data.materials.new(name="FloorPhoto") + floor_mat.use_nodes = True -links.new(texcoord_node.outputs["UV"], mapping_node.inputs["Vector"]) -links.new(mapping_node.outputs["Vector"], checker_node.inputs["Vector"]) -links.new(checker_node.outputs["Color"], bsdf_node.inputs["Base Color"]) -links.new(bsdf_node.outputs["BSDF"], output_node.inputs["Surface"]) -floor.data.materials.append(checker_mat) + nodes = floor_mat.node_tree.nodes + links = floor_mat.node_tree.links + nodes.clear() + + output_node = nodes.new(type="ShaderNodeOutputMaterial") + bsdf_node = nodes.new(type="ShaderNodeBsdfPrincipled") + texcoord_node = nodes.new(type="ShaderNodeTexCoord") + mapping_node = nodes.new(type="ShaderNodeMapping") + image_node = nodes.new(type="ShaderNodeTexImage") + + image_node.image = bpy.data.images.load(str(floor_tex_path), check_existing=True) + image_node.interpolation = "Cubic" + + links.new(texcoord_node.outputs["UV"], mapping_node.inputs["Vector"]) + links.new(mapping_node.outputs["Vector"], image_node.inputs["Vector"]) + links.new(image_node.outputs["Color"], bsdf_node.inputs["Base Color"]) + links.new(bsdf_node.outputs["BSDF"], output_node.inputs["Surface"]) + + floor.data.materials.append(floor_mat) +else: + # Fallback: dein bisheriges Checkerboard behalten + checker_mat = bpy.data.materials.new(name="Checkerboard") + checker_mat.use_nodes = True + nodes = checker_mat.node_tree.nodes + links = checker_mat.node_tree.links + nodes.clear() + + output_node = nodes.new(type="ShaderNodeOutputMaterial") + bsdf_node = nodes.new(type="ShaderNodeBsdfPrincipled") + checker_node = nodes.new(type="ShaderNodeTexChecker") + mapping_node = nodes.new(type="ShaderNodeMapping") + texcoord_node = nodes.new(type="ShaderNodeTexCoord") + + checker_node.inputs["Color1"].default_value = (0.82, 0.82, 0.82, 1.0) + checker_node.inputs["Color2"].default_value = (0.18, 0.18, 0.18, 1.0) + mapping_node.inputs["Scale"].default_value = (20.0, 20.0, 20.0) + + links.new(texcoord_node.outputs["UV"], mapping_node.inputs["Vector"]) + links.new(mapping_node.outputs["Vector"], checker_node.inputs["Vector"]) + links.new(checker_node.outputs["Color"], bsdf_node.inputs["Base Color"]) + links.new(bsdf_node.outputs["BSDF"], output_node.inputs["Surface"]) + floor.data.materials.append(checker_mat) # ============================================================ # CAMERA