Thermal materials - Outerra/anteworld GitHub Wiki
Object's internal heat sources
Optional thermal map texture support in model importer (preferred 3-channel BC1-compressed or 4-channel lower resolution uncompressed)
- each channel corresponds to one internal heat source (engine, interior, exhaust ...)
- an API function is able to set the temperature or heat flow of each internal heat source per object instance
- texture values (0..1) specify the ratio of temperature delta that given heat source adds at given point
- resulting temperature or heat is combined and the resulting thermal value computed in shaders
For example, if the engine temperature channel is set to 90°C, and hood/bonnet has a ratio of 0.5 in its engine channel, then the temperature there may be computed as (90 - ambient) * 0.5
If a material doesn't have a thermal texture, it should still be possible to uniformly apply an internal heating, it's assumed the heating coefficients are 1.0 on the entire body using given material.
Setting internal temperatures from console:
- Spawn a vehicle and do not exit it
- Open console (alt + c)
- type
.current c
g = c.get_geomob(0)
g.set_internal_temperature(0, 32)
- channel 0 (red) has been set to 32 degrees
- you can exit vehicle now
Global parameters
in defaults/thermal.cfg
road_max_temperature
- max relative increase of road's temperature caused by sundirt_max_temperature
- max relative increase of dirt's temperature caused by sunideal_grass_temperature
- ideal temperature of grassideal_tree_temperature
- ideal temperature of treestrunk_temperature_deviation
- blend between ideal_tree_temperature and current air temperature (0 == ideal temp, 1 = air temp)leaves_temperature_deviation
- same as trunk_temperature_deviation, but for leavesroad_sun_lag
- how much is virtual Sun behind the actual Sun, defined in part of day, e.g. 0.1 means 1/10th of a day == 2.4 hours. This can be used to fake heat accumulation. Applied for roads.dirt_sun_lag
- same as road_sun_lag, but for dirtroad_temperature_offset
- fixed amount added to road's temperature
runtime (API in framebuffer::set_thermal_params)
sensor_temperature_black
- temperature map to black (ignored if autogain is enabled)sensor_temperature_white
- temperature map to white (ignored if autogain is enabled)air_temperature
- ambient temperature of environmentwater_temperature
air_temperature_daytime_coef
- intraday difference in air temperature,current_air_temperature = air_temperature + air_temperature_daytime_coef * dot(sun_dir, up)
, default value is 5.0
runtime (API in framebuffer::set_ir_params)
- contrast
- amplify
- noise
color = srcColor * amplify + random_value * noise + contrast;
Example how to set thermal params from console:
.bind f fb
f.enable_thermal_autogain(false)
f.set_thermal_params(10, 60, 10, 5, 5) <- this is white-hot
f.set_thermal_params(60, 10, 10, 5, 5) <- this is black-hot
Scientific mode
Scientific mode uses RGB colors to display thermal information. It can be enabled/disabled with framebuffer::enable_thermal_scientific_mode
.bind f fb
f.enable_thermal_scientific_mode(true)
Thermal material parameters
Extend material definition in mtl files by thermal parameters:
- sun_lag - see road_sun_lag.
- max_temperature_black - Max temperature increase of black material sun can cause, color is taken from albedo texture
- max_temperature_white - same as max_temperature_black, but for white material
Instead of using direct physical values it should be also possible to use material names there, for example to have a "thermal" value that allows for different things:
"thermal" : "glass"
The template materials can be found in defaults/thermal_mats.cfg
. Example:
materials = [ (material) {
name = "glass",
sun_lag = 0.1,
max_temperature_black = 45,
max_temperature_white = 15
}]
External heat source on objects
Heating from sun is computed using the thermal material parameters above, model geometry and thermal sun position for given material type. Resulting temperature is recombined with heat generated from internal sources.
It may be also desirable to be able to suppress the external heating effect on given object or class of objects.
Terrain thermal rendering
Similar to the definition of material parameters for objects, except that it's used internally by terrain generator.
Autogain
If autogain is enabled it uses temperature histogram to compute sensor settings.
If autogain is disabled (e.g. to simulate different sensors with different parameters) API can be used to query the most recent temperature histogram framebuffer::get_temperature_histogram
and set thermal parameters as required framebuffer::set_thermal_params
Can be turned on/off with framebuffer::enable_thermal_autogain
Formulas
There are four different shaders, each with its own formula to compute temperature of a surface - t
. t
is then further processed to get the color on screen.
Grass
Grass is actively trying to keep temperature in ideal range (ideal_grass_temperature
), e.g. cool itself down by evaporation.
t = ideal_grass_temperature * (1 - leaves_temperature_deviation) + air_temperature * leaves_temperature_deviation
Trees
Trees are the same as grass except trunk and leaves use different constants.
deviation = leaves_temperature_deviation or trunk_temperature_deviation
t = ideal_tree_temperature * (1 - leaves_temperature_deviation) + air_temperature * leaves_temperature_deviation
Terrain
Green parts of terrain are handled as grass. Road and dirt use following formula:
max_sun_t = road_max_temperature or dirt_max_temperature
sun_lag = road_sun_lag or dirt_sun_lag
sun_t_0 = angle between sunlight and surface
sun_t_1 = sun_t_0 * sun_occlusion
sun_t_2 = sun_t_1 * forest_coef
sun_t_3 = sun_t_2 * atmosphere_attenuation
t = sun_t_3 + road_temperature_offset for roads
sun_t_3 for dirt
Objects
max_sun_t = max_temperature_black * (1 - luminance) + max_temperature_white * luminance
sun_t_0 = max_sun_t * angle between sunlight and surface
sun_t_1 = sun_t_0 * sun_occlusion
sun_t_2 = sun_t_1 * atmosphere_attenuation
t_0 = max(internal_heat, air_temperature) + sun_t_2
t = t_0 * surface view angle
Output
Nonscientific mode:
grayscale_color = (t - sensor_temperature_black) / (sensor_temperature_white - sensor_temperature_black)
Scientific mode formula is a bit more complicated and output is RGB.