shader_
Detail map blending
When this shader's type is set to blended or blended base specular, the base map's alpha channel will be used as a blending mask between the primary and secondary detail maps.
This allows you to use two detail maps varyingly across a surface and is typically used for ground shaders which need both grassy and dirt areas. In this case the base map provides the general colouring across the ground of the level, while the detail maps tile and provide fine-level detail. There are a few options for how the detail maps blend with the base map.
Alpha testing
When the alpha tested flag is checked, the bump map's alpha channel can be used as a kind of transparency mask. The shader will either be fully opaque or fully transparent depending on if the alpha value is lighter or darker than 50% gray.
You should use this feature for transparent shaders that need to maintain the appearance of sharp edges regardless of distance and where semi-transparency is not needed. Some examples of this include the 2D "billboard" trees outside Timberland, the floor grates in Derelict, or foliage textures on scenery.
Depending on the texture, you may find that at a distance small transparent or opaque details become lost, such as a chain link fence becoming totally invisible. This is the result of mipmapping in the bump map since the alpha chanel is "blurring" as it becomes smaller and details are being lost. It can be important to tune the bump map's mipmap generation to avoid this:
- Limiting mipmap count results in more aliasing but preserves the impression of fine detail.
- Tuning the alpha bias lightens or darkens the alpha channel in mipmaps to result in more or less pixels passing the 50% alpha test.
Bump maps
Bump maps are special textures that encode the "bumpiness" of the surfaces they map to. They are used to represent fine details like cracks and grooves that affect specular reflections and lighting to make the surface look more geometrically detailed than it actually is.
Artists can create them as simple grayscale height maps in TIFF format, and once compiled by Tool or invader-bitmap into a bitmap tag with "height map" usage, they are represented as standard normal maps for use in-engine. Halo CE does not use height maps and doesn't support tessellation or parallax occlusion. The alpha channel of the bump map is unused unless the shader is alpha tested.
The lighting effect of bump maps can be seen under both dynamic lights and static lightmaps (sometimes called environmental bump maps), with the latter only natively supported in H1A and H1X unless using the CEnshine shader port for H1PC/H1CE. Environmental bump mapping uses incoming light directions which have been precalculated and stored per-vertex during radiosity.
Invalid bump maps
Artists should ensure that the bump map referenced by a shader is a valid normal map. Don't forget to set the bitmap's usage to height map if you're using tool to import a greyscale height map. Also, don't simply reuse a diffuse or a multipurpose map for a bump map. Failure to use a valid normal map will result in the surface appearing extremely dark or black.
Modders who are porting older Custom Edition maps to MCC may find that existing shaders have this problem, since environmental bump mapping was unsupported in H1CE and the original mappers would not have seen this darkening.
Shading artifacts
By default, environmental bump mapping is rendered by darkening surfaces based on the dot product (angle difference) between incoming light and the bump map. However, in some locations and lighting setups this can result in strange triangular shading artifacts that look like bad smoothing despite level geometry having the intended normals:
- Where small or point-like light sources are very close to surfaces.
- Where sharp shadows should be, but the area has either low geometric complexity and/or uses shaders with low radiosity detail levels.
The artifact could be considered a problem with the legacy lighting model; the baked lightmap already accounts for diffuse attenuation and it shouldn't be doubly applied. It is made worse by the limited resolution of both the intermediate lightmap mesh and baked lightmap texture which results in light bleeding, and how per-vertex incident radiosity vectors cannot represent quickly changing light directions across a surface.
You can set the new alternate bump attenuation flag to use a different bump mapping method (similar to Halo 2's) which removes these artifacts, but comes at the cost of possibly overexposing highlights from coloured lights and generally lightening surfaces. Using the flag or not is an artistic choice.
Custom Edition mappers never encountered this artifact due to CE's broken bump mapping. If you're porting a map from CE to MCC you may find that this this artifact is now noticeable. The new flag can be a quick fix to better maintain the original map's appearance and, if applied to all shaders, will generally brighten up a map and make it look more like CE.
If you want to avoid this artifact without using the flag because you prefer the classic look for a shader, here are some workarounds:
- Use high radiosity detail level for affected shader(s) if you aren't already.
- Tesselate surfaces where sharp shadows lie, especially where shadow umbras and penumbras would lie. This limits light bleeding by forcing the lightmapper to resolve a higher level of detail than it normally would based on quality settings, and results in more incident radiosity vectors being stored to better match the baked lighting texture, but has the cost of increasing triangle count.
- Replace nearby point light sources with large diffuse invisible light casting surfaces that avoid sharp shadows.
- Avoid putting scenery lights too close to surfaces or in locations that would cast sharp shadows.
Use by gbxmodels
When a gbxmodel references this shader type it will not render correctly in H1CE due to renderer bugs. Specular masking and tinting don't work and sky fog does not render over it. Some affected scenery include the teleporter base and human barricades. It is not recommended to use this shader type for custom objects when targeting Custom Edition, but it is safe to use in H1A.
Related HaloScript
Function/global | Type | |
---|---|---|
Toggles alpha testing for BSP shader_ | Global | |
Toggles the rendering of dynamic mirrors. | Global |
Structure and fields
Field | Type | Comments | |||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
shader environment flags | bitfield | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
shader environment type | enum | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
lens flare spacing | float | Determines how far apart BSP lens flares are generated, in world units, along a surface part using this shader. If set to | |||||||||||||||||||||||||||||||||||||||
lens flare | TagDependency : lens_flare | References the lens flare to be rendered at the generated lens flare markers. If empty, no lens flares will be generated. | |||||||||||||||||||||||||||||||||||||||
diffuse flags | bitfield | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
base map | TagDependency : bitmap | ||||||||||||||||||||||||||||||||||||||||
detail map function | enum | This controls how the detail map is blended with the base map. | |||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
primary detail map scale | float | ||||||||||||||||||||||||||||||||||||||||
primary detail map | TagDependency : bitmap | ||||||||||||||||||||||||||||||||||||||||
secondary detail map scale | float | ||||||||||||||||||||||||||||||||||||||||
secondary detail map | TagDependency : bitmap | ||||||||||||||||||||||||||||||||||||||||
micro detail map function | enum ? | ||||||||||||||||||||||||||||||||||||||||
micro detail map scale | float | ||||||||||||||||||||||||||||||||||||||||
micro detail map | TagDependency : bitmap | ||||||||||||||||||||||||||||||||||||||||
material color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
bump map scale | float | ||||||||||||||||||||||||||||||||||||||||
bump map | TagDependency : bitmap | ||||||||||||||||||||||||||||||||||||||||
bump map scale xy | Point2D | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
u animation function | enum | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
u animation period | float | ||||||||||||||||||||||||||||||||||||||||
u animation scale | float | ||||||||||||||||||||||||||||||||||||||||
v animation function | enum ? | ||||||||||||||||||||||||||||||||||||||||
v animation period | float | ||||||||||||||||||||||||||||||||||||||||
v animation scale | float | ||||||||||||||||||||||||||||||||||||||||
self illumination flags | bitfield | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
primary on color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
primary off color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
primary animation function | enum ? | ||||||||||||||||||||||||||||||||||||||||
primary animation period | float | ||||||||||||||||||||||||||||||||||||||||
primary animation phase | float | ||||||||||||||||||||||||||||||||||||||||
secondary on color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
secondary off color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
secondary animation function | enum ? | ||||||||||||||||||||||||||||||||||||||||
secondary animation period | float | ||||||||||||||||||||||||||||||||||||||||
secondary animation phase | float | ||||||||||||||||||||||||||||||||||||||||
plasma on color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
plasma off color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
plasma animation function | enum ? | ||||||||||||||||||||||||||||||||||||||||
plasma animation period | float | ||||||||||||||||||||||||||||||||||||||||
plasma animation phase | float | ||||||||||||||||||||||||||||||||||||||||
map scale | float | ||||||||||||||||||||||||||||||||||||||||
map | TagDependency : bitmap | ||||||||||||||||||||||||||||||||||||||||
specular flags | bitfield | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
brightness | float | ||||||||||||||||||||||||||||||||||||||||
perpendicular color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
parallel color | ColorRGB | ||||||||||||||||||||||||||||||||||||||||
reflection flags | bitfield | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
reflection type | enum | ||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||
lightmap brightness scale | float | ||||||||||||||||||||||||||||||||||||||||
perpendicular brightness | float | ||||||||||||||||||||||||||||||||||||||||
parallel brightness | float | ||||||||||||||||||||||||||||||||||||||||
reflection cube map | TagDependency : bitmap |
Acknowledgements
Thanks to the following individuals for their research or contributions to this topic:
- Conscars (Notes on bump mapping and alpha testing)
- Kavawuvi (Invader tag definitions)
- MosesOfEgypt (Tag structure research)