BAM now has its own rendering engine and can draw all table elements with pixel shader programs. This New Renderer can calculate lights "per pixel", as well as use normal and relief maps to draw objects with more details.
New Renderer requires more powerfull graphics cards. It will not work on some old computers. Also graphics card driver update may be required.
Tables on New Renderer will look little different.
How to enable New Renderer?
Usage of New Renderer is controlled in 2 places: global and "per table".
- global in [Config] -> [Rendering Engine] -> mode:
- Compatibility (default) - If it is selected at game start, BAM will not create structures required for New Renderer. To enable New Renderer, you have to change mode to "Disabled" or "Enabled" and restart game.
- Disabled - New Renderer is disabled for all tables, except for the few tables with "per table" setting set to Enabled.
- Enabled - New Renderer is enabled for all tables, except for the few tables with "per table" setting set to Disabled.
- "per table" is [Table & Lightning] -> New Renderer:
- Disabled - the current table will not use New Renderer, regardless of global setting.
- Global (default) - the current table will use New Renderer, only when global = Enabled.
- Enabled - the current table will use New Renderer, regardless of global setting.
It is simpler than it sounds. Here are examples:
- All tables use standard rendering (default) --- global=Compatibility, "per table"=any.
- only on few tables --- global=Disabled, for few tables: "per table"=Enabled.
- on all tables --- global=Enabled, leave"per table"=Global.
- almost on all tables --- global=Enabled, for few tables: "per table"=Disabled.
Single pixel objects have more params, than just color. Some of them control reflection of lights. In pure FP, you have very limited control over it. You can select between 4 material types: Metal, Wood, Plastic and Rubber. These 4 material types differ only in one param: "shininess".
Here is list of params, that can be set:
- shininess - controls size of reflection on object surface
- color of reflection - in FP, it is always color of light source. This means that all objects have white color. In my "BAM-demo" table, the second "slug" from left has "green" reflection. By changing this color, you not only change color, but also make reflection brighter or darker (less visible).
Now you have control over the params per object.
How to set material params for BAM New Renderer.
- BAM has to identify object. Bad news is that BAM can only recognize texture name. So you can't tell BAM: set params for object Slug-1, but you can tell BAM: set params for object with texture "Slug-diffuse". In FP when you load texture, you give it a name and select this name on object. Remember that name.
- BAM can read script for table. In script you can put comments. The comments are not important for FP, but here you can pass additional information for BAM. Every line interpreted by BAM starts with: '[BAM] ..... (see script in BAM-demo table). BAM search form syntax: !paramName = value. All param names start with exclamation mark. So all important lines look like this: '[BAM] !paramName = value
- To set params, you have to point to texture with command: !texture = textureName. This will do 2 things: all params set after this line will change params for this texture and ...
- ... it will add this texture to list in BAM where you can change params "on the fly". In BAM menu, you can go to [Rendering Engine] -> [DEV options], select texture name. Experiment, manipulate and test what happens when you change values. Whatever you change, will not be stored. All names in that menu are same as param names that you can use in script.
List of params for Specular Lighting:
- !shininess - smaller values will increase "reflection" spot
- !specularColorRed, !specularColorGreen, !specularColorBlue - RGB values of material "specular" param. Normaly the values are between 0.0 and 1.0. It is same as 0 - 255 on bitmap. But you can set values higher than 1.0 and it will work as you expect: bigger value -> more of that color.
- !specularLevel - is multiplier for values !specularColorRed/Green/Blue. It is easier to change one value than 3 when you only want change of brighness.
- !specularBalance - this value is result of error in previous BAM releases. In first New Renderer release as specular color, BAM uses diffuse color (color of texture). When I tried to fix it, many users didn't like increase of light reflections. So this value is used to control it. We have 2 colors: diffuse color (from texture) and specular color. !specularBalance = 0.0 means: "use diffuse color", = 1.0 means: "use specular color". You can also "blend" two colors.
What you can do with that: You can for example set !shininess low (for example = 1.0) and set !specularLevel also low (=0.1) this makes material look more like skin than shiny plastic. Go ahead and experiment.
Some of the params are connected to global values. !specularBalance is same thing as "Specular Color" in [Lighting model], but it controls the param only for one selected texture. Same thing with !specularLevel and "Speclular Level".
BAM-demo.fpt, BAM-demo table
We all want more details on 3D models. Most natural solution is more vertices and more triangles. But it creates more problems than it solves:
- More vertices require more data to store, more processing power to manipulate it.
- It is very easy to have more triangles in model than pixels on screen. In one pixel, you can have a few triangles. GPU will process only one sample from one triangle. You will have to use AA (Super Sampling) to get rid of aliasing artifacts.
- You can use a few models with LOD, but it is always visible to viewer.
To avoid these problems we have "normal maps". Instead of tens (or hundreds) of triangles, we have one big triangle with additional texture. This texture has information about normal vector from model surface. It allows reproduction of many model details, saves memory and reduces aliasing artifacts.
What is stored in normal maps.
Normal vector. It is a normalized vector (lenght of vectore = 1.0). Normal vector is the set of 3 coords (x,y,z) all in range <-1,1>. BAM needs only 2 values: X and Y. Value of Z can be calculated based on X and Y.
I will not explain how to generate normal maps. If someone else wants to fill this "gap", I will happily add it to this manual.
So BAM can use additional textures. I hope you have noticed, that in one texture we can store two more values. We have "free" BLUE and ALPHA value. BAM use BLUE value as "Specular Level" modifier and ALPHA as "Height Map". To clarify, this additional texture for every pixel in "ordinary" texture has information about:
- Normal vector stored in RED and GREEN channel;
- Specular Level modifier in BLUE channel. This value is interpreted as value in range <0,1>.
!specularLevel described in previous lesson is multipled by this value. This way you can make some parts of model "shine". Default value is 1.0 (=255).
- Height Map used to create effect visible on third video in Example what can New Renderer. Default value is 1.0 (=255).
Preparation of Normal Map for BAM
I assume, that you already have model with additional textures: normal, height or specular map. Now you need to combine it in one texture. For this task I created a tool: "tc.exe". You can find it in the download section or from this link. It is a command line tool (no gui). It processes "input file" with simple "commands". Here is the list of commands:
- o - define size of output texture. It gets two params: width and height.
- i - load source texture, copy selected chanels in source texture to selected chanels in output texture. You can change position of target texture and size. Input texture can be: JPG, BMP, PNG, TGA.
- w - write output texture to file. One param: filename. This tool can save texture as 32-bit PNG or TGA. (FP can't use PNG, so write it as TGA).
Here is an example of file:
- Create texture with size 2048 2048
- Load texture "ed209_N.tga".
It will be stored on target texture at position defined by next 4 params.
First two values are position of left/top corrner. "0 0" is top/left corrner on target texture. "0.5 0.5" is center of target texture. Next two params is with and height. "1 1" means 100% width and 100% height of target texture. You can use the 4 params to change position and dimensions where loaded texture will be stored. The 4 params almost always will be "0 0 1 1"
This texture is normal map with values X,Y,Z stored as Red, Green and Blue color. We want to copy Red and Green value from source to Red and Green on target. Last param defines where values from source will be stored. It will be always 4 letters.
Accepted letters are: r/g/b/a/_/0/1. "_" means "no change". "0" - "= 0", "1" - "= 255" (255 will be in shader program interpreted as 1.0).
So this line will copy Red and Green values to Red and Green on target texture.
- Same as above, but: Red value from source will be copied to Blue value on target and Alpha on target will be set to 1.0
- Save output texture to file "ed209_NS.tga"
It seems complicated, so here is an example of what I did with my BAM-demo table. Inside this file, you will find:
- In "models-src" are source models with textures. Models are downloaded from tf3dm.com.
- In "models-fp" are: models prepared to use in FP (converted to .ms3d and to .fpm), tc.exe, source file with commands for tc.exe, textures generated by tc.exe
- Please read "models-fp/slug.readme.txt" -instruction on how I converted files
- Please read "models-fp.slug.slug.txt" - it is "command" file for tc.exe. Also inside you will find additional description.
Texture Combiner: "tc.exe"
This tool will "evolve" in future. Right now it doesn't have any error checking. It can scale source texture, but only in a limited way. It can decrease size 2x or 4x or 8x ... times. For example, it can convert source image from 1024x1024 to 512x512 or 256x256..., but not to 100x100 or 512x256. It can scale "up" with bilinear filtering. For example, it can convert source from 10x10 to 1024x1024.
You can easly change resolution of output texture. In my example, I set resolution to 2048x2048. If you replace first line of example to: "o 1024 1024" output texture will be 1024x1024.
Please remember, that the texture written to disk is always 32-bit. If you don't use height map, you can load it into any paint program and save as 24-bit image. It will decrease size of output image.
If you have any trouble using it or need help with your models, just ask me. I will help.
How to use all the stuff on table
Now You have two (or three if you have Specular texture) textures for model.
- Import textures in Future Pinball. Remember names of all imported textures.
- Adding "diffuse" (ordinary) texture to object. This texture is used on table, if there is not BAM or if user isn't using New Renderer.
- In table script under param: !texture = diffuseTextureName and !normalMap = normalMapTextureName and if you have Specular texture !specularMap = specularTextureName. See script in my BAM-demo table.
- Now we have one small problem. Because "normalMapTextureName" and "specularTextureName" is not assigned to any object on table, FP will not load it and BAM will not have access to it. We have to "cheat": Create in FP surface, adding as Top or Side texture "normalMpTextureName" and "specularTextureName", uncheck "Render object (initial value)". That last step will make this surface invisible, but FP will now load the additional textures.
When model has Height Map, BAM can distort textures to imitate additional, more complicated, geometry. Height Map stored in texture has only one value in range <0, 1> for every pixel. To use this information BAM also needs to know how to "scale" this value and "bias" of this value. You will have to deterimine these values in experiments (in BAM menu go to: [Rendering Engine] -> [DEV options] -> "!heightMap_scale" and "!heightMap_bias"). Once you find right values, you need only to add it to script.
When you have specular texture with different colors, you don't need to use "Specular level" in normalMap texture prepared with tc.exe. It that case you should set BLUE value to 1 (like i did for "Slug" in my BAM-demo table) and set !specularMap in script. If specular texture is "gray" (alway Red = Green = Blue), you should copy Red value from source specular texture to BLUE value in normalMap created with tc.exe. In this case, you don't need to add specular texture as separate texture to FP.