Feature Request: Bake lightmaps

The interface, modeling, 3d editing tools, import/export, feature requests, etc

Moderators: jesterKing, stiv

Post Reply
RipSting
Posts: 5
Joined: Wed Nov 27, 2002 1:58 am
Location: Oregon, USA
Contact:

Feature Request: Bake lightmaps

Post by RipSting »

I've recently been exporting my models from Blender into Maya so that I can bake lighting to textures- only to then apply those textures on my objects back in Blender. Doing this isn't only great for the game engine, but great for speeding up long animations with multiple lights that must be re-calculated at each frame.

Let me make myself clear. This is NOT converting radiosity into textures, this is about converting high-quality render-time lighting (along with any materials and texture that are already applied to an object) into an image that can be UV-mapped.

The prerequisites for baking are simiple for the end user:
1) Apply UV-coordinates to each object you want to bake
2) Set a texture map size to bake to (1 image file is generated for each object, unless "bake to one map" is selected)
3) Bake to texture map & apply to object

Obviously, different sized objects will require different map sizes, so this procedure will need to be ran more than once.

How it works:
1)Buffered shadowmaps are calculated
2) For each face...
2a) An orthogonal camera is aligned to the current face, and its resolution set based on the amount of area its UV coordinates take up multiplied by its texturemap size.
2b) Raytraced lighting and texturemaps are calculated
2c) The face is rendered and the pixels are transformed to fit the correct UV-coordinates.
2d) the outermost pixels "spill" a user-defined number of pixels outwards to fill seams (as long as those pixels don't spill into another face's UV-coordinates)

Note that lighting is calculated on ALL visible objects (can be controlled through layers), but only applied to selected objects. Each face is rendered individually with no other objects or faces rendered.


Example GUI:
This demonstrates all the user-defined functionality that would need to exist. If tied in correctly, most of these options could use their counterparts in the renderbuttons window.

Code: Select all

##########################################################
#GUI Created using RipSting's Blender-Python GUI designer#
#Download at Http://oregonstate.edu/~dennisa/Blender/BPG/#
##########################################################

import Blender
from Blender.BGL import *
from Blender.Draw import *
from Blender.Noise import *

mnuBakeTo = Create(1)
tglShadows = Create(0)
tglReflection = Create(0)
txtPrefix = Create('')
sldResX = Create(512)
sldResY = Create(512)
mnuFormat = Create(1)
tglOneMap = Create(0)
mnuDepth = Create(1)
sldFill = Create(1)

def draw():
	global mnuBakeTo, tglShadows, tglReflection, txtPrefix, sldResX, sldResY, mnuFormat, tglOneMap, mnuDepth, sldFill

	glClearColor(0.753, 0.753, 0.753, 0.0)
	glClear(GL_COLOR_BUFFER_BIT)

	txtPrefix = String('Prefix:', 1, 16, 408, 255, 23, txtPrefix.val, 512, 'Prefix for image name')

	tglShadows = Toggle('Bake Shadows', 2, 160, 488, 111, 23, tglShadows.val, 'Enable/disable shadow rendering')
	tglReflection = Toggle('Use Face Normals', 3, 160, 464, 111, 23, tglReflection.val, 'Only calculate light falling on the face\'s normal')
	tglOneMap = Toggle('Bake to One Map', 4, 160, 440, 111, 23, tglOneMap.val, 'Combine multiple objects UVs into one texture map')

	mnuBakeTo = Menu('Bake To%t|Texture Map %x1|Vertex Colors %x2', 5, 16, 480, 127, 31, mnuBakeTo.val, '')
	mnuFormat = Menu('File Format%t|Jpeg %x1|Targa %x2|PNG %x3|Bitmap %x4', 6, 16, 288, 159, 23, mnuFormat.val, 'File format to render image-based textures')
	mnuDepth = Menu('Color Depth%t|BW %x1|RGB %x2|RGBA %x3', 7, 176, 288, 95, 23, mnuDepth.val, '')


	sldResX = Slider('X Resolution:', 8, 16, 376, 255, 23, sldResX.val, 2, 1024, 0, '')
	sldResY = Slider('Y Resolution:', 9, 16, 352, 255, 23, sldResY.val, 2, 1024, 0, '')
	sldFill = Slider('Fill Texture Seams', 10, 16, 320, 255, 23, sldFill.val, 0, 5, 0, 'The number of pixels to overspill')

def event(evt, val):
	if (evt== QKEY and not val): Exit()
def bevent(evt):
	if evt == 5: #mnuBakeTo
		if mnuBakeTo.val == 1: #First Item
			InsertCodeHere = 1
		elif mnuBakeTo.val == 2: #Second Item
			InsertCodeHere = 1
		elif mnuBakeTo.val == 3: #Third Item
			InsertCodeHere = 1

	elif evt == 6: #mnuFormat
		if mnuFormat.val == 1: #First Item
			InsertCodeHere = 1
		elif mnuFormat.val == 2: #Second Item
			InsertCodeHere = 1
		elif mnuFormat.val == 3: #Third Item
			InsertCodeHere = 1

	elif evt == 7: #mnuDepth
		if mnuDepth.val == 1: #First Item
			InsertCodeHere = 1
		elif mnuDepth.val == 2: #Second Item
			InsertCodeHere = 1
		elif mnuDepth.val == 3: #Third Item
			InsertCodeHere = 1


	Blender.Redraw()

Register(draw, event, bevent)

A feature of this importance is already included in almost every other mainstream animation package. Creating this would be incredibly valuable to the community, and would boost blender's reputation as a credible self-contained game engine.

joeri
Posts: 96
Joined: Fri Jan 10, 2003 6:41 pm
Contact:

Post by joeri »

Nice work.
I like the button framework. Very helpfull.

If implemented I'd like to add the importance of moving objects and their shadows.
For games, multi layer texture seems to be needed to add the moving objects shadow.
For rendering this is an issue to. The baked shadow could 'sit' in it's own texture channel, so that the user can alter density and other settings. But moving objects should not be in the baked shadows (preferable not selected by hand, maybe by layer) and give correct shadows on render time.

RipSting
Posts: 5
Joined: Wed Nov 27, 2002 1:58 am
Location: Oregon, USA
Contact:

Post by RipSting »

joeri wrote: If implemented I'd like to add the importance of moving objects and their shadows.
For games, multi layer texture seems to be needed to add the moving objects shadow.
I'm not sure how moving objects/shadows would work using this method. In my opinion, they would still need to be lighted per-frame. The advantage is you wouldn't have to re-calculatelighting for EVERY object. This technique is mainly used for environments and architecture and, like radiosity, is used to cut down on render time for non-animated objects.

If the user wants multiple layers of UV textures for animations, they can simply run the process more than once on each object. Which reminds me- *there should be another toggle button that would enable/disable rendering textures to the output file.

joeri
Posts: 96
Joined: Fri Jan 10, 2003 6:41 pm
Contact:

Post by joeri »

Modern architectual visualizations also have moving objects, like cars and walking people. Best to let a developer come up with a smart solution to blend the shadows of moving objects into the baked shadows.

I did something like this years ago.
Renderd a topview of a city with to many spot lights (streetlights all with there own shadow) Then used that rendering as a texturemap for the floor. Then turned the shadows of all the streetlights off and gave moving objects a 'shadow only' light parented to the object.
If this could be automated somehow then big scenes could get much faster.

Post Reply