I'm using a Python script to generate a star-field using data from ~9k of the brightest stars (data is taken from here) Spheres are generated equidistant from the camera (eventually these will be filled circle billboards), and I'm hoping to adjust their magnitudes using an emission shader.

Is there a way to adjust the emission strength of each individual sphere without creating 9000+ separate textures?

My first run at the code was able to change the emission strength of the material, but it's changing it for all of the spheres each time. The code is below:

# Load star data from file
starData = np.loadtxt('/stars/catalog_text')
distanceMultiplier = 1000 * 5

# Create base stare
star1 = Star(starData[0])
starMesh = star1.getMesh()

# Duplicate mesh for every star in the data
i = 0
for star in starData:
    i += 1

    # Set Location variables from data
    magnitude = star[2]
    x = star[3] * distanceMultiplier
    y = star[4] * distanceMultiplier
    z = star[5] * distanceMultiplier

    # Set star magnitude from data
    # (convertMagnitude maps the magnitude value to an emission strength value in Blender) 
    emission = bpy.context.active_object.active_material.node_tree.nodes.get("Emission")
emission.inputs[1].default_value = convertMagnitude(magnitude)

    # Create a copy of our base star
    newOb = starMesh.copy()

    # Assign unique name and location to mesh
    newOb.name = "star_" + str(i)
    newOb.location = (x, y, z)

    # Link mesh to the scene
  • $\begingroup$ Do the stars' materials need to have the texture? $\endgroup$ – someonewithpc Feb 4 '15 at 20:59
  • $\begingroup$ you may group the stars that have the same emission strength in group than set the emission to that value render only this group than move to the next group when done combine the result in the compositor $\endgroup$ – Chebhou Feb 4 '15 at 21:32
  • $\begingroup$ This will help: blender.stackexchange.com/questions/23417/… also you will find there how to assign those vertex colors with python $\endgroup$ – Jaroslav Jerryno Novotny Feb 5 '15 at 23:49

here is a quick solution : use this node setup

enter image description here

set the pass index of the star to its emission brightness

enter image description here

and here is the result :

enter image description here

  • 1
    $\begingroup$ This worked, thanks! I knew something like this had to be possible - I was using almost exactly the same setup using "random" to fake the magnitude. $\endgroup$ – nfojunky Feb 7 '15 at 19:31

There currently appears to be no way to have one material with different settings for each object using it. While an object knows what materials it uses, a material has no link back to the object using it, as a single material may be used by many objects there is also the trouble of choosing which object is currently active.

I see two ways to tackle your problem, one material for each object or a range of materials to be shared across objects. I think a range of materials with varying emission strengths could be generated and one chosen as each object is created. I'm not sure of the range of values in your data, but expect that emission values could be averaged out a bit so that magnitudes within a range could use the same material.

if magnitude >= 100 and magnitude < 200
    obj.material_slots[0] = bpy.data.materials['mag150']
  • $\begingroup$ This is not true, material can read from object - for example vertex colors and indexes. It can be used for this.. $\endgroup$ – Jaroslav Jerryno Novotny Feb 5 '15 at 23:47
  • $\begingroup$ yeah, I was going off failures to retrieve values with drivers. Your use of vertex colours looks interesting. $\endgroup$ – sambler Feb 6 '15 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.