5
$\begingroup$

I am a sensor enginer so I know quite well how a camera work but I am a Blender beginner. So I need your help. I want to have two cameras with total control on both width and height of the sensors. And focal as well. enter image description here

  • Camera A : 14*10mm and 16mm focal lens
  • Camera B : 512px/424px and 70°/60° FOV

You can find my project here blender project link

I first created camera A
enter image description here

But I can only choose Horizontal or Vertical. Then I need to change my output resolution according to my camera so Blender respect the ration width/height of my camera.
enter image description here

The problem is that output resolution is defined at project level and not camera level. So when I add my second camera, with a sensor ratio width/height different from my camera A, I'm stuck :/

Do you have a way to not use this "sensor fit method" in Camera settings and just let me choose by myself at the same time sensor width and sensor height ?

Thank you in advance for your help !

$\endgroup$
10
  • 1
    $\begingroup$ Resolution is part of scene properties, can't natively be changed per camera easily. The native solution is to create two scenes with same content, linked camera positions and set up different render resolutions. See my answer for hints blender.stackexchange.com/questions/52231/… $\endgroup$ Commented Nov 4, 2022 at 12:43
  • 1
    $\begingroup$ Other option is to use an addon like RenderPlus to do it. It is a paid addon I use it personally, but there are probably other free options that can do it too. $\endgroup$ Commented Nov 4, 2022 at 12:48
  • 1
    $\begingroup$ @Jerem_Lab: do you know python a bit? then i could show you a free solution $\endgroup$
    – Chris
    Commented Nov 4, 2022 at 13:22
  • 1
    $\begingroup$ @Chris Yes it's my main language :) $\endgroup$
    – Jerem_Lab
    Commented Nov 4, 2022 at 13:37
  • 2
    $\begingroup$ I think I have tried all the ways already during past 5 years :D. It's possible that Blender has changed since the last time I tried, but it seems it doesn't work with render operator in animation mode. I think render operator checks resolution once and that's it no matter what you do so one needs to write a custom render operator, but it's hard to know when rendering is finished because it's multithreaded and the script that starts it is not so one would probably need to make the script wait until frame file is written to disk or something... or use a handler to restart rendering. $\endgroup$ Commented Nov 4, 2022 at 14:15

1 Answer 1

5
$\begingroup$

Be careful, this is a DIRTY solution which might have sideeffects and might even crash Blender...but...on my Macbook - it worked :D

So all perfectionists and 100% people - don't read this - this is NOT for you. But if people are interested in a solution which can work and if you render over night anyway then a few seconds of "sleep" in the code might not be important ;)

First you need a little python script which basically checks which camera is active and sets the resolution of the scene accordingly.

import bpy
import time

    def setRenderResolution(scene):
        
        render = scene.render
        camera = scene.camera
    
        orig_res_x = render.resolution_x
        orig_res_y = render.resolution_y
    
        # ▼ Resolution change ▼ 
        scene.render.resolution_x = int(bpy.data.cameras[camera.name].sensor_width) * 10
        scene.render.resolution_y = int(bpy.data.cameras[camera.name].sensor_height) * 10
         
        print("camera is", camera.name)
        print ("new res is:", scene.render.resolution_x, "x", scene.render.resolution_y)
    
        return render.resolution_x
    
    def callIt(scene):
        print("in pre append now")
        setRenderResolution(scene)
    
    
    #bpy.app.handlers.frame_change_pre.append(callIt)
    
    print("*" * 50)
    print ("script start")
    
    for frame in range(bpy.data.scenes["Scene"].frame_start, bpy.data.scenes["Scene"].frame_end):
        
        print("rendering frame", frame)
        bpy.context.scene.frame_set(frame)
        
        setRenderResolution(bpy.data.scenes["Scene"])
        
        time.sleep(2)
        
        bpy.data.scenes["Scene"].render.filepath = "/tmp/%04d.png" % frame
    
        bpy.ops.render.render(write_still=True)
        
        time.sleep(2)
        

All this python script does is define a function (def) with the name "setRenderResolution". It then reads the original resolution x and y in the variables orig_res_x and orig_res_y.

Then the next 2 lines after "resolution change" set the render resolution.

So above "resolution change", you should enter YOUR python code to calculate the right resolution depending on your camera settings.

I just set the x and y resolution to sensor.width/height because i am lazy and i don't know the real formula. I just set a value here to prove that my solution works.

Now how can you change cameras "automatically" in a scene?

That's pretty basic:

Open the timeline, go to a frame of your choice, press "M" -> this will set a marker in the timeline:

enter image description here

Now select a camera of your choice, and choose marker->bind camera to marker.

enter image description here

select another frame in the timeline and select another camera and repeat the steps with create marker and bind the other camera to the marker.

If you now toggle to camera view

enter image description here

and move the timeline over the markers, you will see the different cameras in action and it should now work as you wanted it (of course if you did add the python code for the resolution calculation).

Note: Yes, the solution is pretty dirty because of the sleep statements and because i used bpy.data.scenes[] instead from context, but it worked for my test render. It might be, that you have to test with other sleep values that it works for you. It might also be that my solution doesn't work at all for you (which i don't hope).

If you do a "normal" animation render, it won't work, that's why i added here the code in the script to render it "manually" but at least it read the frame start and frame end, so hopefully that's good enough.

enter image description here

i know it's a bit hard to see, but you see here the "finder" of a mac (which is the same as explorer in windows) and by watching the preview you can see that the resolution changes of the rendered images.

enter image description here

$\endgroup$
10
  • $\begingroup$ Have you tested it with animation rendering? $\endgroup$ Commented Nov 4, 2022 at 14:05
  • $\begingroup$ @MartynasŽiemys: No, and you are right - it doesn't work...i try it with handlers $\endgroup$
    – Chris
    Commented Nov 4, 2022 at 14:09
  • 1
    $\begingroup$ It starts rendering as if you pressed F12 - with preview of the render process in the UI. I'll try to write an addon, if I have enough time for this. $\endgroup$ Commented Nov 4, 2022 at 17:43
  • 2
    $\begingroup$ Nope. Still cannot do it. Handlers will not start rendering. They are probably not the way to go. I give up again. Maybe in a few more years... :D Or I'll just buy the RenderPlus addon just to see how it's done :D $\endgroup$ Commented Nov 4, 2022 at 18:54
  • 1
    $\begingroup$ Thank you for your accurate and documented answer. I will give a try to render+ plugin then maybe I will try your solution :) $\endgroup$
    – Jerem_Lab
    Commented Nov 7, 2022 at 12:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .