Here is a script that imports HDR images, creates world settings (worlds), marks them as asset and creates a preview for them.
The script requires a few things.
Blender 3.3. For Blender 3.2, you need a little patch. Increase the number in line 37, e.g. return 1.0
and comment out lines 19 to 21 by adding a #
at the beginning of the line. For the technical details see the linked questions at the end of this answer.
It also requires a template node setup in the World setttings named "World (template") (line 53). There must be an Environment Texture node so the image can be defined there. The name of the node (Environment Texture) is important, not the label. (The values can be changed in the N-panel, just in case you have more than one of these nodes.)
the generated default preview images for HDRIs look very odd for some reason. So I used a plane as a preview object with a simple material (see screenshot). The plane object must be in the XZ plane (add a plane, rotate it by 90° along X-axis, and apply Rotation) because Blender uses automatically a certain point of view to render a preview image from the plane. It does not use the camera as it does for poses.
The script looks for HDR images with *.hdr and *.exr file extensions (line 70+71) in the folder that is defined in line 68. If you want to search in subfolders you can set recursive = True
and specify a folder something like C:/blender/projects/**/hdri
. Then it will look for HDRIs in every subfolder named hdri that is in C:/blender/projects. Of course, C:/blender/projects/**
works as well to search all subfolders in the given base folder. For the file path separator use a /
not a \
.
To run the script, go to Scripting workplace, create a new text data block (menu Text > New Alt+N), copy & paste the code and press the run button.
For messages and errors check the system console. Use main menu entry Window > Toggle System Console if the window is not open.
import bpy
import glob
from os import path
import functools
def load_image(image_path):
basename = path.basename(image_path)
img = bpy.data.images.get(basename)
if img is None:
try:
img = bpy.data.images.load(image_path)
except:
print("ERROR: Cannot load image %s" % image_path)
return img
def create_hdri_previews(assets, callback):
if bpy.app.is_job_running('RENDER_PREVIEW'): # Blender 3.3!
print("Waiting for render...")
return 0.2 # waiting time
while assets: # generate next preview
world = assets.pop()
print(f"Creating preview for world {world.name}...")
# set image in the preview object's material
obj = bpy.context.active_object
image = world.node_tree.nodes['Environment Texture'].image
obj.material_slots[0].material.node_tree.nodes['Image Texture'].image = image
# start preview render
override = bpy.context.copy()
override["id"] = world
with bpy.context.temp_override(**override):
bpy.ops.ed.lib_id_generate_preview_from_object()
return 0.2
callback()
return None
def create_world(image_path):
image = load_image(image_path)
if image is None: return
worldname = image.name.lower().replace('_', ' ')
worldname = worldname.replace('.exr', '').replace('.hdr', '')
worldname = worldname.title()
world = bpy.data.worlds.get(worldname)
if world is None:
template = bpy.data.worlds.get('World (template)') # <------ World template
world = template.copy()
world.name = worldname
world.node_tree.nodes['Environment Texture'].image = image
world.asset_mark()
return world
def message_end():
print('All previews have been generated!')
if __name__ == "__main__":
data_path = 'C:/tmp' # <-------------------- HDRI files
hdri_files = glob.glob(f"{data_path}/*.hdr", recursive = False)
hdri_files.extend(glob.glob(f"{data_path}/*.exr", recursive = False))
assets = []
for image_path in hdri_files:
print(image_path)
assets.append(create_world(image_path))
print(f"{len(hdri_files)} files processed.")
# create preview images
bpy.app.timers.register(
functools.partial(
create_hdri_previews,
assets,
message_end
)
)
Related questions about the preview generation. Kudos to Gorgious.