Difference between revisions of "HowTo:Radiosity baking in Blender"

From VsWiki
Jump to: navigation, search
(replaced image links to the sourceforge location)
(Fix links.)
 
(41 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
==Prelude==
 
==Prelude==
I tried making it easy for non-blenderheads to use this guide too but a bit of know how of blender is good (look at [http://download.blender.org/documentation/htmlI/] if you need something to get you started). The method described here was developed and tested with Blender 2.37. Help the community by imporving upon this if you find anything incorrect or missing.
+
I tried making it easy for non-blenderheads to use this guide too but a bit of know how of blender is good (look at [http://www.blender.org/documentation/] if you need something to get you started). The method described here was developed and tested with Blender 2.37. Help the community by improving upon this if you find anything incorrect or missing.
  
 
==Our goal==
 
==Our goal==
Line 15: Line 15:
 
http://vegastrike.sourceforge.net/users/tiny_paintings/radiotut/radio2.jpg
 
http://vegastrike.sourceforge.net/users/tiny_paintings/radiotut/radio2.jpg
  
Our weapon of choice for achieving the desired result is, as the title of the article ever so subtly suggests, radiosity ([[WikiPedia:Radiosity]]). Using radiosity no manual labour will be required as the computer will calculate the ambient intensities for us. In the end, this should slightly alleviate the texturing process and make for promising results.
+
Our weapon of choice for achieving the desired result is, as the title of the article ever so subtly suggests, radiosity [https://en.wikipedia.org/wiki/Radiosity_%28computer_graphics%29]. Using radiosity no manual labour will be required as the computer will calculate the ambient intensities for us. In the end, this should slightly alleviate the texturing process and make for promising results.
  
 
==A step by step guide==
 
==A step by step guide==
Line 22: Line 22:
  
 
# Load your UV-mapped object into Blender and put it on layer 1. Make sure it is UV-mapped! Also get rid of any lamps lingering in the scene.
 
# Load your UV-mapped object into Blender and put it on layer 1. Make sure it is UV-mapped! Also get rid of any lamps lingering in the scene.
## Add an icosphere with its center roughly in the middle of your model ({{kbd|SPACE}}->'''Add'''->'''Mesh'''->'''Icosphere'''). This will be our ambient light source. Higher subdivision yeilds better results (you need a higher value for a mesh with many polygons, play around!) but longer calculation times, 4 should be sufficient.
+
## Select your model and in edit mode (press {{kbd|TAB}} do switch between edit and object modes) remove all duplicate vertices. You do this by selecting all vertices ({{kbd|A}}) and pressing {{kbd|W}}->'''Remove Doubles'''.
 +
## Add an icosphere with its center roughly in the middle of your model ({{kbd|SPACE}}->'''Add'''->'''Mesh'''->'''Icosphere'''). This will be our ambient light source. Higher subdivision yields better results (you need a higher value for a mesh with many polygons, play around!) but longer calculation times, 4 should be sufficient.
 
## Scale up ({{kbd|S}}) the icosphere to encompass your entire model.
 
## Scale up ({{kbd|S}}) the icosphere to encompass your entire model.
## In edit mode ({{kbd|TAB}}) select all the faces ({{kbd|A}}) and flip the normals ({{kbd|W}},{{kbd|9}}). Turn on normal drawing and make sure they're really pointing inward the sphere ({{kbd|F9}}) and enable '''Draw normals'''.
+
## In edit mode select all the faces ({{kbd|A}}) and flip the normals ({{kbd|W}},{{kbd|9}}). In edit mode, enable normal drawing (done in the editing context, {{kbd|F9}}) and make sure they're really pointing inward the sphere. (Note that you ''must'' be in edit mode to see or enable the drawing of normals.)
 
## Go to the material buttons ({{kbd|F5}}) and add a new material to the sphere. Choose the desired light color (white, normally) and give the material some emission, you have to experiment with the emit value but <code>0.02</code> should be a good starting point.
 
## Go to the material buttons ({{kbd|F5}}) and add a new material to the sphere. Choose the desired light color (white, normally) and give the material some emission, you have to experiment with the emit value but <code>0.02</code> should be a good starting point.
 
# You're now ready to start calculating the radiosity. But before you start you might want to subdivide your mesh a few times, to get better results. Do it, say, twice ({{kbd|W}},{{kbd|1}} and repeat).
 
# You're now ready to start calculating the radiosity. But before you start you might want to subdivide your mesh a few times, to get better results. Do it, say, twice ({{kbd|W}},{{kbd|1}} and repeat).
## Go to the shading context ({{kbd|F5}}) and then the radiosity buttons. Select both the meshes and press '''Collect meshes'''. Switch from '''Solid''' to '''Gourad'''.
+
## Go to the shading context ({{kbd|F5}}) and then the radiosity buttons. Select both the meshes and click the '''Collect meshes'''-button. Switch from '''Solid''' to '''Gourad'''.
## {{info}} '''IMPORTANT''': Set <code>MaxEl</code> (''not ElMax!'') to <code>1</code>. This will ensure that Blender doesn't alter the mesh in any way. http://vegastrike.sourceforge.net/users/tiny_paintings/radiotut/radio_panel.jpg
+
## {{info}} '''IMPORTANT''': Set <code>MaxEl</code> (''not ElMax!'') to <code>1</code>. This will ensure that Blender doesn't alter the mesh in any way.<BR/><BR/>http://vegastrike.sourceforge.net/users/tiny_paintings/radiotut/radio_panel.jpg<BR/><BR/>
 
 
 
## Hit [Go] and lean back. Press {{kbd|ESC}} when you're happy with what you see or wait until it finishes. It shouldn't be all black, if it is something went wrong.
 
## Hit [Go] and lean back. Press {{kbd|ESC}} when you're happy with what you see or wait until it finishes. It shouldn't be all black, if it is something went wrong.
## This is optional but if your results are a little spotty or have artifacts you might want to perform '''Face filter''' or '''Element filter''', or both.
+
## This is optional but if the resulting mesh looks a little spotty or have artifacts you might want to perform '''Face filter''' or '''Element filter''', or both.
## Save the radiosity information in a new mesh by pressing '''Make new mesh'''. Move it to layer 2 ({{kbd|M}},{{kbd|2}}).
+
## Save the radiosity information in a new mesh by pressing '''Add new meshes'''. Move it to layer 2 ({{kbd|M}},{{kbd|2}}).
# Now it's time for a little cleaning up before we can bake the radiosity information to a texture. Remove the icosphere from the newly created mesh with the radiosity information. If you're not comfortable with blender, here's how you do it (if your mesh is one solid mesh!):
+
## Click '''Free Radio Data'''.
## Go to layer 2 ({{kbd|2}}). Select the mesh and enter edit mode ({{kbd|TAB}}). Split the meshes by pressing {{kbd|P}},{{kbd|2}}. Leave edit mode ({{kbd|TAB}}) and delete the sphere.
+
# Now it's time for a little cleaning up before we can bake the radiosity information to a texture. Remove the icosphere from the newly created mesh with the radiosity information. If you're not comfortable with blender, here's how you do it:
##Now, since using the radio tool erases all UV-information from the baked mesh we'll somehow need to transfer the vertex color information from the baked mesh to our original mesh. After trying various methods for doing this, none of which worked, I hacked together a small little script (see [[#Script]]) in python to do it.<BR/>Load it, change the mesh names at the top of the file, run it and voila! For the blender impaired here's what you do:  
+
## Go to layer 2 ({{kbd|2}}). Select the mesh and enter edit mode ({{kbd|TAB}}). Remove double vertices with {{kbd|W}}->'''Remove Doubles'''. Hover the sphere with the mouse cursor and press {{kbd|L}} to select it then delete it using {{kbd|X}}->'''Vertices'''.
# Press {{kbd|Shift}}+{{kbd|F11}} to bring up the text editor, load the script from the menu or paste it and then press {{kbd|Alt}}+{{kbd|P}} to run it.<BR/><BR/>Your original, UV-mapped, mesh should now have all the shading information stored safely in the color of each vertex. You should be able to verify this if you set your viewport shading mode to '''Shaded''' (make sure ''VCol Light'' is enabled for your material).<BR/><BR/>The final step is to bake the vertex color information to texture using your favorite texture baking script.
+
## Now, since using the radio tool erases all UV-information from the baked mesh we'll somehow need to transfer the vertex color information from the baked mesh to our original mesh. After trying various methods for doing this, none of which worked, I hacked together a small little script (see [[#Script]]) in python to do it.<BR/>Load it, change the mesh names at the top of the file, run it and voila! For the blender impaired here's what you do:  
# Enable '''VCol Paint''' and '''Shadeless'''.<BR/>Run '''Texture baker''' (found under '''Scripts'''->'''UV''' and included with Blender). If it doesn't work the first time make sure your mesh is indeed on layer 1 and try again.
+
## Press {{kbd|Shift}}+{{kbd|F11}} to bring up the text editor, load the script from the menu or paste it and then press {{kbd|Alt}}+{{kbd|P}} to run it.<BR/>Your original, UV-mapped, mesh should now have all the shading information stored safely in the color of each vertex. You should be able to verify this if you set your viewport shading mode to '''Shaded''' (make sure ''VCol Light'' is enabled for your material).
 +
# The final step is to bake the vertex color information to texture using your favorite texture baking script.<BR/>Enable '''VCol Paint''' and '''Shadeless'''.<BR/>Run '''Texture baker''' (found under '''Scripts'''->'''UV''' and included with Blender). If it doesn't work the first time make sure your mesh is indeed on layer 1 and try again.
  
 
That's it!
 
That's it!
Line 47: Line 48:
 
http://vegastrike.sourceforge.net/users/tiny_paintings/radiotut/radio3.jpg
 
http://vegastrike.sourceforge.net/users/tiny_paintings/radiotut/radio3.jpg
  
==Script==
 
You have to pardon my python n00bness, this is all I could come up with. Feel free to improve it!
 
  
<pre>
+
==Common troubles==
import Blender
 
  
# WHAT DOES IT DO?
+
'''Problem:''' After calculating the radiosity and clicking '''Add new meshes''' the resulting mesh is split into several parts.<BR/>
# This script copies the vertex color information from one mesh
+
'''Solution:''' I don't know why this happens but fixing it is easy. Select all of the parts and join them ({{kbd|Alt}}+{{kbd|J}}) then remove doubles in edit mode ({{kbd|W}},{{kbd|5}}). Someone on cgtalk suggested it might be caused by bad normals but I haven't been able to verify or reject this theory.
# to another, and does so correctly assuming the meshes have the
 
# same geometry, vertex-wise.
 
  
# IMPORTANT: Assumes meshes with exactly equal geometry, vertex-wise.
+
'''Problem:''' Man, it doesn't look pretty! It's spotty and ugly looking. Face and Element Filter doesn't do much good, either.<BR/>
 +
'''Solution:''' The face ratio between your model and the light source isn't good. Either subdivide the sphere more or do fewer subdivisions on the model.
  
fromObj = "Mesh"  # Set this to the resulting mesh from radio calcuation
+
'''Problem:''' The '''Texture Baker''' doesn't render anything or the wrong things. What's up?<BR/>
toObj = "Fuselage_default" # Set this to the name of your original, UV-mapped mesh.
+
'''Solution:''' The version of the Texture Baker currently bundled with blender (Blender 2.37a -> 0.2.6) is out of date and you can get the newest version of the script from the "Texture baker" homepage in the [[#Links]] <code>0.2.8 2005/7/20</code>. See also the bug report [http://projects.blender.org/tracker/index.php?func=detail&aid=2824&group_id=9&atid=125 here].
  
me_from = Blender.Object.Get(fromObj).getData()
+
'''Problem:''' With MaxEl set to 1, simple models such as cubes don't look good at all.<BR/>
me_to = Blender.Object.Get(toObj).getData()
+
'''Solution:'''  Enter edit mode, select all vertices, press W key, and choose '''subdivide'''. The resulting radiosity calculation will run for longer and provide a more realistic solution.
  
if not me_to and not me_from:
+
==Script==
print "ERROR: Source/destination object does not exist"
+
Just save this link as <code>vccopy.py</code>
 +
[http://wiki.vega-strike.org/mediawiki/index.php?title=HowTo:Radiosity_baking_in_Blender/vccopy.py&action=raw vccopy.py]
  
elif len(me_to.verts) != len(me_from.verts)
+
(If it works better for you you can try using this link: [http://wiki.vega-strike.org/mediawiki/index.php?title=HowTo:Radiosity_baking_in_Blender/vccopy.py&action=raw&ctype=text/css vccopy.py])
print "ERROR: Source and destination objects must have the same number of vertices"
 
 
else:
 
# make two lists sorted on coordinates,
 
# containing a face and vertex index i and j respectively
 
 
l_to = []
 
l_from = []
 
 
# format: [ (x,y,z, face index, vertex index), ... ]
 
 
for i in range(len(me_to.faces)):
 
for j in range(len(me_to.faces[i].v)):
 
vert = me_to.faces[i].v[j].co
 
l_to.append((vert[0], vert[1], vert[2], i, j))
 
 
for j in range(len(me_from.faces[i].v)):
 
vert = me_from.faces[i].v[j].co
 
l_from.append((vert[0], vert[1], vert[2], i, j))
 
 
# Sort the lists after vertex coordinates
 
l_to.sort()
 
l_from.sort()
 
 
for i in range(len(l_to)):
 
to_f = l_to[i][3]
 
from_f = l_from[i][3]
 
to_v = l_to[i][4]
 
from_v = l_from[i][4]
 
 
me_to.faces[to_f].col[to_v] = me_from.faces[from_f].col[from_v]
 
 
  
me_to.update()
+
[[HowTo:Radiosity_baking_in_Blender/vccopy.py]] - The clutter you see on this page is intended. See the source by editing the page.
print "Copied vertex color information from object "+fromObj+" to object "+toObj+"."
 
</pre>
 
  
 
==Links==
 
==Links==
 
* [[WikiPedia:Radiosity]]
 
* [[WikiPedia:Radiosity]]
 +
* [http://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/Baking Wikibook:Blender 3D: Noob to Pro: Baking Radiosity] (currently WIP)
 +
* [http://www.blender3d.org/forum/viewtopic.php?t=4599 "Baking radio data into textures is here..."] thread in the [http://www.blender3d.org/forum/index.php blender3d.org forum] -> ("Bake Radio" script by ideasman)
 +
** See also the [http://members.iinet.net.au/~cpbarton/ideasman/ homepage] ideasman.
 +
* [http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_mesh3d2uv2d.htm Copie les coordonnées UV d'un mesh à la place de ses coordonnées 3D] (french) - The "Texture Baker" homepage and a tutorial similar to this one.
 
* [http://download.blender.org/documentation/htmlI/ Blender documentation - User guide]
 
* [http://download.blender.org/documentation/htmlI/ Blender documentation - User guide]
 
* [http://download.blender.org/documentation/htmlII/ Blender documentation - Reference]
 
* [http://download.blender.org/documentation/htmlII/ Blender documentation - Reference]
* [http://vegastrike.sourceforge.net/forums/viewtopic.php?p=48148#48148 Original tutorial] in the forum (by [[User:Tiny paintings|tiny paintings]])
+
* [http://forums.vega-strike.org/viewtopic.php?p=48148#48148 Original tutorial] in the forum (by [[User:Tiny paintings|tiny paintings]])
  
 
[[Category:HowTos|Radiosity baking in Blender]]
 
[[Category:HowTos|Radiosity baking in Blender]]
 
[[Category:Development|Radiosity baking in Blender]]
 
[[Category:Development|Radiosity baking in Blender]]
 
[[Category:Artwork|Radiosity baking in Blender]]
 
[[Category:Artwork|Radiosity baking in Blender]]
 +
[[Category:Modeling|Radiosity baking in Blender]]
 
[[Category:Blender|Radiosity baking in Blender]]
 
[[Category:Blender|Radiosity baking in Blender]]

Latest revision as of 01:35, 18 June 2015

Prelude

I tried making it easy for non-blenderheads to use this guide too but a bit of know how of blender is good (look at [1] if you need something to get you started). The method described here was developed and tested with Blender 2.37. Help the community by improving upon this if you find anything incorrect or missing.

Our goal

There is no such thing as the ambient lighting most 3D applications and games use, period. An exposed part of the model will receive more ambient light than parts hidden deep beneath pipes and plates. Since we can't simulate this in real-time (at the moment, at least) putting this information in the texture is the way to go. How, you ask? One method is guessing and painting by hand, a very time consuming method which is also likely to render less than stunning results.

Compare the following two pictures:

radio1.jpg


Even though two slightly different meshes were used it should illustrate the difference, clearly the lighting on the latter picture looks more natural.

radio2.jpg

Our weapon of choice for achieving the desired result is, as the title of the article ever so subtly suggests, radiosity [2]. Using radiosity no manual labour will be required as the computer will calculate the ambient intensities for us. In the end, this should slightly alleviate the texturing process and make for promising results.

A step by step guide

As I mentioned above our goal is to calculate some kind of ambient light dependent on the geometry, which we'll use radiosity for. If you don't know what radiosity is, please look it up before proceeding. All right! Just follow these steps:

  1. Load your UV-mapped object into Blender and put it on layer 1. Make sure it is UV-mapped! Also get rid of any lamps lingering in the scene.
    1. Select your model and in edit mode (press TAB do switch between edit and object modes) remove all duplicate vertices. You do this by selecting all vertices (A) and pressing W->Remove Doubles.
    2. Add an icosphere with its center roughly in the middle of your model (SPACE->Add->Mesh->Icosphere). This will be our ambient light source. Higher subdivision yields better results (you need a higher value for a mesh with many polygons, play around!) but longer calculation times, 4 should be sufficient.
    3. Scale up (S) the icosphere to encompass your entire model.
    4. In edit mode select all the faces (A) and flip the normals (W,9). In edit mode, enable normal drawing (done in the editing context, F9) and make sure they're really pointing inward the sphere. (Note that you must be in edit mode to see or enable the drawing of normals.)
    5. Go to the material buttons (F5) and add a new material to the sphere. Choose the desired light color (white, normally) and give the material some emission, you have to experiment with the emit value but 0.02 should be a good starting point.
  2. You're now ready to start calculating the radiosity. But before you start you might want to subdivide your mesh a few times, to get better results. Do it, say, twice (W,1 and repeat).
    1. Go to the shading context (F5) and then the radiosity buttons. Select both the meshes and click the Collect meshes-button. Switch from Solid to Gourad.
    2. i IMPORTANT: Set MaxEl (not ElMax!) to 1. This will ensure that Blender doesn't alter the mesh in any way.

      radio_panel.jpg

    3. Hit [Go] and lean back. Press ESC when you're happy with what you see or wait until it finishes. It shouldn't be all black, if it is something went wrong.
    4. This is optional but if the resulting mesh looks a little spotty or have artifacts you might want to perform Face filter or Element filter, or both.
    5. Save the radiosity information in a new mesh by pressing Add new meshes. Move it to layer 2 (M,2).
    6. Click Free Radio Data.
  3. Now it's time for a little cleaning up before we can bake the radiosity information to a texture. Remove the icosphere from the newly created mesh with the radiosity information. If you're not comfortable with blender, here's how you do it:
    1. Go to layer 2 (2). Select the mesh and enter edit mode (TAB). Remove double vertices with W->Remove Doubles. Hover the sphere with the mouse cursor and press L to select it then delete it using X->Vertices.
    2. Now, since using the radio tool erases all UV-information from the baked mesh we'll somehow need to transfer the vertex color information from the baked mesh to our original mesh. After trying various methods for doing this, none of which worked, I hacked together a small little script (see #Script) in python to do it.
      Load it, change the mesh names at the top of the file, run it and voila! For the blender impaired here's what you do:
    3. Press Shift+F11 to bring up the text editor, load the script from the menu or paste it and then press Alt+P to run it.
      Your original, UV-mapped, mesh should now have all the shading information stored safely in the color of each vertex. You should be able to verify this if you set your viewport shading mode to Shaded (make sure VCol Light is enabled for your material).
  4. The final step is to bake the vertex color information to texture using your favorite texture baking script.
    Enable VCol Paint and Shadeless.
    Run Texture baker (found under Scripts->UV and included with Blender). If it doesn't work the first time make sure your mesh is indeed on layer 1 and try again.

That's it!

You can do even more

Using the same technique you can do even more nifty stuff, such as baking glowmaps:

radio3.jpg


Common troubles

Problem: After calculating the radiosity and clicking Add new meshes the resulting mesh is split into several parts.
Solution: I don't know why this happens but fixing it is easy. Select all of the parts and join them (Alt+J) then remove doubles in edit mode (W,5). Someone on cgtalk suggested it might be caused by bad normals but I haven't been able to verify or reject this theory.

Problem: Man, it doesn't look pretty! It's spotty and ugly looking. Face and Element Filter doesn't do much good, either.
Solution: The face ratio between your model and the light source isn't good. Either subdivide the sphere more or do fewer subdivisions on the model.

Problem: The Texture Baker doesn't render anything or the wrong things. What's up?
Solution: The version of the Texture Baker currently bundled with blender (Blender 2.37a -> 0.2.6) is out of date and you can get the newest version of the script from the "Texture baker" homepage in the #Links 0.2.8 2005/7/20. See also the bug report here.

Problem: With MaxEl set to 1, simple models such as cubes don't look good at all.
Solution: Enter edit mode, select all vertices, press W key, and choose subdivide. The resulting radiosity calculation will run for longer and provide a more realistic solution.

Script

Just save this link as vccopy.py vccopy.py

(If it works better for you you can try using this link: vccopy.py)

HowTo:Radiosity_baking_in_Blender/vccopy.py - The clutter you see on this page is intended. See the source by editing the page.

Links