0

enter image description hereenter image description hereenter image description hereenter image description hereenter image description here> ### AI Icon Warning, Potential AI generated content⚠️

This post is suspected to have been generated with the help of an artificial intelligence, chat bot, or other language model tools without proper attribution.

There is reason to believe this post was not written by a human due to its structure, and grammatical construction, and has been marked by our community.
Current AI chat bots are a language models, that means they are like a parrot, they can mimic human language well, but they are built to write seemingly logical, seemingly factual grammatically valid text, rather than actually be correct, like a human would.
The veracity of the following content cannot be ascertained. See the Concerns regarding AI generated content.

Ive been trying to learn Blender for a few weeks and Ive put lots of late nights and early starts in. The more I learn about Blender the more I realise how little know!

I am trying to create a scene that I can use as input to a batch render process. I am trying to get the batch process to work before I refine the scene to a finished look. When I start rendering I want the colour of the fire surround to cycle through say 10 different colours/textures.

For each colour fire surround, I want to render with a different set of three flame jpgs, its important to know that the flames change/animate as the camera pans around the fireplace. Potentially I might have 12 sets of three jpg flames. Therefore I would produce 120 mpeg files of around 10 seconds long each.

I also have a small problem in that shadows from the fire surround are not cast on the images of flames which I will need for when there is no fire or small flames. From reading, I think this may be because the picture is "emissive"? How can I fix this, please?

The Scene is attached ( I think with all supported files embedded)

  1. How can I make a batch script? (I have attached a ChatGPT attempt below )
  2. How can shadows be cast inside the fire surround?

I am happy to share the scene.


# Define your colors (RGB tuples from 0 to 1)
colors = [
    (1, 0, 0), # Red
    (0, 1, 0), # Green
    (0, 0, 1), # Blue
    # Add more colors as needed
]

Path to the JPEG files, assuming they're named sequentially

jpeg_paths = [f"\flames{i}.jpg" for i in range(1, 3)] print (jpeg_paths)

Reference to the object you want to color

color_object = bpy.data.objects['Cube.001']

Reference to the plane object to which you want to apply JPEG textures

texture_object = bpy.data.objects['Picture']

for color in colors: # Apply color to the color_object if color_object.data.materials: material = color_object.data.materials[0] else: material = bpy.data.materials.new(name="ObjectMaterial") color_object.data.materials.append(material)

material.diffuse_color = color + (1,)  # RGB + Alpha

for jpeg_path in jpeg_paths:
    # Load the JPEG as a texture
    bpy.ops.image.open(filepath=jpeg_path, directory="/", files=[{"name":jpeg_path}], relative_path=True, show_multiview=False)

    # Assuming the plane uses a material that has an Image Texture node
    # Set the image of the texture node to the loaded image
    texture_material = texture_object.data.materials[0]  # Assuming it has a material
    for node in texture_material.node_tree.nodes:
        if node.type == 'TEX_IMAGE':
            node.image = bpy.data.images[jpeg_path.split('/')[-1]]
            break

    # Render settings
    bpy.context.scene.render.filepath = f'/path/to/output/{color}_{jpeg_path.split("/")[-1].split(".")[0]}'
    bpy.ops.render.render(write_still=True)  # Render the scene

,

enter image description here

enter image description here

Mikeyhhh
  • 1
  • 3
  • Chat GPT is pretty much useless for coding with Blender's Python API beyond most basic stuff. You can forget about it. – Martynas Žiemys Feb 04 '24 at 23:26
  • OK thanks for the heads up on ChatGPT. I will forget about it for now. There are 3 jpgs that different when you look at them straight on, from the left, from the right. when I work out how to post the .blend file here I will. do you upload or have to post a link to the file hosted somewhere else? – Mikeyhhh Feb 04 '24 at 23:28
  • So you have scene with animation and you have an object that uses some sort of material with a texture and you want to render that animation with the texture replaced, right? – Martynas Žiemys Feb 04 '24 at 23:29
  • Not quite, I have a scene, it changes the images according to where the camera is, i.e at which angle you look at it from. Please see attached screen shots... – Mikeyhhh Feb 04 '24 at 23:42
  • I have no idea what those shader nodes are supposed to do to be honest. Maybe let's start from there - what is the shader supposed to do exactly and why? Why do you need such a shader? – Martynas Žiemys Feb 04 '24 at 23:55
  • I mean... If you want a realistic flame, why not just use a video of the flame as a texture? What is the end goal here? I suspect this might be an XY problem kind of situation. – Martynas Žiemys Feb 05 '24 at 00:01
  • I just looked up xyproblem, it made me chortle. Let me try and explain what I want as precisely as I can (its 00hr24mins here and I am very tired again ) . – Mikeyhhh Feb 05 '24 at 00:18
  • Let me try and explain as precisely as I can (its 00hr24mins here and I am tired) . I would like to create a scene similar to the one shown in the screenshot. that scene must show only 3 different jpegs (definitely not video) which change depending on the lateral angle the fireplace is viewed from (I have this working ). I want to substitute the colour of the surround for 10 options, for each option of surround colour I want 12 different sets of flames to be used, each combination will be render to a mpeg showing movement around the object. I would like to achieve this using batch processing. – Mikeyhhh Feb 05 '24 at 00:33
  • I need to drive home... I look forward to reading your responses in the morning, thanks all for your help. – Mikeyhhh Feb 05 '24 at 00:34
  • The context is still unclear. Could you provide more context? What is this for? It's unusual to make fire this way. Why did you choose such an unusual method? – Martynas Žiemys Feb 05 '24 at 06:33
  • Hi Martynas, I understand that its difficult for you to understand the requirement, you must be asking "why would he want to do that when he could have video or a much better solution" but anything other than I describe wont work for me. If Blender cant do it ( I will be surprised) I will need to find another package. – Mikeyhhh Feb 05 '24 at 11:16
  • I am googling other examples I can hopefully borrow and adapt as I am slightly dyslexic and find syntax very tricky. I have found what I think are the names of the parameters that I need to change are... see new screenshots. I need to find a close example of something similar, edit it for my parameters and files, amend and debug. If anyone can point me in the direction of something I would be most grateful. – Mikeyhhh Feb 05 '24 at 11:44
  • I know how to do it in principal. I hesitate to provide an answer because I do not fully understand the situation. – Martynas Žiemys Feb 05 '24 at 11:53
  • I have tried to define the requirements as precisely as I can.... I thought they were clear however if they are not (probably the case) and there is anything else I can add to help what I want to achieve it become clearer please do let me know. In the mean time I have broken it down and I am just trying to get the scene to render with only the fire surround changing color, if I can get at least that working its a start. Thanks again, Mikey – Mikeyhhh Feb 05 '24 at 14:19
  • There are a lot of people here who are able to help with this, not just me. Nobody answered yet. Must be something wrong with the formulation. More context would probably help. Context meaning the circumstances that lead to this problem and decisions you have made as far. Not only the requirements, but the reasons behind them. – Martynas Žiemys Feb 05 '24 at 15:04
  • My first attempts of asking for help you said I was creating a XY problem. I looked at your link which said "The XY problem is asking about your attempted solution rather than your actual problem". I perhaps misunderstood this as I have not adequately described the problem. Thanks for explaining what you mean by context, I will try and explain. I have a scene that does exactly what I want, it is WIP and the objects and environment etc will be developed when I know I can do what I require, you hint that it should be possible and you probably know how to do it so I am hopeful. – Mikeyhhh Feb 05 '24 at 15:40
  • when you say i need to describe the decisions I have made to reach this point I assume you mean technical decisions. If thats the case I have few, I want a flat object to change as I move around it, normally to 3 different versions, but perhaps to 7, 9 or more versions in the future. It could be a bad render of a fireplace (the example I have shown), or a computer monitor cycling through MS PPT slides as I walk by. I dont think that matters. I have 10 color variations or so of fireplace surround (or computer monitor bezel) and 3, 5 or more images that will change. – Mikeyhhh Feb 05 '24 at 15:41
  • I may also use multiple room backgrounds in future. The only technical decisions I have made is to research if Blender can do batch jobs where I discovered the scripting function, my first attempts used chatgpt which everyone tells me is a mistake, I thought it would at least give me something to work with and amend to my requirements..... I need to know how to update the object/variables and iterate within loops. – Mikeyhhh Feb 05 '24 at 15:45
  • I may have 10 bezels x 20 powerpoint sets (each 3, 5, or 7 slides) x 10 back grounds/enviroments = 2000 small videos to make. I appreciate your help and feedback and understand your probable frustration with me for not helping you help me. ): ... sorry – Mikeyhhh Feb 05 '24 at 15:46
  • No frustration. Just trying to understand. This seems to be a very good question that will be very useful for the community. I will attempt to provide a solution. Might take a bit of time though. – Martynas Žiemys Feb 05 '24 at 16:29
  • Thank you so much, no matter how long it might take you, it will be quicker for you than it will be for me watching dozens of youtube videos (I've just fallen asleep half way through one - I've just asked my partner to pick my child up from school as I think I would fall asleep at the wheel driving) and reading countless articles. which I am doing currently (: – Mikeyhhh Feb 05 '24 at 16:35
  • Hello, this conversation is becoming a little too extensive for a comments section, and so I've moved it to chat. Apologies that the interface over there isn't wonderful, but notifications will still work. Leaving the local copies here for the time being. – Robin Betts Feb 05 '24 at 17:03
  • Comments have been moved to chat; please do not continue the discussion here. Before posting a comment below this one, please review the purposes of comments. Comments that do not request clarification or suggest improvements usually belong as an answer, on [meta], or in [chat]. Comments continuing discussion may be removed. – Robin Betts Feb 05 '24 at 17:03

1 Answers1

1

OK, so the weird part about rendering in Blender from a script is that rendering is a complex multithreaded process possibly happening on multiple devices, so it's sort of difficult to know when the rendering job is done inside a script and to make it wait before executing anything after render process is started. So this does have to happen inside a modal operator with a bunch of application handlers. Confusing right? I know... Well, it is what it is. Thanks to this amazing answer(let's upvote it!) it's possible to figure out how to do that.

So in order for my script to work unmodified, you have to prepare the .blend file and your folder structure in a certain way:

  1. You have to place the .blend file in a folder where you also have another folder called Variations:

enter image description here

  1. You have to make sure that the images you want to replace with variations are called exactly the same as folders in that Variations folder and put your variation images in them.

Variations

You can also see the image names in the Outliner, Blender File mode:

enter image description here

Image data-block name can be anything regardless of the image path.

So your Variations folder should contain folders named same as your image data-blocks and there(in those folders) you should have images for those data-blocks.

For example: I have Variations folder containing folders named Sphere and Suzanne and some image textures for them(2 in one, 3 in another). I also named them in a reasonable manner, because the script will use those names for render output. They are images filled with single color only for the sake of simplicity.

enter image description here

This is how my folder structure looks:

enter image description here

And here is the script that you can copy to the Text Editor of your file and run from it:

import bpy
import os
import itertools

class Multi_Render(bpy.types.Operator): """Renders multiple times""" bl_idname = "render.multi" bl_label = "Render multiple times"

_timer = None
shots = None
stop = None
rendering = None
path = bpy.path.abspath("//Render//")
v_dir = bpy.path.abspath("//Variations")
def pre(self, scene, context=None):
    self.rendering = True 
def post(self, scene, context=None):
    self.shots.pop(0) #this removes last variation from the list
    self.rendering = False

def cancelled(self, scene, context=None):
    self.stop = True

def execute(self, context):
    self.stop = False
    self.rendering = False

    # Prepare all variations for rendering 

    # let's make a list of image variation lists(so a list of all lists)
    variations = []
    for folder in os.listdir(self.v_dir):
        image_variations = []
        for file in os.listdir(os.path.join(self.v_dir,folder)):
            image_variations.append(os.path.join(self.v_dir,folder, file)) 
        variations.append(image_variations)
    # Let's convert it to a list of all variations
    self.shots = list(itertools.product(*variations))

    # Carry on with other stuff making this work
    context.scene.render.filepath = self.path
    bpy.app.handlers.render_pre.append(self.pre)
    bpy.app.handlers.render_complete.append(self.post)
    bpy.app.handlers.render_cancel.append(self.cancelled)
    self._timer = context.window_manager.event_timer_add(1, window=context.window)
    context.window_manager.modal_handler_add(self)
    return {"RUNNING_MODAL"}

def modal(self, context, event):
    if event.type == 'TIMER':
        if True in (not self.shots, self.stop is True): 
            bpy.app.handlers.render_pre.remove(self.pre)
            bpy.app.handlers.render_complete.remove(self.post)
            bpy.app.handlers.render_cancel.remove(self.cancelled)
            context.window_manager.event_timer_remove(self._timer)
            return {"FINISHED"}
        elif self.rendering is False: 
            # Changes happen here: 
            paths = self.shots[0]
            sc = context.scene
            names = [os.path.splitext(os.path.basename(f))[0] for f in paths]
            sc.render.filepath = self.path + '-'.join(names) + " "
            for path in paths:
                image = os.path.basename(os.path.dirname(path)) # folder name
                bpy.data.images[image].filepath = path

            # now just render
            bpy.ops.render.render("INVOKE_DEFAULT", animation=True,write_still=True)

    return {"PASS_THROUGH"}

bpy.utils.register_class(Multi_Render) bpy.ops.render.multi()

Like I mentioned it is weird, because it is wrapped in a modal operator, but there are 2 main parts: The one starting at line 29 where you prepare a list of variations and the one starting at line 59 where all the changes happen per iteration. It is using a list and every time an item is rendered in that list it is removed by render_complete application handler at line 19. This is the only way(at least I know of) to have the render visible in the UI, which from my experience is sort of important when you render stuff and want to see if it's going OK(so pretty much every single time)

Once you hit run in the Text Editor, it will start rendering and output your render to the same folder the .blend file is in a Render subfolder:

enter image description here

I have an animation of only 2 frames and output set to .png so it outputs frames separately. It names them according the texture names.

This should work with more variations as you can add more folders matching image data-blocks.

Note that I did not write any checks whatsoever for errors. So you should only have folders and valid images in those folders and names must match existing image data-blocks, other way it will fail in ways I have not tested. The idea is if you like it, you should probably write your own checks (I spent way too much time on this already, but don't get me wrong, it was fun and educational) ...and of course I assume you would modify it further according your needs on your own.

If you have sets of images, I think it might be easier to just combine every set into one image for this, although, it's also possible to load a folder of images as one variation, but I would just combine them to be honest and split them with UV map or any other way in the shader.

Martynas Žiemys
  • 24,274
  • 2
  • 34
  • 77
  • Ive not had chance to read or test this yet... but totally awesome effort (: thank you so much for having a look at this. I think I would have been working on this for several months... will read, test and get back to you. – Mikeyhhh Feb 06 '24 at 10:26