nib's Mapper Resource Center
     

Creating Lightmapped Terrain with q3map2

by nib


This is a very basic introduction to creating lightmapped terrain. I want to start by making one thing very clear: I am not an expert at lighting and I do not understand it all. I'm still learning. The reason I decided to do this tutorial is beacuse I spent many days bothering ydnar trying to get my terrain converted from vertex lit to lightmap lit. I figured I'd put this up to help other folks that are just starting to learn about lightmapped terrain and to alleviate some of the "newbie" questions ydnar is hit with every day. Ydnar deserves more credit than I do, every last thing here I've learned from talking with him. That said, ANY mistakes or errors are mine. Most of this is being done from memory of various chats and other reading I have done. I could very well have some mistakes in here. I'll correct them as they are found, but again, the mistakes are mine, not ydnar's. Ok, on to the tutorial.

The new q3map2 line has many, many changes it in. One of the best changes is the ability to use a lightmap on terrain. What does that mean? Well, basically it gives you two things. First, it compiles faster than the older vertex lit terrain. And second, it allows for much better shadowing and lighting effects than before.

This tutorial is based on q3map2 2.3 a21. The q3map compiler changes rapidly and new features are added almost weekly and, as such, this tutorial can get outdate very quickly.


Assumptions:

I'm assuming you're not a total newb to mapping, if you are, don't tackle lightmapped terrain just yet. :) I also assume you know how to create terrain and create a working map. You should be able to create, change and compile a working map before starting this tutorial. Also, if your map uses fogvars in your skyshader (i.e. if you have sky based fog), lightmapped terrain does not work. According to ydnar, there is a bug in the Wolf rendering engine that causes weird things to happen.

A Quick Side Note
Just what is the difference between "vertex" lighting and "lightmap" lighting? Well here is a very basic and over-simplified explaination. Vertex lighting is the old, standard way terrain has been lit. What happens is that each vertex of your terrain is looked at and the value of the light on that vertex is taken. This is done for every vertex on your terrain. Then, for each piece (triangle) of your terrain, the light values of the vertices are blended together and that creates the lighting for that piece of terrain. This worked, but created some problems. For example, if one vertex was hidden or inside of a brush, it wouldn't get a light value. This could sometimes cause some really bad shadowing effects that looked horrible.
Lightmapped terrain is different. What it does is break the surface area of the terrain up into predefined "chunks", which are lightmaps. These chunks can vary in size depending on how fine you want your shadows. The light value assigned to each lightmap is determined by taking the average lighting over that lightmaps size and applying it to the terrain. This is the style of lighting that has always been used on brushes.
Compare the Difference
Small Image of terrain Small Image of terrain
Vertex LitLightmapped

Step 1:

The first thing you need to do is upgrade to q3map2. As of the writting of this tutorial the q3map 1.x series is the compiler released with gtk. There are a few things you have to do to get the q3map2 series to work correctly. If you've already got q3map2 installed and working correctly, skip down to step 2.

First, download q3map2. Most recent version can be found here.
Next, extract that zip to the c:\Program Files\Return to Castle Wolfenstein\Radiant directory (or where ever your copy of Wolf is installed).
Then, I highly recommend you use a front end compiler. This allows you to select which compiler to use and which compile options to use very easily. I recommend q3map2build, which can be found here. Download that, extract it to your radiant directory and then run it. (note: if you put your q3map2.exe in a directory other than the Wolf\Radiant directory, be sure to use the -fs_basepath switch. If you're using q3map2build it doesn't matter where you put q3map2 as it will handle that switch for you)
The first time you run q3map2build, you'll need to click on the Directory Options button to Configure it. Your settings should be as follows:

Directory Options
Game Executable Location:Path to Wolfmp.exe
Q3Map2.exe Location:C:\Program Files\Return To Castle Wolfenstein\Radiant\q3map2_2.3.0-a20\q3map2.exe (or wherever you installed it)
Game:Type in "wolf"

Ok, now that you've done that, you need to update your main\scripts\common.shader file. Open that file and locate the common/terrain and common/terrain2 shaders. Add the line "q3map_terrain" to the top of both shaders. It should look like this:

textures/common/terrain
{
	q3map_terrain

	surfaceparm grasssteps
	surfaceparm nodraw
	surfaceparm nomarks
    surfaceparm nolightmap
}

Ok, only a couple more small things to take care of before we're ready to move on. The next thing we need to do is copy the two .shader files that were included with the q3map zip file to your main\scripts directory. Look in the directory where you extracted the q3map zip file, go to the "extras" subdirectory and copy q3map.shader and cel.shader to your wolf main\scripts directory. After doing that, open the main\scripts\shaderlist.txt file and add q3map and cell to the end of that file.

That's it! You've now set up your system to compile maps using q3map2. Now, if you compile using gtkRadiant it will still use the old q3map 1.x series. You'll want to compile your maps by using the Q3map2Build program you installed above. Personally, I find this much better than using gtk since a) you can close gtk and free up memory and b) it allows yout to pause the compile after each stage to check the compiler output.

At this point you may want to load up a sample map and do a quick compile to test it and make sure everything is working. If something isn't working, go back through everthing above and make sure you didn't miss a step. There are a lot of little things you must do and if you miss even one, your terrain will likely not compile correctly.

One last thing, everything I outlined above is explained in the readme_previous.txt file that comes with q3map2 (except the q3map2build stuff).

Ok, wow. That sure was a lot of stuff to do! No worries though, you still have plenty more!! :) Just kidding, we've really only got one more step.

Step 2:

Ok, on to lightmapped terrain. Everything you need to do to get lightmapped terrain to work is handled in the terrain shaders. Your old, vertex lit terrain shader should look something like this:

textures/bunker_terrain_2/terrain_0
{
	surfaceparm nolightmap
	q3map_novertexshadows
	q3map_forcesunlight
	{
		map textures/stone/mxsnow3.jpg
		rgbGen vertex
		tcmod scale 0.05 0.05
	}
}

And, for your blended terrain textures:

textures/bunker_terrain_2/terrain_0to1
{
	surfaceparm nolightmap
	q3map_novertexshadows
	q3map_forcesunlight
	{
		map textures/stone/mxsnow3.jpg
		rgbGen vertex
		alphaGen vertex
		tcmod scale 0.05 0.05
	}
	{
		map textures/snow/s_grass_ml03a_s.jpg
		rgbGen vertex
		alphaGen vertex
		tcmod scale 0.05 0.05
		blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
	}
}


So, what do we do? Well, the first thing you want to create is called a "base" shader. This basically allows you to set the common settings in a single shader, then include that in each shader. This For example, in the sample above, notice how both shaders include "surfaceparm nolightmap", "q3map_novertexshadows", and "q3map_forcesunlight". You can, with a base shader, have all of those defined in the base shader and they will automatically be added to each shader. So, lets create our lightmapped terrain "base" shader.

textures/YourMapShaderNameHere/baseterrain
{

	q3map_lightmapsampleoffset 8.0
	q3map_lightmapaxis z
	q3map_tcGen ivector ( 512 0 0 ) ( 0 512 0 )
}

So, all of those compiler directives will be used for each terrain shader you create. A real quick explanation q3map_tcGen iVector is warranted (the other ones are less important). q3map_tcGen ivector is used to determine how often your texture repeats itself. So, in the example above, the texture would repeat itself every 512 units in the X and Y directions. This means that if you want your textures were 256x256 units, using the above q3map_tcGen iVector would stretch the texture out to be 512 x 512

Alright, so you've got your base terrain defined, next we need to create your regular terrain shader. This is pretty straight forward, here is what it should look like:

textures/YourMapShaderNameHere/terrain_0
{
	q3map_baseshader textures/YourMapShaderNameHere/baseterrain
	q3map_lightimage textures/snow/s_dirt_m03i_2.jpg
	
	{
		map textures/snow/s_dirt_m03i_2.jpg
		rgbGen identity
	}
	{
		map $lightmap
		blendFunc GL_DST_COLOR GL_ZERO
		tcGen lightmap
		rgbGen identity
	}
}

The first line simply imports the commands from your base shader and adds them to this terrain_0 shader. The next line, q3map_lightimage, is used to determine what color light to use when your light "bounces" off of that surface (this is only calculated if you use the -bounce X option during the light compile). So, in this example, when the compiler is determining what color of reflective light to use, it will take the average color of the s_dirt_m03i_2.jpg image and use that for the light's color. You can actually use any image you want to create whatever color you need.

I also want to show you a blended terrain texture. Here that is:

textures/YourMapShaderNameHere/terrain_0to1
{

	q3map_baseshader textures/YourMapShaderNameHere/baseterrain
	q3map_lightimage textures/snow/s_dirt_m03i_2.jpg

		{
			map textures/snow/s_dirt_m03i_2.jpg
			rgbGen identity
		}
		{
			map textures/stone/mxsnow3.jpg
			blendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA
			rgbGen identity
			alphaGen vertex
		}
		{
			map $lightmap
			blendFunc GL_DST_COLOR GL_ZERO
			tcGen lightmap
			rgbGen identity
		}
}

The only thing to really note here is the q3map_lightimage line. Remember I said that it is used to determine the color of reflected light. Well, what should you do when you have blended textures like this? Well, you can do a couple things. First, you could just pick one of the images to use like I did above. Or, if you want to go through the trouble, you could created your own image that is a blended image of your two textures.

Step 3:

Ok, on to the compile. Compiling the terrain is really no different than compiling vertex lit terrain. The recommended light compile options to use for a production map are: -light -fast -fastgrid -patchshadows -filter -super 2 -bounce 2

Now, there are some situations where -filter will cause weird shadow blending so if you have some strange artifacts, just remove that options. Also, when testing, you can do a faster compile by dropping the -super and -bounce switches.

Step 4:

Couple of miscellaneous points.

There are some new keys you can use with your terrain. "shader" has been replaced with "_shader", "layers" is now "_layers" and "alphamap" is now "_indexmap" (all old keys are still valid). Also, the "terrain" key is no longer necessary. Q3map simply looks for the common/terrain texture.

Another point is you can easily have multiple terrains in your map. Simply make each group of terrain its own func_group with its own key values and you're all set.

One last thing, you aren't required to only use brushes either. You can mix and match patches along with your standard terrain brushes. This means, if you want to have a really smooth hole in the ground, you could, for example, delete the terrain brushes, replace them with a patch mesh, deform it how you want, then add that to the group and texture it with the common/terrain texture. Cool huh?

Conclusion:

There you have it. That should be enough information to get you started. Keep in mind, all this tutorial did was touch on the bare minimum you need to do to get lightmapped terrain working. There are many more options and features you can explore. If you want to do addition reading and learn more, there are a few places to go:

  • First and foremost, read the q3map manual.
  • Also, you may want to check out the Quake3World Forums, there are two q3map threads at the top of the editing form that are packed with good information and advice. There is a lot to read, but its worth it.
  • And finally, you can always check out the #q3map channel at irc.enterthegame.com, there are plenty of folks there that are ready to help.

Files:

None.