Blender as a Renderer

Ideas, enhancements, feature requests and development related discussion.

Blender as a Renderer

Postby dcuny » Sat Mar 01, 2008 1:11 pm

I'm put together a simple Python script that reads through a Blender scene and prints out a bunch of attributes. The on-line API was helpful in figuring a lot of stuff out, as well as the tutorial on writing an export script.

Basically, I did a dir() on every type of object, and looked for the getAttribute() methods, since there are equivalent setAttribute() methods that can be used to set the attribute back when the scene is reconstructed.

The main objects in Blender are Cameras. Lamps and Mesh.

The Camera is pretty straight forward:
Code: Select all
CAMERA_START
name  Camera
loc  (7.4811315536499023, -6.5076398849487305, 5.3436651229858398)
rot  1.10931897163 0.0108169913292 0.814928174019
size  (1.0, 1.0, 1.0)
clipEnd 100.0
clipStart 0.10000000149
drawSize 0.5
lens 35.0
mode 8
name Camera
scale 7.31428575516
type 0
CAMERA_END
A number of these attributes (clipStart, clipEnd, drawSize) probably can be dropped.

The Lamp has a few more attributes:
Code: Select all
LAMP_START
name  Lamp
loc  (4.0762453079223633, 1.0054539442062378, 5.9038619995117188)
rot  0.650327980518 0.0552171133459 1.86639082432
size  (1.0, 1.0, 1.0)
areaSizeX 1.0
areaSizeY 1.0
bias 1.0
bufferSize 2880
clipEnd 30.0020008087
clipStart 1.00079894066
col [1.0, 1.0, 1.0]
dist 29.9999828339
energy 1.0
haloInt 1.0
haloStep 0
mode 8192
quad1 0.0
quad2 1.0
raySamplesX 1
raySamplesY 1
samples 3
softness 3.0
spotBlend 0.15000000596
spotSize 75.0
type 0
haloInt 1.0
LAMP_END
The mode is a series of bit flags. Most of the flags are ignored if the particular setting isn't set on.

The Mesh is the most complex. It contains Materials, which contain Textures. I probably won't bother trying to support the textures at this point - they're just too complicated.

A Mesh is a collection of Faces which are made up of Vertices. Each face can have the following attributes:
Code: Select all
face 0 1 2 3
face.col []
face.flag 28009
face.hide 0
face.image None
face.mat 0
face.materialIndex 0
face.mode 1
face.normal [0.0, 0.0, -1.0]
face.sel 1
face.smooth 0
face.transp 112
face.uv []

The [] indicates an empty list. Each vertex of the face can be set to a seperate (r,g,b) value. I'm currently only planning on supporting the materialIndex attribute, which will reference the attributes of the mesh's material.

There are a lot of attributes of the Material, but again, most of them only make sense when other options are set. They are:
Code: Select all
MATERIAL_START
add 0.0
alpha 1.0
amb 0.5
diffuseDarkness 1.0
diffuseShader 0
diffuseSize 0.5
diffuseSmooth 0.10000000149
emit 0.0
filter 0.0
flareBoost 1.0
flareSeed 6
flareSize 1.0
fresnelMirr 0.0
fresnelMirrFac 1.25
fresnelTrans 0.0
fresnelTransFac 1.25
haloSeed 0
haloSize 0.5
hardness 50
IOR 1.0
mirCol [1.0, 1.0, 1.0]
mirrDepth 2
mode 50397187
nFlares 1
nLines 12
nRings 4
nStars 4
name Material
rgbCol [0.80000001192092896, 0.80000001192092896, 0.80000001192092896]
rayMirr 0.0
ref 0.800000011921
refracIndex 4.0
rms 0.10000000149
roughness 0.5
spec 0.5
specCol [1.0, 1.0, 1.0]
specShader 0
specSize 0.5
specSmooth 0.10000000149
specTransp 1.0
subSize 1.0
transDepth 2
translucency 0.0
zOffset 0.0
MATERIAL_END

I've removed the Textures, Vertices and Faces from the list. There are a number of attributes that I haven't included yet, such as subsurface scattering and color ramps. The attributes are there, but there are not setAttribute() methods for them. I figured I can add these later.

I haven't done the Render object yet, but I think most of the settings can be reached from the command line. I'm not entirely sure where AO is - I think it's a World attribute.

Next on the "To Do" list, I need to read how to write an import script.

Do you have any opinions on what the output should look like? I'm thinking I should write it so that most of the attributes are optional, and any unknown attribute is ignored.

Thoughts? :?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: Blender as a Renderer

Postby sascha » Sat Mar 01, 2008 3:42 pm

If it doesn't support SDS natively, JPatch will have to export a triangle (or quadrilateral) mesh anyway.

As far as materials are concerend, right now JPatch doesn't support anything that's beyond vanilla OpenGL material definitions with ambient, diffuse, specular and emissive colors.

For RenderMan, you'll be able to specify a shader (and to controll the shader parameters from within the animator), but the shader has to be created externally (in a first step). A similar approach would make sense for all the other renderers - a PovRay material definition has to be written in POV SDL, and a Blender Material should be created with Blender.
sascha
Site Admin
 
Posts: 2792
Joined: Thu May 20, 2004 9:16 am
Location: Austria

Re: Blender as a Renderer

Postby dcuny » Sat Mar 01, 2008 7:53 pm

Thanks. I'll start with a fairly "plain vanilla" export then. It'll probably look something like the .obj file, with the materials embedded into the file.
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: Blender as a Renderer

Postby dcuny » Tue Mar 04, 2008 10:04 am

I've got a simpler export script working. It ended up taking longer than I thought, mostly because I'm a Python newbie.

The script is pretty simple, and needs some additional features (image size, anti-aliasing, etc), but does the basics of dumping the mesh and materials. I ended up using a format similar to the Sunflow format, since I think it's pretty readable. Here's the output for a scene with two differently colored cubes:
Code: Select all
material {
   name Blue
   ka 1.000000 1.000000 1.000000
   ks 1.000000 1.000000 1.000000
   kd 0.208476 0.032384 0.986822
}

material {
   name Red
   ka 1.000000 1.000000 1.000000
   ks 1.000000 1.000000 1.000000
   kd 0.986822 0.000000 0.000000
}

mesh {
   name RedCube
   material Red
   location 2.572083 -1.164206 0.000000
   rotation 0.000000 -0.000000 -0.262755
   size 1.000000 1.000000 1.000000
   vertices 8
   -1.798866 4.010101 -1.000000 0.577349 0.577349 -0.577349 0.000000 0.000000
   -1.798866 2.010102 -1.000000 0.577349 -0.577349 -0.577349 0.000000 0.000000
   -3.798866 2.010102 -1.000000 -0.577349 -0.577349 -0.577349 0.000000 0.000000
   -3.798866 4.010102 -1.000000 -0.577349 0.577349 -0.577349 0.000000 0.000000
   -1.798866 4.010101 1.000000 0.577349 0.577349 0.577349 0.000000 0.000000
   -1.798867 2.010101 1.000000 0.577349 -0.577349 0.577349 0.000000 0.000000
   -3.798867 2.010102 1.000000 -0.577349 -0.577349 0.577349 0.000000 0.000000
   -3.798866 4.010101 1.000000 -0.577349 0.577349 0.577349 0.000000 0.000000
   faces 6
   0 1 2 3
   4 7 6 5
   0 4 5 1
   1 5 6 2
   2 6 7 3
   4 0 3 7
}

mesh {
   name BlueCube
   material Blue
   location 1.584264 -2.587631 0.000000
   rotation 0.196730 2.523273 0.331169
   size 1.000000 1.000000 1.000000
   vertices 8
   1.000000 1.000000 -1.000000 0.577349 0.577349 -0.577349 0.000000 0.000000
   1.000000 -1.000000 -1.000000 0.577349 -0.577349 -0.577349 0.000000 0.000000
   -1.000000 -1.000000 -1.000000 -0.577349 -0.577349 -0.577349 0.000000 0.000000
   -1.000000 1.000000 -1.000000 -0.577349 0.577349 -0.577349 0.000000 0.000000
   1.000000 0.999999 1.000000 0.577349 0.577349 0.577349 0.000000 0.000000
   0.999999 -1.000001 1.000000 0.577349 -0.577349 0.577349 0.000000 0.000000
   -1.000000 -1.000000 1.000000 -0.577349 -0.577349 0.577349 0.000000 0.000000
   -1.000000 1.000000 1.000000 -0.577349 0.577349 0.577349 0.000000 0.000000
   faces 6
   0 1 2 3
   4 7 6 5
   0 4 5 1
   1 5 6 2
   2 6 7 3
   4 0 3 7
}

lamp {
   name Lamp
   location 4.076245 1.005454 5.903862
   rotation 0.650328 0.055217 1.866391
   size 1.000000 1.000000 1.000000
   color 1.000000 1.000000 1.000000
   type lamp
}

camera {
   name Camera
   location 7.481132 -6.507640 5.343665
   rotation 1.109319 0.010817 0.814928
   size 1.000000 1.000000 1.000000
   type perspective
}

So the next thing to do will be to write an importer. :?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: Blender as a Renderer

Postby dcuny » Tue Mar 04, 2008 10:09 pm

It doesn't look like Blender exposes the AAO attributes to Python at this point. One reason for this is that it's so new, it's not even available in the official builds. One possible workaround for this would be to open a pre-build Blender scene with the World attributes already set. Not the most elegant solution, but it should work.

I've been looking around to see if Blender has support for spherical harmonics, because I was curious about combining it with AO. It doesn't look like anyone's coded it, but I found out that Blender's incorporated a Python-based set of custom shaders called PyNodes. These are still in development, but (in theory) stable enough to start playing with.

So, in theory, I could port my spherical harmonic and LDRI shaders into Blender using Python. Interesting. :?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: Blender as a Renderer

Postby dcuny » Fri Mar 07, 2008 11:58 am

Hrm... I'm baffled at this point. After messing around with various options, I've gotten Blender to export and import my file. The problem is, I can't render the scene once it's been loaded. So I guess I'll have to start asking around on the Blender board.

I'm also not quite sure how to launch the script. You can pass the name of a script via the command line, but there doesn't appear to be a way to pass parameters. You can launch a script from within Python, but it's not clear if you can pass parameters. Something else to look into. :?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: Blender as a Renderer

Postby dcuny » Fri Mar 07, 2008 11:11 pm

I found the API for passing parameters to Blender from the command line:
Passing parameters:
To pass parameters to the script you can:
  • write them to a file before running Blender, then make your script parse that file;
  • set environment variables and access them with the 'os' module:

Examples with parameters being passed to the script via command line:

Execute a command like:
Code: Select all
myvar=value blender -P script.py
and in script.py access myvar with os.getenv (os.environ and os.setenv are also useful):
Code: Select all
# script.py:
import os
val = os.getenv('myvar')
To pass multiple parameters, simply write them in sequence, separated by spaces:
Code: Select all
myvar1=value1 myvar2=value2 mystr="some string data" blender -P script.py

Not the most elegant solution I've ever seen, but as long as it works, that's great.

Hopefully someone on the board will be able to figure out the issue with the import script. :|
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: Blender as a Renderer

Postby dcuny » Sat Mar 08, 2008 7:29 am

I found the problem with the import script - I was using 1 as the material index instead of 0. I can now load and display the saved scene. :)

There are still some bits of code I have to write:
  • Read the input and output file names from the command line
  • Add smooth and subdivision parameters to the mesh
  • Add background color and ambient occlusion parameters to the world
  • Pass the input scene and output file names via the command line
Once that's done, I'll post the script with some instructions.
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: Blender as a Renderer

Postby dcuny » Sat Mar 08, 2008 11:11 am

OK, I've got something that's a bit kludgy, but it should work: jpatch_to_blender.zip

I was stuck on the rendering bit, until I ran across this exchange which says that it's broken. :? Anyway, here's the included README file:
README file wrote:To launch Blender from the command line, use the instructions:
Code: Select all
   infile="example" blender -b default.blend -P jpatch_load.py

Here's the breakdown:
  • infile="example" This sets the name of the data file to be parsed
  • blender Launches Blender
  • -b default.b Runs in the background. A blend file is required.
  • -P jpatch_load.py The name of the Python script to run
You can create data files by running the Python script export_jpatch.py from within Blender. You can test load them from within Blender with jpatch_import.py.

A limitation with the scripts is that you cannot currently specify the name of the output file. The instructions:
Code: Select all
    renderContext.render()
    renderContext.saveRender(filname, zbufferFlag)
are supposed to render the file with the specified name, but the saveRender() routine has been broken for some time. The current workaround is:
Code: Select all
    context.sFrame = 1
    context.eFrame = 1
    context.renderAnim()
[/code]which will render a single frame of animation, named 0001.png.
The format of the file should be self-explanatory. Some features (such as the zenith color) may be broken. Many of the options are not fully implemented.

So what it boils down to is:
  • Blender only seems to run in the background if you supply a .blend file, even if you're creating one from scratch. I could be wrong, but as a temporary workaround, I supply a file.
  • There's a bug that prevents Blender from saving the output file under a given name. The workaround is to accept the default file name, 0001. (The file extension can be set from within the image block).
Hopefully the Blender folk can provide some help on these issues, but at least I've got something that (sort of) works.

Let me know what you think. :?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: Blender as a Renderer

Postby sascha » Sat Mar 08, 2008 11:24 am

So what kind of files do you expect from JPatch?
sascha
Site Admin
 
Posts: 2792
Joined: Thu May 20, 2004 9:16 am
Location: Austria

Re: Blender as a Renderer

Postby dcuny » Sat Mar 08, 2008 7:29 pm

sascha wrote:So what kind of files do you expect from JPatch?

Sorry, I didn't realize how badly I had documented this. :oops:

Have a look at the Example file that's included in the .zip. Basically, it's a text file with a series of blocks describing the scene. I've adopted the notation based on Sunflow's file format of:
Code: Select all
<blocktype> <name> {
<setting name> <value>
...
}
Although not all blocks have names.

There blocks are:
  • image is image attributes;
  • world is global scene settings;
  • camera is the camera;
  • lamp for each light;
  • material for each type of shader material;
  • mesh for each mesh.
Here the breakdown for the example file. First, the image block:
Code: Select all
image {
   resolution 800 600
   imagetype jpeg
   osa
   shadow
   raytracing
}
  • resolution is the x/y resolution of the image
  • imagetype is type of file to produce. targa, hdr, png, bmp, jpeg, openexr and tiff are supported.
  • osa indicates oversampling is to be used. There's no way to set the oversampling level yet.
  • shadow indicates that the scene will cast shadows.
  • raytracing indicates the scene will use raytracing.
Since the scene defaults to the values set in the .blend file, most of these aren't necessary. In the future, I'll probably change flags so they indicate on or off.

The world block is:
Code: Select all
world {
   horizon 0.056563 0.220815 0.400000
   zenith 0.100000 0.100000 0.100000
}
This sets the horizon and zenith colors using RGB tuples with values from 0..1.

You can have multiple material blocks. From the example:
Code: Select all
material Material {
   ambient 0.500000
   specular 1.000000 1.000000 1.000000
   diffuse 0.800000 0.800000 0.800000
}
The name of the material is Material. You can use any names you want, but the parser expects values to be space delimited. Currently, only specular and diffuse colors are supported. The ambient parameter tells how much ambient lighting to apply. There's a global amb parameter that sets the ambient color that I haven't implemented yet.

The mesh block is the largest, but it's not too complicated:
Code: Select all
mesh Suzanne {
   material red
   location 0.000000 0.000000 0.000000
   rotation 0.000000 -0.000000 0.000000
   size 1.000000 1.000000 1.000000
   smooth
   vertices 507
   0.437500 0.164062 0.765625 0.722587 -0.669759 0.171026 0.000000 0.000000
   -0.437500 0.164062 0.765625 -0.722587 -0.669759 0.171026 0.000000 0.000000
   0.500000 0.093750 0.687500 0.601306 -0.478561 0.639790 0.000000 0.000000
        ....
   faces 500
   46 0 2 44
   3 1 47 45
        ...
}
The name of this mesh is Suzanne. It's not actually used by anything.

The material references a prior material block by name.

The location, rotation and size are what they say, but I haven't played with them enough to know what sorts of values that Blender expects. They can be left off, since they are set to default values when the mesh is created.

The smooth attribute indicates that the mesh is to be rendered with smoothing. I should add an additional smoothing angle parameter as well.

The vertices parameter precedes the vertex list, and indicates the vertex count. Each line following indicates a vertex. The first three values are the x,y,z position. The next three are the normal. The last two are the u,v values. The normal and u/v values are optional, but if you have u/v, you need to have the normal as well.

The faces parameter precedes the face list, and provides the face count. Each line following indicates a set of vertices that makes up a face, indexing into the vertices list. It's zero based.

The lamp block indicates a light. The example:
Code: Select all
lamp Lamp {
   location 4.076245 1.005454 5.903862
   rotation 0.650328 0.055217 1.866391
   size 1.000000 1.000000 1.000000
   color 1.000000 1.000000 1.000000
   type lamp
}
is pretty self-explanatory, except for the type. The supported types are lamp, sun, spot, hemi, area and photon. Each type of lamp has a lot of parameters associated with them, but I haven't implemented them yet.

Finally, the camera block declares the camera:
Code: Select all
camera Camera {
   location 7.481132 -6.507640 5.343665
   rotation 1.109319 0.010817 0.814928
   size 1.000000 1.000000 1.000000
   type perspective
}
Since there will only be a single camera in the scene, it seems sort of pointless to have a name associated with it. The type can me perspective or orthographic. (Ooops... Just found a bug in that code :roll:). There are a lot of parameters that I haven't included in the camera block yet.

This file format is pretty much a literal interpretation of Blender's various settings, with a lot of stuff still left to do.

Thoughts? Would you prefer a different sort of file format?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am


Return to Development

Who is online

Users browsing this forum: No registered users and 2 guests

cron