New plugin that imports HDRI light info

For those of you interested, I have created a simple import script for blender.

This script will import a text file with light data and create a ball of lights to simulate the lighting from an HDRI image.

http://www.geocities.com/calegatter/3dlights.JPG

The text file used is created by the plug-in “Median Cut”
(my script will only work with the text file created by this plugin)
http://www.banterle.com/francesco/download.html

This plug-in is used with HDRShop, found here
http://gl.ict.usc.edu/HDRShop/

I am new to blender and am still playing with this script.

I was hoping someone else out there would try it and see if they can come up with results as shown on Banterles’s page (Link is first one above). I haven’t yet been able to.

This would potentially allow HDRI lighting using blenders internal render engine.

Notes about use:

This script is rough and has to be controlled by changing the script (IE no GUI). If it proves of use, I would like to see me or anyone else develop it further.


#!BPY

""" Registration info for Blender menus:
Name: 'Mediancut light import (.txt)'
Blender: 237
Group: 'Import'
Tip: 'Imports Mediacut text files only'
"""

__author__ = "Cale Fallgatter (calegatter)"

"""
This file can be used freely.  You may modify it, but may not distribute
the modification as a part of my file.  Please give me credit where credit is due.
Thanks and I hope this works well for you

The program that creates the light data was written for HDRShop and was 
written by Francesco Banterle
"""


import Blender
from Blender import Window
from Blender import Lamp
def HDRI_LIGHTS(filename):         # callback for the FileSelector
  file = open(filename)
  #Open only a text file created by Mediancut plugin for HDRShop
  kills = 0                        #counter to terminate loop
  position = 0                     #counter to keep place in list
  line = file.readlines()
  line = line[4:]                  #gets rid of junk at begining of file
  line = line +['
']+['
']+['
']  #add blank lines to end of file to avoid read error
  power_total = []
  #this for loop is used for presorting file to add total number of light pixels
  #this will be used to give each lamp an emit power less than 1 so they total to 1
  for x in line:
    #Looking for line in text that gives coord. of lights
    if line[position][0:4] == 'Dir:':          
      kills = 0              
      position = position + 1
      continue
    #Looking for line in text that gives power of lights in RGB values
    elif line[position][0:4] == 'Pow:':                     
      kills = 0
      #If light power is found it is stored here as a list
      power = line[position][4:].split()
      power = [float(power[0]),float(power[1]),float(power[2])]
      power_total[:0] = power                  
      position = position + 1
      continue
    else:
      position = position + 1
      kills = kills + 1
    if kills == 1:      #allows the loop to continue if only one blank line is found
      continue
    elif kills == 2:    #terminates loop if two consecutive blank lines are found
      power_total_sum = sum(power_total)
      break
    else:
      continue
      
  kills = 0
  position = 0
  for x in line:
    #Looking for line in text that gives coord. of lights
    if line[position][0:4] == 'Dir:':          
      kills = 0
      #If light coord. are found they are stored as a list here
      direction = line[position][4:].split()
      direction = [float(direction[0]),float(direction[1]),float(direction[2])]               
      position = position + 1
      continue
    #Looking for line in text that gives power of lights in RGB values
    elif line[position][0:4] == 'Pow:':                     
      kills = 0
      #If light power is found it is stored here as a list
      power = line[position][4:].split()
      power = [float(power[0]),float(power[1]),float(power[2])]
      power_sum = sum(power)
      RGB = [power[0]/power_sum, power[1]/power_sum, power[2]/power_sum] 
      Energy = (power_sum/power_total_sum)*100                  
      position = position + 1
    else:
      position = position + 1
      kills = kills + 1
    if kills == 1:      #allows the loop to continue if only one blank line is found
      continue
    elif kills == 2:    #terminates loop if two consecutive blank lines are found
      break
    else:
      pass
       
    scene = Blender.Scene.getCurrent ()     # get the current scene
    ob = Blender.Object.New ('Lamp','Lamp'+str(position))  # make lamp object
    l = Blender.Lamp.New ()                 # make lamp data object
    ob.link (l)                             # link lamp data with the object
    scene.link (ob)                         # link the object into the scene
    ob.setLocation (direction)              # position the object in the scene
    l.setCol(RGB)                           # sets light color
    l.setEnergy(Energy)                     # sets light energy
    l.setMode('RayShadow')                  # sets ray shadow to active
    
Window.FileSelector (HDRI_LIGHTS, "Open Mediancut Text File")
#
#
Blender.Redraw()                    # redraw the scene to show the updates.

Let me know what you think

Well it works. It gives an error but it still works. If only it was spotlights with buffered shadows instead of the ray traced shadows.

I also had to select all the lights and scale them a lot bigger to get a normal strenght in the lights.

Great stuff going on here.

I don’t receive any errors when I use it. Would you please tell me what the error message is?

Also, what is the benifit of spotlights with buffered shadows? I am going to try and make a version of the script with your requests.

For the light intensity find the line in the script

Energy = (power_sum/power_total_sum)*100

The “100” scales the light intensity. Just change this to whatever you want.

I forgot to mention that this script will only work properly with blender 2.4.

How do you get the plug-ins to work with HDRSHop? I have 1.0.3 and put the plug-ins in the same directory as the HDRShop program file, but I can’t get the plug-ins to appear in the Plugins drop down menu.

Create a plugins folder.

\HDRShop\plugins

Place the plugins there.

Rescan the directory in HDRShop

calegatter: That worked, thanks.

Here is a modified version of the script.

I creates spot lights with buffer shadows.

All of the lights will be pointing in one direction so you will have to select all of them and track them to something.

Here is a rendered picture of the monkey using this lighting.
http://www.geocities.com/calegatter/Monkey.jpg

Here is a screen shot of what the lights look like
http://www.geocities.com/calegatter/SpotBall.JPG

I think this will be more usefull than the first version.


#!BPY

""" Registration info for Blender menus:
Name: 'Mediancut light import (.txt)'
Blender: 237
Group: 'Import'
Tip: 'Imports Mediacut text files only'
"""

__author__ = "Cale Fallgatter (calegatter)"

"""
This file can be used freely.  You may modify it, but may not distribute
the modification as a part of my file.  Please give me credit where credit is due.
Thanks and I hope this works well for you

The program that creates the light data was written for HDRShop and was 
written by Francesco Banterle
"""


import Blender
from Blender import Window
from Blender import Lamp
def HDRI_LIGHTS(filename):         # callback for the FileSelector
  file = open(filename)
  #Open only a text file created by Mediancut plugin for HDRShop
  kills = 0                        #counter to terminate loop
  position = 0                     #counter to keep place in list
  line = file.readlines()
  line = line[4:]                  #gets rid of junk at begining of file
  line = line +['
']+['
']+['
']  #add blank lines to end of file to avoid read error
  power_total = []
  #this for loop is used for presorting file to add total number of light pixels
  #this will be used to give each lamp an emit power less than 1 so they total to 1
  for x in line:
    #Looking for line in text that gives coord. of lights
    if line[position][0:4] == 'Dir:':          
      kills = 0              
      position = position + 1
      continue
    #Looking for line in text that gives power of lights in RGB values
    elif line[position][0:4] == 'Pow:':                     
      kills = 0
      #If light power is found it is stored here as a list
      power = line[position][4:].split()
      power = [float(power[0]),float(power[1]),float(power[2])]
      power_total[:0] = power                  
      position = position + 1
      continue
    else:
      position = position + 1
      kills = kills + 1
    if kills == 1:      #allows the loop to continue if only one blank line is found
      continue
    elif kills == 2:    #terminates loop if two consecutive blank lines are found
      power_total_sum = sum(power_total)
      break
    else:
      continue
      
  kills = 0
  position = 0
  for x in line:
    #Looking for line in text that gives coord. of lights
    if line[position][0:4] == 'Dir:':          
      kills = 0
      #If light coord. are found they are stored as a list here
      direction = line[position][4:].split()
      direction = [float(direction[0]),float(direction[1]),float(direction[2])]               
      position = position + 1
      continue
    #Looking for line in text that gives power of lights in RGB values
    elif line[position][0:4] == 'Pow:':                     
      kills = 0
      #If light power is found it is stored here as a list
      power = line[position][4:].split()
      power = [float(power[0]),float(power[1]),float(power[2])]
      power_sum = sum(power)
      RGB = [power[0]/power_sum, power[1]/power_sum, power[2]/power_sum] 
      Energy = (power_sum/power_total_sum)*100                  
      position = position + 1
    else:
      position = position + 1
      kills = kills + 1
    if kills == 1:      #allows the loop to continue if only one blank line is found
      continue
    elif kills == 2:    #terminates loop if two consecutive blank lines are found
      break
    else:
      pass
       
    scene = Blender.Scene.getCurrent ()     # get the current scene
    ob = Blender.Object.New ('Lamp','Lamp'+str(position))  # make lamp object
    l = Blender.Lamp.New ('Spot')                 # make lamp data object
    ob.link (l)                             # link lamp data with the object
    scene.link (ob)                         # link the object into the scene
    ob.setLocation (direction)              # position the object in the scene
    l.setCol(RGB)                           # sets light color
    l.setEnergy(Energy)                     # sets light energy
    l.setMode('Shadows')                    # sets Shadow Buff. shadow to active
    
Window.FileSelector (HDRI_LIGHTS, "Open Mediancut Text File")
#
#
Blender.Redraw()                    # redraw the scene to show the updates.

I was going to post some quick test images that I made with the Lamp version of the script versus the new spot version. I set the energy of the lamps to *25 as opposed to the *100 that is originally in the script.

The problem is that when I reply I don’t see the choice in the editor to post an attach an image. Where’d they go.

You have to post the images somewhere that allows image hosting. I use geocities.

Imageshack might be easier.
http://www.imageshack.us/

Then you post the link to the image between [‘img’](image link goes here)[’/img’]

(Remove the single quotes first)

There is an button, “Img”, at the top that automates this.

I look forward to seeing your results.

Last time I posted to the boards about a week ago, you could upload images to be hosted by Elysiun. Are they not doing this anymore?

[edit]
I just checked and they only host images in the Artwork forums. I;ll see if I can get the images hosted somewhere.
[/edit]

Here they are:

LAMP:
http://img265.imageshack.us/img265/8476/hdriscriptlamp0ml.th.png

SPOT:
http://img265.imageshack.us/img265/6856/hdriscriptspot5mf.th.png

Here is the HDR I used to get the lighting data:
http://img390.imageshack.us/img390/1287/kitchenprobe7fb.th.jpg

Would you mind sharing your .blend files so I can see your set up.

Your results are much better than I have achieved.

Here is the blend file I used. All I did was:

  1. Import the lights at Energy*25 (not *100)
  2. Create a plane and UV sphere inside the lights, I never touched the lights (default materials)
  3. For the spots, I added an empty at 0,0,0 and track the spots to that to get them all pointing at the sphere.
  4. Rendered in Blender (OSA: 8, Ray On, 640x480 - 75%)

Layers in this file:
1 - Plane, Sphere, camera, empty
2 - Lamp lights
3 - Spot lights

http://blender.sixmonkeys.geek.nz/albums/kirpre/HDRIScriptTest.blend

In your first preview I saw well a LOT of lamps.
Won’t this slow down performance incredibly?
What’s the difference between a Yafray/HDRI render
and a Blender render with your script?
P

You can choose how many lights to use to simulate an HDRI image. I used 256. You can use less.

Your right about process time. Using that many lights is kinda slow. The reason I created this is because of problems I was having rendering with HDRI in yafray (specifically refraction of textures).

According to the developers of the algorithm (the one that converts the HDRI into light), this was suppose to be fast compared to HDRI.

As it stands, its another tool to ad to the arsenal.

If you do try it out, give me some ideas to make it more usefull.

Here’s the results from rendering my images on the previous page:

Lamps: 10:14
Spots: 2:54
Yafray (w/ pretty high quality settings): < 1 minute

Would you please tell me what the error message is?

Well it just says to me to check the console.

About the buffered shadows.
The problem right now is that you can’t change SpotSi to 120 degrees and the bias to 0.01 or change the ShadowBufferSize.

Can you make this options in the script?

Here is my result with the Spot Size set to 120 and the bias to 0.01 (as suggested by bigbad). The lighting looks much better. This was the first time I have ever modified a script and the API is very helpful with little tweaks like this (http://members.iinet.net.au/~cpbarton/ideasman/BPY_API/)

It would be great to see a simple interface that allows you to set some of the basic lighting options (type, energy, distance, etc.). Calegatter, thanks for your work on this script.

http://img489.imageshack.us/img489/3954/hdriscriptspot21lt.th.png

That looks great.

Could you post the modified script?

This is very handy.