Links
Back
Introduction
Environment Creation
Shader Development
Introduction
Galactic Bowling is the result of a collaboration between Perpetual FX, Tangrin, and other indy game developers and freelancers. Tangrin.com’s responsibilities involved:
- Creation and coordination of environment art in an international team
- GUI design
- Improving and integrating shader support and effects, including:
- Higher level shader support
- Post effects, featuring bloom, blur, color correction
- Cartoon styled lighting models, featuring multiple dynamic lights, reflection, and environment cube and spherical mapping
With this article, we want to provide you with some insight in the development process of Galactic Bowling. We specifically concentrate on the work done by Tangrin during development. This article can also be viewed as an introduction of the steps involved in creating 3D environment art for games.
Environment Creation
Environment creation for Galactic Bowling can roughly be divided in the following steps:
- Concept art creation
- Creation of a rough gameplay version
- Modeling a detailed version
- Level unwrapping
- High resolution texturing
- Lighting
- Low resolution texture baking
- Collision Geometry creation
- Particle FX creation, scripting
- Final in-game result
Environment Concept Art
Nearly all environment concept art on Galactic Bowling was created by Pavel Cucka. Pavel Cucka teamed up on the Galactic Bowling project as a concept artist, he is specialized in environment concept art and matte painting. Pavel uses a combination of real life photo's, photoshop, and his trusty Wacom tablet to create concept art. During the concept stage we create and review a number of sketches, up to a point where we are happy with the quality and mood of an environment piece. The image below shows the underwater planet concept art. We will use the underwater planet throughout this article to illustrate the environment creation workflow.
Sample concept art for the Underwater planet alley
Rough gameplay version
The next stage of map creation involves setting up a basic map to prove the gameplay on the map is a fun and enjoyable experience. China-based studio SunupCG helped us by creating early versions maps. This allowed us to work in parallel, while SunupCG was developing early gameplay maps in China, another team based in the USA and Europe would polish maps to reach a consistent look between all levels.
Modeling a detailed version
When a map was gameplay-approved, we started from scratch, creating a higher detail map. High detail maps range from somewhere between 50.000 and 150.000 triangles, depending on the level of complexity. In scenes with many natural elements or details, we create even higher resolution meshes with millions of polygons, this information is baked to normal maps. By baking the high detail to normal maps, we keep render and subsequent baking times low, giving us room to do quick adjustments to the look of the environments. One of the most important aspects of creating an environment for games is smart triangles distribution. Use many triangles in places that are near the player, and remove, or reduce polygon count in places the player will not be able to reach, or views from afar. For example, if you are certain the player will not see the back of a mountain, there is no point in placing polygons in that area. Also object that are viewed from afar are a good place to start optimizing and reducing the polygon count. The image below shows the landing zone of the underwater planet.
Render of Underwater planet model
Level unwrapping
Another important part in environment development, or gameplay development in general, is efficient use of texture space. With Galactic Bowling, we faced some challenges. We use the Vicious Engine V1 for Galactic Bowling. The key strengths of the vicious engine are the support for a very solid editor, easy integration with popular 3D development tools, and the power to publish to multiple platforms, like Wii, Gamecube, PSP, Xbox/360, and PS2/3. The key weaknesses of the engine are the limited support for lightmaps, quality lighting, and multiple texture channels per mesh. With these limitations, it was not possible for us to create a high quality lighting solution for our game by using the capabilities of the engine. We solved this by baking the lighting and diffuse maps in the same textures with a high quality renderer. One of the consequences of this approach is that every object in the world needs an unique unwrap. Without unique uv coordinates, overlapping parts in a light map will result in artifacts during baking, because the renderer is not capable of deciding what piece of geometry in a shared texture space has priority. The image below shows a sample unwrap on underwater planet. When unwrapping, the goal is to get the white and black shapes as square as possible on the mesh, with the least distortion possible.
Viewport screenshot of Underwater planet unwrapped
High resolution texturing
After creating a clean unwrap, we start creating diffuse textures. A great source for textures is CGTextures. CGTextures provides categorized, high resolution textures, free for commercial use. We used CGTextures for an incredible amount of our texture work. In the rare case we needed more specific textures, we would go out, and photograph. Being in an international team means you have access to texture material from all across the globe. We have members in Europe, USA, and China who working on the creation of Galactic Bowling. During the texture stage, it is important not to worry too much about matching the right hues early on. Try to get the textures crisp, detailed, good contrast, and create balance between high frequency and low frequency parts of textures. When a texture has too much high frequency detailing, it will start to look crowded. If there is too little detail, the scene will feel empty, and the low detailed polygons will start to show through. During initial texturing, hues and brightness are less important, the lighting of the scene will influence them greatly. Because of the strong lighting influence, we still tweak texture hues and brightness during the lighting stage.

Viewport screenshot of Underwater planet unwrapped
Lighting
After creating textures and setting up materials, we start defining a lighting scheme for the map. Even though lighting is possibly the main contributor to a scenes mood, proper lighting is often an underestimated process.
When lighting, you often have to make many testrenders to get the look just right. Testrenders can take a lot of time too, depending on the complexity of the scene and light setup. Because of this, it is smart to create testrenders on a separate machine, or render farm. This way, multiple light setups can be rendered at once, and picking the right version becomes a much easier and faster process.
It is important to try and match the environment concept art lighting, because the mood of environment art is often created by shapes and lighting. The lighting scheme contributes to the unique look to a high degree. Good examples are the two snow/ice maps in Galactic Bowling, even though both are in a cold, snowy environment, they have completely different lighting schemes. We always setup lighting first by using a neutral, gray material on all meshes. Only once we feel that we have balanced lighting across the entire scene on neutral gray, we start integrating the materials and textures created in the texturing stage. With this approach you are sure that your lighting is correct, and tweaking only has to be done on materials and textures to get a balanced look. This approach also lends itself well to people working in parallel on texturing and lighting.

Lighting comparison between two snow maps, different light schemes generate a completely different setting
Low resolution texture baking
One of the final stages in our 3D modeling tool involves baking all high resolution textures to lower resolution, optimized sheets. All modern 3D modeling tools support the baking of render passes to textures. By baking all lighting and color information, we are able to get quality lighting in a somewhat aged engine, without affecting performance too much. After the baking is done, we set up vicious materials, and export the level to the vicious editor.

Final viewport screenshot of the under water planet scene, with baked low resolution textures.
Collision Geometry creation
After all art is created, we start working on the collision surfaces for the map. Collision surfaces are used to determine surface types and are used by the physics engine to get proper collision response. The surface types are used by the game programmers to determine gameplay and logic in-game. For example, in the image below, the yellow surfaces indicate a ball that has gone out of bound. The green surface indicates a ball has landed in the gutter. The brown surface indicates that a bowling ball has entered the collector, and is ready for reset. Care must be taken when creating collision surfaces, because collision calculations are computationally expensive.
Because of this, we always try to reduce the geometry on the collision meshes as much as possible. In the screenshot below you can see this effect at the edges of the map, the rocks have been removed, because the player will not be able to hit those surfaces. Care must be taken however, too little detail on the collision mesh, and the gameplay will feel disconnected from the graphical representation. In even worse scenarios, the ball will be thrown in places where there is no collision mesh.

Collision of the underwater planet, different colors indicate different collision surfaces, with different collision response
Editor integration
The final stage of development involves importing the level from our 3D development tool to the Vicious engine. After importing the level, we configure the materials, and start the final detailing. Artists place particle systems to enhance the look of the level. Level designers place dynamic environment lights that light our characters, and bowling balls. The programmers integrate gameplay logic and AI to get the level playable. When the level is in the editor, we still go through a couple of iterations to perfect the gameplay, and fix bugs.

Editor viewport screenshot with all particle systems and effects integrated
Final result
After all that work, we get something like the image shown below. Don't forget to click the image to watch a short movie showing the level!

And Finally, an in-game screenshot don't forget to click to view a short movie!
Shader Development
At a later stage during development, our team got access to the source code of the Vicious Engine. This allowed us to extend it with some extra visual elements, such as PostFX and dynamic lighting. One of the first steps was upgrading the engine to support more complex shaders. This included rerouting parts of the graphics pipeline to support more complex effects. We used Render Monkey to develop all shaders. Render Monkey is an easy-to-use shader development tool, that allows us to develop and test all shaders, before we integrate anything in the engine.
Bloom - the easy way
Bloom is probably one of the most used effects in games of recent years. Bloom is actually an easy to create effect:
- Render the scene to a render target, place result in TEXTURE1.
- Render a screen-space full screen quad, with TEXTURE1 on it. Render at 1/2, or 1/4 of the resolution, while rendering, only render pixels above a certain threshold, all other pixels are black. Place result in TEXTURE2.
- Blur TEXTURE2. There are different ways to blur a texture. A common approach is to apply a discrete blur to the image in two passes, a horizontal pass, and a vertical pass. This reduces the potential bottleneck of the quadratic computational growth of larger 2D kernels to a linear growth of 2 1D kernels.
- Mix TEXTURE1 and TEXTURE2. This can be done in different ways. We simply mix the two together by adding the pixels, but allowing our artists to change the strength of both images. For example, it could be mixed with 0.8*TEXTURE1 + 0.5*TEXTURE2.
There are different approaches to bloom, our approach is one of the easiest to implement. More advanced blooms can use HDR graphics pipelines, and depth buffers to create a more photoreal look. The image below shows the result of using bloom. It has exaggerated
bloom settings to illustrate the effect. The effect can clearly be seen around the edges of the rock, and the lights. Bloom helps to create a softer look, but it should be used with care. The bloom will distract, or confuse the player if it is too strong and makes the scene less readable.
Bloom comparison. Top image: no bloom, Bottom image:bloom