Tutorial Render with Blender

From FreeCAD Documentation
Revision as of 08:50, 26 April 2019 by Vocx (talk | contribs) (→‎Prepare the lighting of the scene: Render of the assembly in Blender with a sun lamp added that emits parallel light rays with a certain angle)
Tutorial
Topic
Rendering
Level
Intermediate
Time to complete
60 minutes
Authors
vocx
FreeCAD version
0.18 or greater
Example files
none
See also
None

Introduction

This tutorial shows how to produce a rendered image in Blender, beginning from a part or assembly created with FreeCAD. It assumes that the user already created the part in FreeCAD, which is then exported to Blender for rendering.

It uses Blender 2.80 with the EEVEE and Cycles renderers. It shows various Python commands that can be used to perform actions quicker.

FreeCAD

1. Create an assembly using bodies from the Part or PartDesign Workbenches, or any other workbench that produces solid objects, for example, the Arch Workbench. Assign colors or materials to the individual bodies that make the assembly, approximately matching the color that you want in your render.

Assembly of three bodies created in FreeCAD, and with colors or materials assigned.

2. If your model is very detailed, make sure the ViewDeviation of the body is set to a low value, between 0.1 and 0.01, or even smaller. The lower this value is, the more detailed the exported mesh will be, and thus the better the quality of the render will be.

Deviation property of the bodies created in FreeCAD; the deviation needs to be small in order to export the parts with good resolution.

3. Select your model and export it as Wavefront OBJ. Select the Part, then File → Export, or press Ctrl+E.

Alternatively, the export can be done from the Python console. Define a list of objects to be exported and use the exporting function with a file name.

import importOBJ
objs = FreeCAD.ActiveDocument.getObjectsByLabel("Part")[0]

importOBJ.export(objs, "/home/user/assembly.obj")

Note: If the resulting OBJ file appears to be empty, you may have to export the individual bodies. In this case, select each of the bodies under the part, and repeat the export.

import importOBJ
objs = [FreeCAD.ActiveDocument.getObjectsByLabel("Body.base")[0],
FreeCAD.ActiveDocument.getObjectsByLabel("Body.bolt")[0],
FreeCAD.ActiveDocument.getObjectsByLabel("Body.bolt.big")[0]]

importOBJ.export(objs, "/home/user/assembly.obj")

Blender

Prepare the model

3. Open Blender. Change the Timeline panel into a Python Console (Shift+F4). This will help you to input commands and see the results. You may also divide this panel and set an Info panel to see other actions as you click on the interface.

Make sure you are using the EEVEE renderer. In the Properties panel go to Render, and for Render Engine select Eevee.

bpy.context.scene.render.engine = 'BLENDER_EEVEE'

4. Import the model file from the menu, File → Import → Wavefront (.obj).

Alternatively, importing can be done from the Python Console.

obj_file = "/home/user/assembly.obj"
bpy.ops.import_scene.obj(filepath=obj_file)

4. Change the scale. If the bodies appear to be very large you may have to change the units so the objects appear at the right scale.

In the Properties panel go to Scene, Units, and select the appropriate Unit System, Unit Scale, and Length.

For small parts, you may wish to keep the length to Millimeters, and the scale to 0.001. For bigger parts, for example, the model of a building, you may have to set these values to Meters and 0.001. Try other values of scale if you need.

This can be set also from the Python console, for example

bpy.context.scene.unit_settings.length_unit = 'MILLIMETERS'
# or bpy.context.scene.unit_settings.length_unit = 'METERS'
bpy.context.scene.unit_settings.scale_length = 0.001

Note: changing the scale and units of the model is only necessary if you wish to add elements to your scene at their true dimensions. If you just want to render your scene quickly, you may not need to do any adjustment.

4.1. If you zoom out, and the view cuts the imported parts, you may have to adjust the view clip values.

Hit N to show the auxiliary panel; go to the View section and set the End to a large value, for example, 1E6 mm or 1000 m.

If you wish, also adjust the size of the grid; go to Overlays then Guides, and set the Scale of the grid to 0.001.

5. Fix the rotation of the objects.

When imported, objects may appear rotated around one of the axes, for example, 90 degrees around the X axis. Hit N to show the auxiliary panel; select an object, go to the Transform section and set the Rotation to in each field. Do this for every object.

This can be automated by a small script that just sets the rotation of each imported body to zero, with the exception of the objects inside the fixed_objs tuple. This can be useful if you are importing objects into an existing scene where other objects are already in their right positions.

fixed_objs = ('Camera', 'Cube', 'Light')

for obj in bpy.data.objects:
    if any(s for s in fixed_objs if s in obj.name):
        print('%s %s  [[No change]]' % (obj.name, obj.rotation_euler))
        continue
    else:
        obj.rotation_euler = (0, 0, 0)
        print('%s %s  ... rotated' % (obj.name, obj.rotation_euler))

Assembly created in FreeCAD imported into Blender; the model was rotated and the units for the scene were adjusted to match the imported objects.

Prepare the camera of the scene

6. Set the camera in the right position.

Adjust the viewport to the right angle to see the model, and then hit Ctrl+Alt+0 (numerical pad), or use the menu View → Align View → Align Active Camera to View.

6.1. If you don't see anything in the camera view, you may need to adjust the clipping. Selecting the camera in the Outliner, go to the Properties panel, then Object Data, then Lens, then set the Clip End to a large value, for example, 1E3 mm or 1000 m.

bpy.context.object.data.clip_end = 1e+03

Now you can already quickly render the model by pressing F12, which will open the Image Editor with the rendered result. Press Esc to exit, and return to the 3D Viewport.

First render of the assembly in Blender with the camera with correct clipping, but no lighting

You can toggle between camera view and the 3D viewport by pressing 0 in the numerical pad; pressing F12 will render the camera view in any moment.

If the camera looks very small in the 3D viewport, go to the Properties panel, then Object Data, then Viewport Display, and set a larger value for the Size, for example, 20 mm. Also activate the Limits checkbox to see the clipping distance of the camera.

bpy.context.object.data.display_size = 20
bpy.context.object.data.show_limits = True

Prepare the lighting of the scene

7. Select the light in the Outliner, go to the Properties panel, then Object Data, then press on Sun, and set the Strength to 5.0.

bpy.context.object.data.type = 'SUN'
bpy.context.object.data.energy = 5

This will turn the light into a sun lamp. This type of lamp emits an infinite number of parallel light rays with a certain angle.

You may position the sun lamp anywhere on the viewport above your model so that you can define the direction of the rays of light. For a sun lamp it doesn't matter how close or far you place the lamp, only the direction of the rays, which are defined by the rotation of the object.

bpy.context.active_object.location = (150, 100, 100)
bpy.context.active_object.rotation_euler = (0.6, 0.05, 1.88)

Press F12 again to see a preliminary render of the model.

Render of the assembly in Blender with a sun lamp added that emits parallel light rays with a certain angle

Add floor and global lighting

8. Add a floor plane. Click Shift+A then Mesh, Plane, and give it dimensions 10 times larger than your model. This will serve as a ground plane or table top on which the model is standing. Also move the plane a bit down (-1 mm is enough), so that it does not intersect the model.

bpy.ops.mesh.primitive_plane_add(size=1500, view_align=False, enter_editmode=False, location=(0, 0, -1))

9. Set the world illumination. In the Properties panel go to World, and set Color to a light blue-gray value, and the Strength to 0.3.

10. Set reflections. The EEVEE renderer of Blender produces fast renders by deactivating particular effects. In order to obtain better images, some options need to be made active.

Go to the Properties panel, then Render, and check Screen Space Reflections. In the Shadows section, also check Soft Shadows.

bpy.context.scene.eevee.use_ssr = True
bpy.context.scene.eevee.use_soft_shadows = True

Set the materials of the objects

11. Turn the Python Console panel into a Shader Editor panel (Shift+F3).

11.1. Select the ground plane, go to the Properties panel, then Material, and click on New. In the Shader Editor a Principled BSDF node should appear. Give it a beige Base Color, turn the Metallic to 0.000, and the Roughness to 1.000.

Principled BSDF shader used in Blender to simulate a variety of materials ranging from shiny metals to rough and opaque solids

11.2. Select each of the parts of the model, and adjust the respective Principled BSDF material node. For metallic parts, turn the Metallic property all the way to 1.000. Adjust the value of Roughness to be between 0.2 and 0.7. The closer to 0.000 the Roughness is, the more reflective (mirror-like) it will appear.

For non metals, like plastics, wood and textiles, set the Metallic property all the way to 0.000, and adjust the value of Roughness to between 0.4 and 1.0.

In general, metals are naturally smooth and therefore their roughness is small, making them shiny (reflective). Other materials are microscopically rough, and therefore do not reflect as much light, making them more opaque.

Test different combinations of materials until they look acceptable. Press Z and then 8 (numeric pad) to enter Rendered mode; in this mode, the EEVEE renderer shows in real time in the 3D viewport how the final image will look like. Use Z to open the pie menu and switch back to Solid mode (Z 6), or go to LookDev mode (Z 2), a mode which adds different types of lighting to the scene to test the materials.

Press F12 to render the view through the camera and check the quality of your image.

Rendering and saving

12. If your model looks reasonable well with the EEVEE renderer you can already save the image by going to Image → Save As or pressing Shift+S in the Image Editor.

Rendered assembly produced with EEVEE; all materials use the Principled BSDF shader; only one sun lamp is used, with some ambient background light

13. If you want to improve the quality of the image, try the Cycles renderer.

Go to the Properties panel, then Render, and for Render Engine select Cycles. With the Cycles renderer, Blender will refine the image gradually until a number of iterations have passed. Every time the viewport changes the recalculation restarts.

bpy.context.scene.render.engine = 'CYCLES'

Press F12 to render the final view through the camera. Depending on your graphics card (GPU) the image should take several more seconds, or minutes, to render with Cycles than with EEVEE, but the quality of the image should be better.

14. When you are satisfied with the quality of the image, go to Image → Save As or press Shift+S.

Rendered assembly produced with Cycles; all options, materials, and lights that were used with EEVEE were kept for use with Cycles

Final notes

EEVEE is not a physically accurate renderer, however its main strength is that it is a real time renderer so it is able to produce quick images directly in the 3D viewport. In many cases, these images have enough quality for final production which means it's possible to obtain a good result in a very short time.

On the other hand, Cycles is a true raytracing renderer which means it is more accurate at calculating light paths in a scene in order to produce a photorealistic result. Cycles is still the recommended renderer when the best quality is desired.

In many cases, the scene prepared with EEVEE can be used immediately without change in Cycles in order to produce a better rendering. However, in cases were complex light interactions are desired (reflections, refractions, volumetric light, and caustics) EEVEE is limited, and requires some tricks and options to work around some of these limitations.

Obtaining good results is highly dependent on configuration of the rendering options, the materials, and the lighting. The Principled BSDF material shader is a generic solution that works well for many cases, however, to produce trully photorealistic results, the use of texture maps and normal maps, along with careful lighting of the scene is still very important.