Once you have created a scene and populated it with all the mesh instances, light sources, etc. that exist in your game world, you need to carry out a rendering job to create the final lighting data for that scene. This page provides an overview of the concepts and procedures involved in setting up and carrying out a rendering job.
Rendering involves three principal types of objects:
Beast offers you the choice of three very different workflows for rendering your scene. Each of these workflows is reflected by its own kind of rendering job.
You can carry out a straighforward rendering job that simply bakes the lighting data for the scene as you have created it. This type of job terminates automatically when all passes have been rendered for all targets.
To create a simple rendering job, call the ILBCreateJob() function. When you call this function, you need to provide an XML file that configures a variety of settings about the algorithms that will be used in the rendering, the way instances are sampled, etc.
For a detailed reference that contains all available settings, see XML Reference.
You can create a rendering job that launches the standalone eRnsT viewer to give your artists an interactive preview of the lighting in your scene. The job will continue to run until you explicitly destroy it, or until the user closes the eRnsT viewer. As long as the job continues to run, the eRnsT viewer will show the contents of your scene. Your artists will be able to change the lighting in the scene and tweak other Beast configuration parameters. You can retrieve the changes they make in your code, and update your game level accordingly.
For details on how to use the standalone eRnsT viewer, see also Using the eRnsT Viewer.
To create an eRnsT job, call the ILBCreateErnstJob() function. When you call this function, you need to provide an XML file that configures a variety of settings about the global illumination algorithms that will be used in the rendering, the way instances are sampled, etc. For a sample configuration that contains some of the most important settings, see Sample XML Configuration File for Classic Material Rendering. For a detailed reference that contains all available settings, see XML Reference.
Note that some restrictions apply to standalone eRnsT jobs:
You can create a rendering job that integrates the eRnsT real-time rendering engine directly into your own level editor, to give your artists immediate feedback on the changes they make. As the rendering job is carried out, Beastprovides you with progressive updates of rendered data for the targets you have created. You can retrieve the updated data in your code, and use it to update a render view or the textures and lighting data you display in your level editor. See the Maya plug-in for a live workflow example.
During a live eRnsT session, your Beast scene is completely editable. If your designers make a change in the level editor, such as adding or removing a light or object in the level, you can change the light sources and mesh instances contained in your Beast scene to reflect the changes made in the level editor. Beast will automatically determine when the targets in your scene need to be re-baked.
To create a live eRnsT job, call the ILBCreateLiveErnstJob() function. This function does not accept an XML configuration file like the other kinds of rendering jobs. Instead, you can configure the job by calling a set of functions provided by the Beast API:
The type of updates you receive from a live eRnsT job depend on the type of targets you create in the scene:
If you choose to retrieve renderings of the scene from a camera target, you can choose how those renderings should be created by calling the ILBCameraTargetSetRenderMode() function, and passing a value from the ILBCameraRenderModeType enumeration. You can retrieve fully shaded per-pixel renderings (ILB_LEC_CAMERA_PER_PIXEL_LIGHTING); in this case, the texture targets and vertex targets in the scene are not used at all. Alternatively, you can have the eRnsT job calculate lightmaps for the texture targets and vertex targets in the scene, refining them progressively with more details, and create the camera renderings based on those lightmaps (ILB_LEC_CAMERA_LIGHT_MAP_LIGHTING).
The Beast API provides two functions that you can use to control the quality of the rendering.
The first controls the quality using a single parameter, similar to a JPEG quality setting:
ILBSetJobRenderQuality(ILBJobHandle job, float quality);
The other option gives more detailed control over sample quantity and variance:
ILBSetJobRenderSamples(ILBJobHandle job, int minSamples, int maxSamples, float varianceThreshold);
In addition, you can also control physical rendering using the following eRnsT API functions, which provide control over the artistic qualities of the rendering:
ILBSetErnstGIDepth(ILBJobHandle job, int minDepth, int maxDepth); ILBSetErnstGIDiffuseBoost(ILBJobHandle job, float boost); ILBSetErnstGIEmissiveScale(ILBJobHandle job, float scale);
Regardless of the rendering workflow you choose to use, the process of setting up and running a rendering job always involves the same basic steps:
For example, the following code demonstrates how to set up and launch a simple rendering job:
std::string xmlFileName = "../../data/settings.xml"; // 1. Create the job. ILBJobHandle job; ILBCreateJob(bmh, _T("TestJob"), scene, xmlFileName.c_str(), &job); // 2. Create render targets. ILBTargetHandle cameraTarget; ILBCreateCameraTarget(job, _T("cameraTarget"), camera, 640, 480, &cameraTarget); ILBTargetHandle textureTarget; ILBCreateTextureTarget(job, _T("textureTarget"), 512, 512, &textureTarget); // 3. Add the floor instance to the texture target. ILBTargetEntityHandle entity; ILBAddBakeInstance(textureTarget, floorInstance, &entity); // 4. Create a render pass. ILBRenderPassHandle fullShadingPass; ILBCreateFullShadingPass(job, _T("fullShading"), &fullShadingPass); // 5. Add the render pass to the targets. ILBAddPassToTarget(textureTarget, fullShadingPass); ILBAddPassToTarget(cameraTarget, fullShadingPass); // 6. Launch the job. ILBStartJob(job, ILB_SR_KEEP_OPEN, ILB_RD_FORCE_LOCAL); // 7. Monitor the job and get progress updates. ILBBool isRunning = true; ILBBool completed = false; int32 oldProgress = 0; while (isRunning) { ILBWaitJobDone(job, 0xffffffff); ILBIsJobRunning(job, &isRunning); if (isRunning) { ILBBool newProgress; ILBBool newActivity; ILBJobHasNewProgress(job, &newActivity, &newProgress); if (newProgress) { ILBStringHandle taskName; int32 progress; ILBGetJobProgress(job, &taskName, &progress); // Handle progress update. oldProgress = progress; } } } // Handle the result of the job. ILBJobStatus status; ILBGetJobResult(job, &status); if (status != ILB_JS_SUCCESS) { switch(status) { ... } return false; } // 8. Retrieve baked output. ... // 9. Destroy the job. ILBDestroyJob(job);
API functions related to the creation and setup of render jobs are declared in the beastjob.h file.