# POV-Ray lightmapping helper

Version 0.1 - April 2011

Jaime Vives Piqueres - jaime@ignorancia.org - http://www.ignorancia.org

## Description

This Java tool helps preparing a basic structure of POV-Ray files and a batch script, which will allow to bake lightmaps from a POV-Ray scene. The scene, at least the part of it to be baked, has to be composed out of uv-mapped meshes, and converted to POV-Ray format using Poseray.

## Introduction

At first, this was going to be just a little tutorial illustrating a method I developed to generate lightmaps with POV-Ray, using the new `mesh_camera` feature in the latest version. I started by doing all the work manually, but as it was rather tedious with more than a few meshes, I created a PHP_CLI script which automated the process by creating the needed include files and a batch script.

I used PHP just because I'm accustomed to use it to write this kind of file I/O scripts, but it seemed an odd choice for a multiplatform distribution. After a little quest, I decided my best option was to use Java instead. A friend recommended Netbeans, so I installed it and started development... it seemed so easy to learn, that I decided to move the app from the command-line to a simple GUI, and in the process I've made it a bit more complete and practical (though there is still plenty of room to refine and enhance, or even redesign this tool).

## Requirements

To try the technique with the included test scene, you will need:

- The latest POV-Ray 3.7 RC, of course.
- Java 6 SE (JRE 1.6.0).

Additionally, to try it on your own scene, you will need also:

- A scene composed out of uvmapped meshes, in a format wich Poseray can load.
- PoseRay 3.12.2 (current) to convert it to POV-Ray meshes.

## General Description

A lightmap is an image which captures the effect of the lighting on the surface of a 3D object. The technique usually known as lightmap baking, consists on rendering images of the uv maps with a plain white texture, so the resulting maps can be used back to texture the meshes (this is done usually by just multipliying the lightmaps and the final pigments), making the light sources no longer necessary.

The more obvious applications are virtual reality and games, but it could be useful also just to make faster POV-Ray animations, or to render in minutes multiple views of a scene, or the same shot with different textures, etc...

The main drawback is that we lose color bleeding in radiosity, as the pigments are all white (tough the same procedure can be used to bake textured maps, just by using POV-Ray textures instead plain white pigments). Also, only the meshes on the scene can be baked, but other primitives can be used if they are going to be self-lighted or not visible.

The process I used assumes that our main purpose is to use POV-Ray as a radiosity-baking engine for externally modelled scenes, converted to POV-Ray format with Poseray. It will go as follows:

- Create the mesh-scene on your favorite modeler and export it to a format supported by Poseray.
- Load the exported file into Poseray, and export it to POV-Ray meshes.
- Run the Java tool on the Poseray export to generate the customized include files and batch script needed for the baking process.
- Fill the generated templates for lighting, camera and non-baked objects.
- Render the main scene generated to test the camera and lighting setup using regular rendering.
- When you are satisfied with the lighting, run the generated batch script to bake all the lightmaps.
- Use the generated main scene to test the baked lightmaps, this time without light sources.
- Import the lightmaps and meshes onto you preferred VR application, game engine, etc... or just use them with POV-Ray.

I will explain these steps with more detail later... but first, let's take a look at the contents of the archive.

## ZIP Contents

- ### Application files:

  These are the two files you need to try the technique with your own scene:
  - prepare_baking.jar :
    Java application used to automate the process of extracting the information needed from the Poseray geom file, adjusting the baking options, and writing the files required for the baking process. Copy it to your preferred location for applications.
  - baked_tools.inc :
    This is a common include which will be used by every scene prepared with the above Java application. At the moment contains just one macro, used to load back the lightmaps while mixing them with user-supplied textures. Copy it to your POV-Ray includes directory (or directly to the scene folder, if you don't want to pollute your POV-Ray installation for the moment).

- ### Test scene files:

  In case you don't have any mesh-only scene at hand, but you really want to try the technique, I've provided a test scene you can use. It's a simple room with a chair, modeled and uv-mapped with Wings3D. You can find it on the subdirectory lm_test/, which contains the following files and folders:
  - the obj scene:
    - lm_test.mtl
    - lm_test.obj
  - the geometry file exported by Poseray from the above obj:
    - lm_test_POV_geom.inc
  - the files generated by prepare_baking.jar using the above geometry:
    - lm_test.pov
    - lm_test.properties
    - lm_test_bake_all.sh
    - lm_test_baking_cameras.inc
    - lm_test_baking_control.inc (edited to add custom switches and radiosity)
    - lm_test_POV_mat.inc
    - lm_test_POV_mat-example.inc (version from the above file, edited to customize the materials)
    - lm_test_repair_seams.pov
  - the user-suplied files I created for this scene:
    - lm_test_camera.inc
    - lm_test_lights.inc
    - lm_test_unbaked.inc
  - An extra INI file for POV-Ray, which I used to animate the test scene:
    - lm_test_animation.ini
  - the folder containing pre-baked lightmaps for convenience:
    - lightmaps/

## Getting a first taste

If you still don't know what I'm talking about, let's do a real test, which should do a better job at explaining itself.

Open the lm_test folder with your file manager. First, take look at the lightmaps already baked in the lightmaps/ subfolder (you will need a program capable of displaying EXR files, like IC or hdrview for example). What you are seing are the uv maps of each mesh rendered with the `mesh_camera` feature.

Now, if you just render the file lm_test.pov, the resulting image will show a shot with the test camera, without any lighting: just these pre-baked lightmaps applied back as textures to the meshes. Because they were rendered from the own uv maps of each mesh, they fit perfectly into them, giving the impresion that the scene is lighted.

If you set `use_baking=0` on the file lm_test_baking_control.inc, and render again, you will get the regular render with actual light sources, which was the base for the baking process. You will notice it renders much slower...

If you compare both renders, you shouldn't see much difference, except for some pixelation on the shadows on the first render because the supplied lightmaps are small.

For an example on how these lightmaps can be mixed with regular textures, just rename lm_test_POV_mat-example.inc as lm_test_POV_mat.inc, and render again with `use_baking=2` and `use_fblur=1`.

Also look into lm_test_unbaked.inc to see how I used this user-supplied file to add objects which don't need baking, in this case just the sky sphere.

Now, if you want to know how to use this technique with your own scenes, continue reading to the next section (you can try it with the included test scene: just skip the first step and start with the obj file supplied).

## First step: modeling the scene

Fire up your preferred mesh modeler, and create you scene with the following ideas in mind:

- To save baking time, and to make more efficient uv maps, you only need to create uv maps for the parts that are going to be visible. For example, if you are making a room, and you don't plan an outdoor walk-through, you don't need to uvmap the exterior walls faces.
- Additionally, set all non-uvmapped faces to the same material, so we can later exclude them from baking.
- Be sure that your uv maps do not contain any overlapping zones/charts.
- Be sure that your uv maps have some space between the different zones/charts, as later we will need this space to expand a bit the charts to avoid the problem with the uv seams becoming visible.
- When you're finished, save it into any format that Poseray can manage. If there are objects you don't want to bake, just export them to a separate file, so we can later manage them as "unbaked" objects.

## Converting to POV-Ray with PoseRay

Launch PoseRay and load the obj/3ds/whatever you exported from your modeler. Go to the POV-Ray output tab and select to break the mesh by materials only, then check to only export geometry and materials, and chose the left handed system if you prefer.

Push the Export button and save it to your project folder, then exit Poseray.

## Running the Java application

Next step is to use the Java tool to create a set of files which will allow to automate the baking process. On most systems you will only need to double-click on the file prepare_baking.jar, but in some cases you may need to do some extra work (How to Run a .Jar Java File).

Once launched, the application will show a simple dialog window, asking for a Poseray geometry file: push the Browse button and find your geometry file. The file is then loaded and scanned to obtain the names of the objects and materials contained into it. If any materials are found, the rest of the controls will be enabled, allowing some configuration of the output files:

- Exclude material: drop-down to choose the name of a material to exclude when baking (I use it to exclude objects that I put just to block/bounce/generate radiosity, or faces that are not uv-mapped and which I'm too lazy to remove).
- Lightmaps subfolder: the name of the subdirectory where you want to store the lightmaps. Optionally it will be created if it doesn't exists yet.
- Lightmaps size: the default lightmap resolution (square).
- AA: check to use antialiasing for the rendering of the lightmaps, and set the amount next to it.
- Type of batch script: the type of batch script to generate for mass-baking (.sh or .bat).
- Display images while rendering: check to display the images while rendering the lightmaps.
- POV-Ray executable: the path to the POV-Ray 3.7 executable. Use the Browse button to find it on your system.

All these options can be saved to a PREFIX_NAME.properties file with the Save scene config button (where PREFIX_NAME is the prefix used when exporting from Poseray). Additionally, some of the options wich are going to be useful on future runs, are saved automatically to a .prepare_baking.properties file on the user home folder.

Once you tweaked the configuration at your will, push the Prepare baking button to generate the include files and the script which will allow baking this scene with stand-alone POV-Ray.

If everything goes as expected, the script will generate the following files:

- PREFIX_NAME.pov:
  This is the main file you will be rendering, tough you don't need to edit it as it only calls the required includes (see PREFIX_NAME_baking_control.inc instead).
- PREFIX_NAME_baking_control.inc:
  This is the file that holds all the switches and control variables needed for the setup, testing and baking. Tough you will render the main .pov scene generated, this is the one you will tweak for the baking control. You can also add here the controls for your custom lights and camera to centralize all the setup in one place. It's generated only if it doesn't exists (to avoid overwriting existing changes).
- PREFIX_NAME_POV_mat.inc:
  This is the materials file expected by the scene exported from Poseray, modified to work with two versions of each material: one for the lightmap baking step, that I will call the baking material, and another for the lightmap loading step, which I will call the baked material. The original file will be overwritten without warning if it exists, tough existing maps and pigments will be preserved for use on the baked materials (this only works properly with materials exported from Poseray 3.12, not with the latest beta 3.13, as the format has changed).
- PREFIX_NAME_baking_cameras.inc:
  This file contains the actual baking cameras, one for each mesh within a switch case, to help automating the baking process with a external batch script, and also to allow individual re-generation by using the clock on the command line.
- PREFIX_NAME_camera.inc:
  Placeholder file for the user-supplied camera, which will be used for tests and baked renders. Put here your camera definition(s). It's generated for convenience, only if it doesn't exists (to avoid overwriting already existing code).
- PREFIX_NAME_lights.inc:
  Placeholder file for the user-supplied lighting, which will be used for tests and baking renders. Put here your scene light sources. Note that placing here luminous objects it's not convenient, as they will not be used on baked renders (better place them on the following include). It's generated for convenience, only if it doesn't exists (to avoid overwriting already existing code).
- PREFIX_NAME_unbaked.inc:
  Placeholder file for the user-supplied non-bakeable objects, which will be used for tests and baked renders. Put here any object you want to use on the scene, but which doesn't needs to be baked (for example, objects used to block, bounce or emit radiosty). It's generated for convenience, only if it doesn't exists (to avoid overwriting already existing code).
- PREFIX_NAME_repair_seams.pov:
  This is a tool scene, used by the baking batch script to correct the known (and universal) problem with uv maps seams becoming visible. It offsets some copies of the original exr image to expand a bit the uv charts. For it to work, you need to leave some space between the different charts contained on the uv map.
- PREFIX_NAME_bake_all.sh:
  Main script used to bake all the textures at once. By default, it's generated with the same supplied resolution for all meshes: you are supposed to edit it afterwards to set appropiate resolutions for each mesh map.

## Using the resulting files

So now you have a scene, a set of include files, and a batch file which will allow to:

- Test the lighting of the scene before baking.
- Easily bake the lightmap for each mesh.
- Correct the seams problem on the baked maps.
- Test the baked lightmaps later, using them back into the meshes.

First thing you need is to add a camera to PREFIX_NAME_camera.inc, and some lighting into PREFIX_NAME_lights.inc. You can create the code manually by looking for the coordinates with your modeler, or generate it using PoseRay, or even by exporting them from your modeler if you're lucky (I can do it directly from Wings3D). The provided camera will be used for test and baked renders, while the lights will be used to light the scene being baked.

To test if lighting is correct, edit the file baking_control.inc and verify that `use_baking` is set to 0. Then render the main pov file: you will get a render with all the surfaces set to plain white, so you can see clearly what is going to be baked.

If the lighting is correct, you then use the generated shell script to bake all the meshes. Note it was generated with fixed resolutions for the lightmaps: you should increase/decrease them as needed for each mesh, depending on the size and visibility.

Once all the meshes are baked (something that can take a very long time), set `use_baking=2` to load the lightmaps back and render the scene again, without using any lights. By default you will get the lightmaps multiplied by the existing pigments on the original materials file, or by plain white pigments if it didn't exist.

Now you can test the real target of this demo: edit the materials file and change the parameters for the baked_texture() macro of each material. Look into the test file lm_test/lm_test_POV_mat-example.inc to see some examples.

Alternatively, you can just take the lightmaps and meshes into your preferred VR or game engine, and texture them there... I would be very interested to know about any success on that regard.

## License

I grant to anyone the right to use the Java application, the POV-Ray include files generated from it, and the bundled test scene, for any purpose.

## Source code

The Netbeans project for the application is available upon request, tough it is very uninteresting, as the important part is the output it generates, not how it generates it (apart from the fact that I suck at coding, and this is my first Java application ever).

## Feedback

Please, let me know any problems, comments or suggestions... they are always welcome.

If you develop an alternative baking method, specially if it's a more user-friendly solution, please let me know, so I can put a link on the corresponding page at my web site.

Jaime Vives Piqueres, 2011
jaime@ignorancia.org
http://www.ignorancia.org