I’m doing something where I’m needing to import tons and tons and tons of reference images into a project. They cannot have the black borders. The “Image/Mesh Plane” would be the solution, but I don’t want to use it because a) it doesn’t render the image by default (you have to do extra setup), and b) you can’t drag/drop in images, you have to manually add it and set it up. Given the volume of images in m project, I don’t have time for this.
I couldn’t figure out how to remove the black outline, but here’s a workaround that was good enough for me.
I asked gemini to write a script which converts every reference image to a shaderless mesh plane. Running this script is a lot faster than manually clicking through the UI. I’m on Blender vesion 4.2 – there’s no guarantee the script will work on any other version.
NOTE 1: You need to be in “material preview” or “rendered” and not “solid” to see the image in the mesh plane.
NOTE 2: this was made by gemini, not me, so it’s possible that it could have some strange behaviors or weird lines of code. However, I tested it and it seems to work fine.
import bpy
import math
def create_shaderless_material(image, name):
"""Creates a shaderless material with alpha transparency."""
mat = bpy.data.materials.new(name=name)
mat.use_nodes = True
nodes = mat.node_tree.nodes
links = mat.node_tree.links
# Clear default nodes
nodes.clear()
# Create nodes
node_output = nodes.new(type='ShaderNodeOutputMaterial')
node_output.location = (400, 0)
node_mix = nodes.new(type='ShaderNodeMixShader')
node_mix.location = (200, 0)
node_transparent = nodes.new(type='ShaderNodeBsdfTransparent')
node_transparent.location = (0, 100)
node_emission = nodes.new(type='ShaderNodeEmission')
node_emission.location = (0, -100)
node_tex = nodes.new(type='ShaderNodeTexImage')
node_tex.location = (-300, 0)
if image:
node_tex.image = image
# Link nodes
# Use Image Alpha as the factor for the Mix Shader
links.new(node_tex.outputs['Alpha'], node_mix.inputs['Fac'])
# If Alpha is 0, use Transparent (Top slot), else use Emission (Bottom slot)
links.new(node_transparent.outputs['BSDF'], node_mix.inputs[1])
links.new(node_emission.outputs['Emission'], node_mix.inputs[2])
# Connect color
links.new(node_tex.outputs['Color'], node_emission.inputs['Color'])
# Connect to Output
links.new(node_mix.outputs['Shader'], node_output.inputs['Surface'])
# --- VERSION COMPATIBILITY FIX ---
# Blender 4.2+ removed blend_method and shadow_method (Eevee Next handles this auto)
# Older versions require these to be set manually for transparency to work.
if hasattr(mat, 'blend_method'):
mat.blend_method = 'BLEND'
if hasattr(mat, 'shadow_method'):
mat.shadow_method = 'NONE'
return mat
def convert_refs_to_planes():
# Gather all Image Empties
ref_images = [obj for obj in bpy.context.scene.objects
if obj.type == 'EMPTY' and obj.empty_display_type == 'IMAGE']
if not ref_images:
print("No Reference Images found.")
return
# Deselect all to start clean
bpy.ops.object.select_all(action='DESELECT')
count = 0
for ref in ref_images:
img = ref.data # The actual bpy.types.Image
if not img:
continue
# 1. Calculate Dimensions
w, h = img.size
display_size = ref.empty_display_size
if w >= h:
aspect_w = 1.0
aspect_h = h / w
else:
aspect_w = w / h
aspect_h = 1.0
final_w = display_size * aspect_w
final_h = display_size * aspect_h
# 2. Create the Plane
bpy.ops.mesh.primitive_plane_add(size=1, align='WORLD')
plane = bpy.context.active_object
plane.name = f"Mesh_{ref.name}"
# 3. Apply Dimensions to Mesh Data
for vert in plane.data.vertices:
vert.co.x *= final_w
vert.co.y *= final_h
# 4. Copy Transforms
plane.matrix_world = ref.matrix_world
# 5. Create and Assign Material
mat = create_shaderless_material(img, f"Mat_{ref.name}")
plane.data.materials.append(mat)
# 6. Hide Original
ref.hide_viewport = True
ref.hide_render = True
count += 1
print(f"Converted {count} reference images to mesh planes.")
# Execute
convert_refs_to_planes()