I have plotted a series of blue and red spheres to replicate an atomic structure.

I would like the blue and red spheres to remain distinct; such that when I rotate the model, and the spheres overlap, the colours stay blue and red.

The problem I am facing is that the colours mix where the spheres overlap.

E.g) Plotting Blue and Red spheres. I want the spheres to remain blue of red, however when I move the camera, the overlapping spheres appear pink at the intersection.

blue and red spheres ovelap to give purple. I want only red and blue to show How do I stop the colours from mixing into this purple-ish tone and keep my spheres red and blue?

See my source code below for more information:

import bpy
import numpy as np
sizes = { 'In' : 0.7, 'Ga' : 0.7 }
colors = { 'In' : (0.0, 0.0, 255.0, 0.3), 'Ga' : (255.0, 0.4, 0.4, 0.7), 'bond': (0.05, 0.05, 0.05 , 0.1) }
for key in colors.keys():
    bpy.data.materials[key].diffuse_color = colors[key]
    bpy.data.materials[key].specular_intensity = 0.1
def distance(a, b):
    return np.sqrt(np.dot(a - b, a - b))
def normalize(a):
    return np.array(a) / np.sqrt(np.dot(a, a))
class Structure:
    def __init__(self, filename):
        with open(filename, 'r') as f:
            data = f.readlines()
        self.n_atoms = int(data[0].split()[0])
        self.atom_list = [line.split()[0] for line in data[2:]]
        coordinates = []
        for i, line in enumerate(data[2:]):
            coordinates.append([float(value) for value in line.split()[1:4]])
        self.coordinates = np.array(coordinates)
        self.bonds = set()
    def add_bonds(self, atom_types, cutoff):
        for i in range(self.n_atoms - 1):
            position_1 = self.coordinates[i]
            element_1 = self.atom_list[i]
            if not element_1 in atom_types:
            for j in range(i + 1, self.n_atoms):
                position_2 = self.coordinates[j]
                element_2 = self.atom_list[j]
                if not element_2 in atom_types:
                dist = distance(position_1, position_2)
                if dist <= cutoff:
                    self.bonds.add((i, j))
    def draw_bonds(self):
        for atom_1, atom_2 in self.bonds:
            pos_1 = self.coordinates[atom_1]
            pos_2 = self.coordinates[atom_2]
            difference = pos_2 - pos_1
            center = (pos_2 + pos_1) / 2.0
            magnitude = distance(pos_1, pos_2)
            bond_direction = normalize(difference)
            vertical = np.array((0.0, 0.0, 1.0))
            rotation_axis = np.cross(bond_direction, vertical)
            angle = -np.arccos(np.dot(bond_direction, vertical))
            bpy.ops.transform.rotate(value=angle, axis=rotation_axis)
    def draw_atoms(self):
        for element, position in zip(self.atom_list, self.coordinates):
            bpy.ops.mesh.primitive_uv_sphere_add(radius=sizes[element], location=position)
    def draw_structure(self):
#        self.draw_bonds()
InGaN = Structure(r'\8x8x5-xIn=0.5.xyz')

  • $\begingroup$ Does it also happen with material alpha 1? Can you please add a sample data file? See blender.stackexchange.com/questions/55965/… re copying object rather than multiple create primitive operator calls. $\endgroup$
    – batFINGER
    Commented Jun 10, 2020 at 13:28

2 Answers 2


Try changing the "color" line to:

colors = { 'In' : (0.0, 0.0, 255.0, 1.0), 'Ga' : (255.0, 0.4, 0.4, 1.0), 'bond': (0.05, 0.05, 0.05 , 1.0) }
  • $\begingroup$ This did the trick! Thanks for the one-line fix :) $\endgroup$
    – hkh
    Commented Jun 10, 2020 at 15:04

The materials you create in your script seem to be translucent, as you can clearly make out the contours of what is behind individual balls (hence the "color-blending" effect resulting in this pinkish color).

I do not know why this is the case, since the API clearly states that the default blend mode is set to OPAQUE when creating a new material via scripting.

My suggestion would be to create your necessary materials manually with Blender's powerful Node-Editor to get the desired result.

If you need an amount of different materials that would be unfeasible to create individually by hand, start out with one handmade non-translucent "Base"-material and copy it via scripting and just modify it's diffuse color every time you copy it.


You must log in to answer this question.

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