Difference between revisions of "Shaders in Oolite: uniforms"

From Elite Wiki
(Entity: Add fogUniform)
 
(17 intermediate revisions by 4 users not shown)
Line 1: Line 1:
== Uniforms in Oolite Shaders ==
 
 
 
:<small>The information presented on this page applies to Oolite test release 1.69 and later.</small>
 
:<small>The information presented on this page applies to Oolite test release 1.69 and later.</small>
  
A '''uniform''' in a [[Shaders in Oolite|shader]] is a variable whose value is specified by the host application – in this case, [[Oolite]]. Oolite allows arbitrary uniforms to be specified for shaders applied to ships, and these may either take constant values specified in ''shipdata.plist'', or be “bound” to an attribute of the ship. This allows shader authors to access numerous properties of a game entity without having to ask for them and wait for an updated version of Oolite.
+
A '''uniform''' in a [[Shaders in Oolite|shader]] is a variable whose value is specified by the host application – in this case, [[Oolite]]. Oolite allows arbitrary uniforms to be specified for shaders applied to ships, and these may either take constant values specified in ''shipdata.plist'', or be “bound” to an attribute of the ship. This allows shader authors to access numerous properties of a game entity without having to ask for them and wait for an updated version of Oolite. ('''Note:''' in the case of subentities, bound properties are fetched from the parent ship.)
  
 
=== Basic syntax ===
 
=== Basic syntax ===
Line 22: Line 20:
 
                     type = float;
 
                     type = float;
 
                     value = 42.0;
 
                     value = 42.0;
                 }
+
                 };
                 withinAegis =
+
                 withinAegis = "withinStationAegis";
                 {
+
                 compassMode = "compassMode";
                    type = binding;
 
                    value = "within_station_aegis";
 
                }
 
 
             }
 
             }
 
  <font color="#AAAAAA">        }</font>
 
  <font color="#AAAAAA">        }</font>
 
  <font color="#AAAAAA">    }</font>
 
  <font color="#AAAAAA">    }</font>
 
  <font color="#AAAAAA">}</font>
 
  <font color="#AAAAAA">}</font>
This contrived example declares two uniforms, ''shininess'' and ''withinAegis''. ''shininess'' is a constant float – it is always 42 – while ''withinAegis'' is bound to the ship’s ''within_station_aegis'' property. (See below for information on available properties.) This is a boolean, that is, a number whose value is either 0 (meaning no) or 1 (meaning yes). To use the uniforms within a shader (either a vertex shader or a fragment shader), they are declared as follows:
+
This contrived example declares three uniforms, ''shininess'', ''withinAegis'' and ''compassMode''. ''shininess'' is a constant <code>float</code>; it is always 42. ''withinAegis'' is bound to the ship’s ''withinStationAegis'' property. (See below for information on available properties.) This is a boolean, that is, a number whose value is either 0 (meaning no) or 1 (meaning yes). ''compassMode'' is a binding to the ''compassMode'' property. To use the uniforms within a shader (either a vertex shader or a fragment shader), they are declared as follows:
 
  uniform float shininess;
 
  uniform float shininess;
 
  uniform int withinAegis;
 
  uniform int withinAegis;
 +
uniform int compassMode;
 
  ...
 
  ...
 
  void main(void)
 
  void main(void)
Line 46: Line 42:
  
 
=== Uniform property types ===
 
=== Uniform property types ===
Every bindable property has a '''type'''. The simplest types, ''int'' and ''float'', correspond directly to the same types in GLSL. Both represent numbers, with the difference that a ''float'' can represent fractional values and very large values, but always has the same level of precision (about six digits), while ''int''s can represent any integer (non-fractional value) in a limited range. (FIXME: what are the precision and range guarantees for GLSL?)
+
Every bindable property has a '''type'''. The simplest types, ''int'' and ''float'', correspond directly to the same types in GLSL. Both represent numbers, with the difference that a ''float'' can represent fractional values and very large values, but always has the same level of precision (about six digits), while ''int''s can represent any integer (non-fractional value) in a limited range. A ''bool'' is an integer whose value can be only 0 (meaning no or false) or 1 (meaning yes or true). ('''Note:''' the GLSL specification is deliberately vague on the ranges of the number types. It also points out that most hardware will actually use floating-point calculations for ''int'' variables, which implies that integer calculations will incur rounding overhead.)
  
 
The ''vector'' type is translated to a GLSL ''vec4'', whose ''x'', ''y'' and ''z'' components correspond to those of the Oolite vector, and whose ''w'' component is always 1.0.
 
The ''vector'' type is translated to a GLSL ''vec4'', whose ''x'', ''y'' and ''z'' components correspond to those of the Oolite vector, and whose ''w'' component is always 1.0.
  
The ''quaternion'' type can be translated to a ''mat4x4'' representing a rotation matrix, or to a ''vec4'' whose ''x'', ''y'', ''z'' and ''w'' components correspond to those of the Oolite quaternion. '''IMPORTANT:''' in contexts such as [[property list]]s, quaternions are presented in the order ''w'', ''x'', ''y'', ''z''. However, GLSL ''vec4''s use the order ''x'', ''y'', ''z'', ''w''. This doesn't matter if you access the components by name (as in <code>myQuat.y</code> or <code>myQuat.wxyz</code>), but does matter if you use indices (as in <code>myQuat[1]</code>). (FIXME: is this even valid in GLSL?)
+
The ''quaternion'' type can be translated to a ''mat4x4'' representing a rotation matrix, or to a ''vec4'' whose ''x'', ''y'', ''z'' and ''w'' components correspond to those of the Oolite quaternion.
  
 
The ''matrix'' type is translated into a GLSL ''mat4x4''.
 
The ''matrix'' type is translated into a GLSL ''mat4x4''.
Line 60: Line 56:
 
  haveFuel =
 
  haveFuel =
 
  {
 
  {
     type = binding;
+
     binding = "fuel";
    value = "fuel";
 
 
     clamped = true;
 
     clamped = true;
  }
+
  };
The '''clamped''' conversion option, when applied to a property of type ''float'', causes the value to be clamped to the range [0, 1]. When applied to an ''int'' propertie, any value other than 0 (including negative values) is converted to 1. The default value is ''false''.
+
The '''clamped''' conversion option, when applied to a property of type ''float'', causes the value to be clamped to the range [0, 1]. When applied to an ''int'' property, any value other than 0 (including negative values) is converted to 1. The default value is ''false''.
  
 
The '''normalized''' option causes vector properties to be normalized, that is, scaled so they have the same direction but length 1. The default value is ''false''.
 
The '''normalized''' option causes vector properties to be normalized, that is, scaled so they have the same direction but length 1. The default value is ''false''.
  
The '''toMatrix''' option causes quaternion properties to be converted to rotation matrix, rather than having their components packed into a ''vec4''. The default value is ''true''.
+
The '''asMatrix''' option causes quaternion properties to be converted to rotation matrix, rather than having their components packed into a ''vec4''. The default value is ''true''.
  
 
=== Bindable property reference ===
 
=== Bindable property reference ===
The following sections list all properties of entities which can be used in a uniform binding, regardless of apparent usefullness. Note, however, that '''many of these names will change before the next stable release''' – in particular, it is intended that by Oolite 1.70 properties using underscores (<code>a_property_name</code>) will be converted to CamelCase (<code>aPropertyName</code>). This reflects ongoing clean-up activity within the Oolite code.
+
The following sections list entity properties which can be used in a uniform binding, regardless of apparent usefullness. Note, however, that '''some of these names may change before the next stable release'''.
  
 
==== Entity ====
 
==== Entity ====
FIXME: fill in
+
The following properties are available for all entities:
 +
{| class="wikitable" border="1" cellpadding="3" cellspacing="0"
 +
|+ Bindable entity properties
 +
! Name !! Type !! Description
 +
|-
 +
| ''position'' || vector || The location of the entity in system co-ordinates.
 +
|-
 +
| ''orientation'' || quaternion || The orientation of the entity.
 +
|-
 +
| ''relativePosition'' || vector || The location of the entity, relative to the player.
 +
|-
 +
| ''viewpointOffset'' || vector || The location of the current camera, in entity co-ordinates. Although this is defined for all entities, it is only meaningful for the player ship.
 +
|-
 +
| ''collisionRadius'' || float || Together with the ''position'', specifies a sphere completely containing the collidable volume of the entity.
 +
|-
 +
| ''mass'' || float || The mass of the entity.
 +
|-
 +
| ''energy'' || float || The current energy level of the entity.
 +
|-
 +
| ''maxEnergy'' || float || The current maximum energy level of the entity.
 +
|-
 +
| ''universalTime'' || float || The [[Time scales in Oolite#game real time|game real time]] clock. The value is the same for all entities and updates once per frame.
 +
|-
 +
| ''spawnTime'' || float || The [[Time scales in Oolite#game real time|game real time]] at which the entity came into existance.
 +
|-
 +
| ''timeElapsedSinceSpawn'' || float || The number of seconds (in the [[Time scales in Oolite#game real time|game real time]] scale) since the entity came into existance – the difference between ''universalTime'' and ''spawnTime''.
 +
|-
 +
| ''throwingSparks'' || bool || Whether the entity is generating sparks (for instance, a ship about to explode).
 +
|-
 +
| ''fogUniform'' (version 1.83) || vector || Atmosphere colour rgba for applying fog effect. Alpha channel is zero for no fogging to 1 for full fogging.
 +
|-
 +
|}
  
 
==== Ship ====
 
==== Ship ====
Ships have all the properties of [[#Entity|entities]], and several others:
+
Ships (i.e., anything set up in ''shipdata.plist'', regardless of function) have all the properties of [[#Entity|entities]], and several others:
FIXME: fill in
+
{| class="wikitable" border="1" cellpadding="3" cellspacing="0"
 +
|+ Bindable ship properties
 +
! Name !! Type !! Description
 +
|-
 +
| ''isBeacon'' || bool || True if the entity is a beacon.
 +
|-
 +
| ''isFrangible'' || bool || True if the entity is frangible, i.e. subentities can be shot off.
 +
|-
 +
| ''isCloaked'' || bool || True if the entity is cloaked. [b]Note:[/b] a cloaked ship will only be drawn approximately once per ten frames, regardless of shaders.
 +
|-
 +
| ''isJammingScanning'' || bool || True if the ship has an active military jammer.
 +
|-
 +
| ''hasMilitaryScannerFilter'' || bool || True if the ship has a military scanner filter.
 +
|-
 +
| ''messageTime'' || float || Time before a radio message may be sent, in seconds. (This is set to 6.0 seconds when an NPC ship sends a message, and decreases over time.)
 +
|-
 +
| ''groupID'' || int || Unique identifier for the escort group the ship belongs to.
 +
|-
 +
| ''escortCount'' || int || The number of active escorts the ship has.
 +
|-
 +
| ''hasHostileTarget'' || bool || True if the ship has a target and the ship’s current AI behaviour is one of hostile intent.
 +
|-
 +
| ''weaponRange'' || float || Maximum range (in metres) of the ship’s main weapon. [b]Note:[/b] since subentities’ shaders get the parent ship’s properties, this may not work as expected.
 +
|-
 +
| ''scannerRange'' || float || The distance (in metres) in which the ship will scan for enemies.
 +
|-
 +
| ''withinStationAegis'' || bool || True if the ship is within the aegis of the system’s main station.
 +
|-
 +
| ''fuel'' || int || Ship’s fuel level, in tenths of a light year.
 +
|-
 +
| ''flightPitch'' || float || Current pitch rate.
 +
|-
 +
| ''flightRoll'' || float || Current roll rate.
 +
|-
 +
| ''flightYaw'' || float || Current yaw rate. Currently always 0 for NPC ships.
 +
|-
 +
| ''flightSpeed'' || float || Ship’s current speed.
 +
|-
 +
| ''maxFlightSpeed'' || float || Ship’s speed at full throttle. Something of a misnomer – actual speed may be higher using afterburners or hyperspeed.
 +
|-
 +
| ''speedFactor'' || float || ''flightSpeed'' divided by ''maxFlightSpeed''. May be greater than 1.0 (unless [[#Conversions|clamped]] is used).
 +
|-
 +
| ''damage'' || int || ''energy'' expressed as a percentage of ''maxEnergy''.
 +
|-
 +
| ''laserHeatLevel'' || float || The temperature level of the current weapon.
 +
|-
 +
| ''hullHeatLevel'' || float || The temperature level of the hull, due to proximity to stars, atmospheric drag or combat hits. When it reaches 1.0, the ship starts taking damage rapidly.
 +
|-
 +
| ''entityPersonality'' || float || A randomly-generated value in the range 0.0 to 1.0 that stays with the entity for its lifetime. Useful for adding random variations.
 +
|-
 +
| ''entityPersonalityInt'' || float || Same as ''entity_personality'', scaled to the range 0 to 32767.
 +
|-
 +
| ''numberOfScannedShips'' || int || The number of ships within scanner range (but no more than 16).
 +
|-
 +
| ''destination'' || vector || The location, in system co-ordinates, that the AI is trying to fly to. This may not always be meaningful depending on AI state.
 +
|-
 +
| ''rangeToDestination'' || float || The distance in metres between ''position'' and ''destination''.
 +
|-
 +
| ''rangeToPrimaryTarget'' || float || The distance in metres to the AI’s target (i.e., the ship it is trying to shoot). 0 if no target.
 +
|-
 +
| ''laserColor'' || colour || The colour of the ship’s laser.
 +
|-
 +
| ''isHulk'' || bool || True if the ship has been abandoned.
 +
|-
 +
| ''lightsActive'' || bool || True if flashers are turned on, false otherwise.
 +
|-
 +
| ''alertCondition''<br>(1.77 or later) || int || Current alert condition – 0 for docked, 2 for yellow, 3 for red.
 +
|-
 +
|}
  
 
==== Player ship ====
 
==== Player ship ====
 
The player ship has all the properties of [[#Entity|entities]] and [[#Ship|ships]], and several others:
 
The player ship has all the properties of [[#Entity|entities]] and [[#Ship|ships]], and several others:
FIXME: fill in
+
{| class="wikitable" border="1" cellpadding="3" cellspacing="0"
 +
|+ Bindable player ship properties
 +
! Name !! Type !! Description
 +
|-
 +
| ''massLocked'' || bool || True if the ship is too close to a large object to be able to make a witchspace jump.
 +
|-
 +
| ''atHyperspeed'' || bool || True if the ship is at hyperspeed.
 +
|-
 +
| ''velocityVector'' || vector || The ship’s velocity.
 +
|-
 +
| ''dialForwardShield'' || float || The forward shield level, ranging from 0.0 to 1.0.
 +
|-
 +
| ''dialAftShield'' || float || The aft shield level, ranging from 0.0 to 1.0.
 +
|-
 +
| ''dialMissileStatus'' || int || State of selected missile – 0 for safe/no missile, 1 for active, 2 for locked.
 +
|-
 +
| ''dialFuelScoopStatus'' || int || State of cargo scoop – 0 for no scoop installed, 1 for full hold, 2 for idle with space in hold, 3 for actively scooping.
 +
|-
 +
| ''compassMode'' || int || State of advanced space compass – 0 for no advanced space compass installed, 1 for planet mode, 2 for station mode, 3 for sun mode, 4 for target mode, 5 for any beacon. More may be added in future.
 +
|-
 +
| ''activeMissile'' || int || Which missile slot is currently selected, from 0 to ''dialMaxMissiles'' - 1.
 +
|-
 +
| ''dialMaxMissiles'' || int || The number of missile slots on the ship.
 +
|-
 +
| ''dialIdentEngaged'' || bool || True if ident (targeting) mode is active.
 +
|-
 +
| ''alertCondition'' || int || Current alert condition – 0 for docked, 1 for green, 2 for yellow, 3 for red.
 +
|-
 +
| ''trumbleCount'' || int || Number of trumbles with which the player’s ship is infected.
 +
|-
 +
|}
 +
Additionally, all [[Methods#Querying states|state query scripting methods]] ending with ''_number'' may be used for the player.
 +
 
 +
 
 +
[[Category:Oolite]]
 +
[[Category:Oolite scripting]]

Latest revision as of 18:03, 24 February 2016

The information presented on this page applies to Oolite test release 1.69 and later.

A uniform in a shader is a variable whose value is specified by the host application – in this case, Oolite. Oolite allows arbitrary uniforms to be specified for shaders applied to ships, and these may either take constant values specified in shipdata.plist, or be “bound” to an attribute of the ship. This allows shader authors to access numerous properties of a game entity without having to ask for them and wait for an updated version of Oolite. (Note: in the case of subentities, bound properties are fetched from the parent ship.)

Basic syntax

Uniforms are specified in the materials or shaders dictionary of a ship’s shipdata.plist entry:

"ahruman_shady_cobra_example" =
{
    like_ship = "cobra3-player";
    shaders =
    {
        "cobra3_redux.png" =
        {
            textures = ( "cobra3_redux.png" );
            fragment_shader = "ahruman_shady_cobra_example.fragment";
            uniforms =
            {
                shininess =
                {
                    type = float;
                    value = 42.0;
                };
                withinAegis = "withinStationAegis";
                compassMode = "compassMode";
            }
        }
    }
}

This contrived example declares three uniforms, shininess, withinAegis and compassMode. shininess is a constant float; it is always 42. withinAegis is bound to the ship’s withinStationAegis property. (See below for information on available properties.) This is a boolean, that is, a number whose value is either 0 (meaning no) or 1 (meaning yes). compassMode is a binding to the compassMode property. To use the uniforms within a shader (either a vertex shader or a fragment shader), they are declared as follows:

uniform float shininess;
uniform int withinAegis;
uniform int compassMode;
...
void main(void)
{
    if (withinAegis)
    {
         // Do aegis-specific effect here
    }
    ...
}

Uniform property types

Every bindable property has a type. The simplest types, int and float, correspond directly to the same types in GLSL. Both represent numbers, with the difference that a float can represent fractional values and very large values, but always has the same level of precision (about six digits), while ints can represent any integer (non-fractional value) in a limited range. A bool is an integer whose value can be only 0 (meaning no or false) or 1 (meaning yes or true). (Note: the GLSL specification is deliberately vague on the ranges of the number types. It also points out that most hardware will actually use floating-point calculations for int variables, which implies that integer calculations will incur rounding overhead.)

The vector type is translated to a GLSL vec4, whose x, y and z components correspond to those of the Oolite vector, and whose w component is always 1.0.

The quaternion type can be translated to a mat4x4 representing a rotation matrix, or to a vec4 whose x, y, z and w components correspond to those of the Oolite quaternion.

The matrix type is translated into a GLSL mat4x4.

The colour type is translated into a GLSL vec4 type, whose r, g, b and a components correspond to those of the Oolite colour object.

Conversions

Several types of binding can be modified by conversion options, specified in the uniforms dictionary, for example:

haveFuel =
{
    binding = "fuel";
    clamped = true;
};

The clamped conversion option, when applied to a property of type float, causes the value to be clamped to the range [0, 1]. When applied to an int property, any value other than 0 (including negative values) is converted to 1. The default value is false.

The normalized option causes vector properties to be normalized, that is, scaled so they have the same direction but length 1. The default value is false.

The asMatrix option causes quaternion properties to be converted to rotation matrix, rather than having their components packed into a vec4. The default value is true.

Bindable property reference

The following sections list entity properties which can be used in a uniform binding, regardless of apparent usefullness. Note, however, that some of these names may change before the next stable release.

Entity

The following properties are available for all entities:

Bindable entity properties
Name Type Description
position vector The location of the entity in system co-ordinates.
orientation quaternion The orientation of the entity.
relativePosition vector The location of the entity, relative to the player.
viewpointOffset vector The location of the current camera, in entity co-ordinates. Although this is defined for all entities, it is only meaningful for the player ship.
collisionRadius float Together with the position, specifies a sphere completely containing the collidable volume of the entity.
mass float The mass of the entity.
energy float The current energy level of the entity.
maxEnergy float The current maximum energy level of the entity.
universalTime float The game real time clock. The value is the same for all entities and updates once per frame.
spawnTime float The game real time at which the entity came into existance.
timeElapsedSinceSpawn float The number of seconds (in the game real time scale) since the entity came into existance – the difference between universalTime and spawnTime.
throwingSparks bool Whether the entity is generating sparks (for instance, a ship about to explode).
fogUniform (version 1.83) vector Atmosphere colour rgba for applying fog effect. Alpha channel is zero for no fogging to 1 for full fogging.

Ship

Ships (i.e., anything set up in shipdata.plist, regardless of function) have all the properties of entities, and several others:

Bindable ship properties
Name Type Description
isBeacon bool True if the entity is a beacon.
isFrangible bool True if the entity is frangible, i.e. subentities can be shot off.
isCloaked bool True if the entity is cloaked. [b]Note:[/b] a cloaked ship will only be drawn approximately once per ten frames, regardless of shaders.
isJammingScanning bool True if the ship has an active military jammer.
hasMilitaryScannerFilter bool True if the ship has a military scanner filter.
messageTime float Time before a radio message may be sent, in seconds. (This is set to 6.0 seconds when an NPC ship sends a message, and decreases over time.)
groupID int Unique identifier for the escort group the ship belongs to.
escortCount int The number of active escorts the ship has.
hasHostileTarget bool True if the ship has a target and the ship’s current AI behaviour is one of hostile intent.
weaponRange float Maximum range (in metres) of the ship’s main weapon. [b]Note:[/b] since subentities’ shaders get the parent ship’s properties, this may not work as expected.
scannerRange float The distance (in metres) in which the ship will scan for enemies.
withinStationAegis bool True if the ship is within the aegis of the system’s main station.
fuel int Ship’s fuel level, in tenths of a light year.
flightPitch float Current pitch rate.
flightRoll float Current roll rate.
flightYaw float Current yaw rate. Currently always 0 for NPC ships.
flightSpeed float Ship’s current speed.
maxFlightSpeed float Ship’s speed at full throttle. Something of a misnomer – actual speed may be higher using afterburners or hyperspeed.
speedFactor float flightSpeed divided by maxFlightSpeed. May be greater than 1.0 (unless clamped is used).
damage int energy expressed as a percentage of maxEnergy.
laserHeatLevel float The temperature level of the current weapon.
hullHeatLevel float The temperature level of the hull, due to proximity to stars, atmospheric drag or combat hits. When it reaches 1.0, the ship starts taking damage rapidly.
entityPersonality float A randomly-generated value in the range 0.0 to 1.0 that stays with the entity for its lifetime. Useful for adding random variations.
entityPersonalityInt float Same as entity_personality, scaled to the range 0 to 32767.
numberOfScannedShips int The number of ships within scanner range (but no more than 16).
destination vector The location, in system co-ordinates, that the AI is trying to fly to. This may not always be meaningful depending on AI state.
rangeToDestination float The distance in metres between position and destination.
rangeToPrimaryTarget float The distance in metres to the AI’s target (i.e., the ship it is trying to shoot). 0 if no target.
laserColor colour The colour of the ship’s laser.
isHulk bool True if the ship has been abandoned.
lightsActive bool True if flashers are turned on, false otherwise.
alertCondition
(1.77 or later)
int Current alert condition – 0 for docked, 2 for yellow, 3 for red.

Player ship

The player ship has all the properties of entities and ships, and several others:

Bindable player ship properties
Name Type Description
massLocked bool True if the ship is too close to a large object to be able to make a witchspace jump.
atHyperspeed bool True if the ship is at hyperspeed.
velocityVector vector The ship’s velocity.
dialForwardShield float The forward shield level, ranging from 0.0 to 1.0.
dialAftShield float The aft shield level, ranging from 0.0 to 1.0.
dialMissileStatus int State of selected missile – 0 for safe/no missile, 1 for active, 2 for locked.
dialFuelScoopStatus int State of cargo scoop – 0 for no scoop installed, 1 for full hold, 2 for idle with space in hold, 3 for actively scooping.
compassMode int State of advanced space compass – 0 for no advanced space compass installed, 1 for planet mode, 2 for station mode, 3 for sun mode, 4 for target mode, 5 for any beacon. More may be added in future.
activeMissile int Which missile slot is currently selected, from 0 to dialMaxMissiles - 1.
dialMaxMissiles int The number of missile slots on the ship.
dialIdentEngaged bool True if ident (targeting) mode is active.
alertCondition int Current alert condition – 0 for docked, 1 for green, 2 for yellow, 3 for red.
trumbleCount int Number of trumbles with which the player’s ship is infected.

Additionally, all state query scripting methods ending with _number may be used for the player.