Skip to content
Home » Animated Credits in Blender with Python

Animated Credits in Blender with Python

Spread the love

Today we’ll be making animated scrolling credits in Blender that you can use at the end of a video with all the images and video clips that were used in it. I’ll be using the 2.93 version of Blender. You will find the blend file and the images and video clips that I’m using here on Github.

Here’s what it’s supposed to look like:

So, let’s do it. Here are the steps for you to follow:

Step 1 – Create a New File

Create a new blend file, delete everything, so the default cube, the light and the camera, so that you can start with an empty scene. We’ll add all elements we need in code. You can just select all the elements in the Outliner, right-click and select Delete:

Create a New File for the Credits in Blender

Step 2 – Add a Script

Next, go to the Scripting workspace (A) and hit the New button (B) to create a new script:

Add a Script

Step 3 – Type In the Python Script

Script Description

Type in the following script. You will find all the explanations in comments, but to be brief, here’s what the code in the script does:

– First we import the bpy and os modules that we’ll need to use the Blender Python API and to work with files and directories respectively.

– Then we define some functions. In particular we define the following functions:

1) change_directory (It will change to the directory where the videos and images are that we want to show in the credits animation. It will also create a list of all videos and a list of all images. To keep things simple, we’ll only be using files with the ‘.jpg’ and ‘.png’ extensions for images and files with the ‘.mp4’ extension for videos.)

2) reset_cursor (It will move the 3D cursor to the World origin, so to the location at x=0, y=0, z=0.)

3) add_text (It will create text and add a material to it.)

4) show_items (It will display each video or image and add text to it. Again, to keep things simple, the text will be just the name of the file without its extension.)

– Next, the main part of our code begins. We’ll change to a sample directory. The names of the files in that directory are at the same time the credits that I want to display. Here you can see them in the folder:

folder

As you can see, they all have either the ‘.jpg’ or the ‘.mp4’ extension. The ‘.png’ extension would work too.

– Next we’ll change the World color to black and reset the 3D cursor.

– If there are any videos in our folder, we’ll create the text ‘Videos’ and display all the videos one after another below it.

– Next, if there are any images in the folder, we’ll create the text ‘Images’ and show all the images below it.

– Next, we’ll add and set a camera.

– We’ll set the End Frame to 480 so that the animation takes 20 seconds to complete (the frame rate is by default 24 FPS).

– At frame 1 we’ll insert a Location keyframe for the camera. Then the camera will move all the way down, below where the last image is, and we’ll insert another Location keyframe at the last frame. After that we’ll go back to frame 1.

The Script Itself

OK, so here’s the script that you can use to create the animated credits in Blender:

 # We need this to work with the Blender Python API.
 import bpy
  
 # We need this to work with directories and files.
 import os
  
 ### Functions ###
  
 # Change to a directory and get the current working directory. Also, create 
 # a list of all the videos and a list of all the images. To do the latter, we're using
 # list comprehensions. If you want to learn more about these, you will find
 # the links below the code section. You will also find a link to my article about
# string boolean methods like endswith, which is the one I'm using inside the
# list comprehensions.
 def change_directory(directory):
     # Here we're using the global statement so that we have access to the variables
     # outside the function. I have an article about the global statement, so if you want
     # to read it, you will find the link below.
     global folder, videos, images
     os.chdir(directory)
     folder = os.getcwd()
     
     # videos
     videos = [vid for vid in os.listdir(folder) if vid.endswith('.mp4')]
     
     # images
     images = [img for img in os.listdir(folder) if img.endswith('.jpg') or img.endswith('.png')]
  
 # Reset 3D cursor back to World origin.
 def reset_cursor():
     bpy.context.scene.cursor.location = (0.0, 0.0, 0.0)
         
 # Add text.
 def add_text(text, scale, centered=False):
     global pos
     
     # If the text contains the jpg, png or mp4 extension, let's remove it. We can do it by slicing.
     # If you want to learn more about slicing, you'll find a link below.
     if text.endswith('.jpg') or text.endswith('.png') or text.endswith('.mp4'):
         text = text[:-4]
     
     bpy.ops.object.text_add()
     ob=bpy.context.object
     ob.data.body = text
     
     # Remember text position so that you know where the last item is. We'll need
     # this to know how much the camera should move down in the animation.
     pos = ob.location
     
     # Here we have some transformations. I have a separate article about transformations
     # in Blender Python, so feel free to check it out (link below).
     bpy.ops.transform.rotate(value=1.5708, constraint_axis=(True, False, False))
     bpy.ops.transform.resize(value=(scale, scale, scale))
     if centered:
         bpy.context.object.data.align_x = 'CENTER'
     bpy.context.object.data.extrude = 0.05
  
     # create text material
     mat = bpy.data.materials.get("Material")
     if mat is None:
         # create material
         mat = bpy.data.materials.new(name="Material")
         bpy.data.materials["Material"].node_tree.nodes["Principled BSDF"].inputs[17].default_value = (0.0469195, 1, 0.971278, 1)     
  
     # assign material        
     if ob.data.materials:
         # assign to 1st material slot
         ob.data.materials[0] = mat
     else:
         # no slots
         ob.data.materials.append(mat)
         
 # Show items (videos or images).
 def show_items(item_list):
     for item in item_list:
         bpy.ops.import_image.to_plane(files=[{"name":item}], directory=folder)
         bpy.ops.transform.rotate(value=1.5708, constraint_axis=(True, False, False))
         
         # add light
         bpy.ops.object.light_add(type='POINT', align='WORLD', scale=(1, 1, 1))
         bpy.context.object.data.shadow_soft_size = 1
         bpy.context.object.data.energy = 100
         
         # add text
         bpy.context.scene.cursor.location.x += 2
         add_text(item, .25)        
         
         # move cursor
         bpy.context.scene.cursor.location.x -= 2
         bpy.context.scene.cursor.location.z -= 2
  
 ### Main Code ###
  
 # Change to the directory where the images and videos are.
 change_directory(r'D:\Blender\YT\Projects\42 - Credits in Blender with Python\images and videos')
  
 # Set World color to black.
 bpy.data.worlds["World"].node_tree.nodes["Background"].inputs[0].default_value = (0, 0, 0, 1)
  
 # Reset the 3D cursor.
 reset_cursor()
  
 # Add the 'Videos' text if there are any videos.
 if videos:
     add_text('Videos', .5, centered=True)
  
     # Move cursor down.
     bpy.context.scene.cursor.location.z -= 2
  
     # Show all the videos.
     show_items(videos)
  
 # Add the 'Images' text if there are any images.
 if images:
     add_text('Images', .5, centered=True)
  
     # Move cursor down.
     bpy.context.scene.cursor.location.z -= 2
  
     # Show all the images.
     show_items(images)
  
 # Reset cursor.
 reset_cursor()
  
 # Add and set camera.
 bpy.ops.object.camera_add(location=(4, -10, 0), rotation=(1.5708, -0, -0))
 bpy.context.object.data.lens = 30
  
 # Set the end frame in the timeline to 480 (animation duration - 20s).
 bpy.context.scene.frame_end = 480
  
 # Go to frame 1.
 bpy.context.scene.frame_current = 1
  
 # Keyframe the camera (insert a Location keyframe).
 bpy.ops.anim.keyframe_insert_menu(type='Location')
  
 # Go to frame 480.
 bpy.context.scene.frame_current = 480
  
 # Move the camera below the last image. We're using the pos variable here
 # which holds the location of the last text element.
 bpy.ops.transform.translate(value=(-0, -0, pos.z - 4), constraint_axis=(False, False, True))
  
 # Keyframe the camera again.
 bpy.ops.anim.keyframe_insert_menu(type='Location')
  
 # Go back to frame 1.
 bpy.context.scene.frame_current = 1 

Here you can see the script in the Text editor (A). As you can see, the 3D Viewport is empty (B):

script

Some Useful Links

In the script above I mentioned some links to my other videos where topics related to what I used in the code are covered. Here they are:

Your Panda3D Magazine

Make Awesome Games and Other 3D Apps

with Panda3D and Blender using Python.

Cool stuff, easy to follow articles.

Get the magazine here (PDF).

Step 4 – Run the Script

Hit the Run Script button (A). If there are no errors (there shouldn’t be if you copied and pasted the code as well as used a path to an existing folder with JPG, PNG and MP4 files. Naturally, your results will be different. Anyway, you will see all the new elements that we added in the Outliner (B) and in the 3D Viewport (C). Go to front view (Num 1) and switch to Rendered shading (D):

Python Jumpstart Course

Learn the basics of Python, including OOP.

with lots of exercises, easy to follow

The course is available on Udemy.

Step 5 – Play the Animation and Watch the Credits in Blender Scroll

Now you can go back to the Layout workspace and test the animation. Switch to Rendered shading and go to camera view (Num 0):

Play the Animation of the Credits in Blender

Step 6 – Render the Credits in Blender Animation

In the Output Properties tab (A) select a location for your animation file (B). Set File Format to FFmpeg Video (C) and under Encoding set the Container to MPEG-4 (D). Then go to the Render menu (E) and select Render Animation. It will take a while to render.

Render the Animation of the Credits in Blender

Naturally, this was just a very basic example. You can tweak it to your heart’s content. For example you can choose to allow other file formats or get the texts from other sources. Feel free to experiment.

Blender Jumpstart Course

Learn the basics of 3D modeling in Blender.

step-by-step, easy to follow, visually rich

The course is available on Udemy and on Skillshare.


Spread the love

Leave a Reply