Effect framework: Difference between revisions

Jump to navigation Jump to search
(29 intermediate revisions by the same user not shown)
Line 1: Line 1:
{{forum|47|Effects & Shaders}}
{{Rendering}}
The effect framework as per version 2019.1
The effect framework as per version 2019.1
Effects describe the graphical appearance of 3d objects and scenery in
FlightGear. The main motivation for effects is to support OpenGL
shaders and to provide different implementations for graphics hardware
of varying capabilities. Effects are similar to DirectX effects files
and Ogre3D material scripts.
An effect is a property list. The property list syntax is extended
with new "vec3d" and "vec4d" types to support common computer graphics
values. Effects are read from files with a ".eff" extension or can be
created on-the-fly by FlightGear at runtime.  An effect consists of a
"parameters" section followed by "technique" descriptions.  The
"parameters" section is a tree of values that describe, abstractly,
the graphical characteristics of objects that use the effect. Techniques
refer to these parameters and use them to set OpenGL state or to set
parameters for shader programs. The names of properties in the
parameter section can be whatever the effects author chooses, although
some standard parameters  are set by FlightGear itself. On the other
hand, the properties in the techniques section are all defined by the
FlightGear.


=Default Effects in Terrain Materials and Models=
=Default Effects in Terrain Materials and Models=
Line 20: Line 42:
system. The parameters created are:  
system. The parameters created are:  


* material active, ambient, diffuse, specular, emissive,
* material active, ambient, diffuse, specular, emissive, shininess, color mode
shininess, color mode
# blend active, source, destination
* blend active, source, destination
# shade-model
* shade-model
# cull-face
* cull-face
* rendering-hint
* rendering-hint
* texture type, image, filter, wrap-s, wrap-t
* texture type, image, filter, wrap-s, wrap-t


=Specifying Custom Effects=
=Specifying Custom Effects=
Line 34: Line 55:
In the terrain materials.xml, an "effect" property specifies the name
In the terrain materials.xml, an "effect" property specifies the name
of the model to use.
of the model to use.
In model .xml files, A richer syntax is supported. [TO BE DETERMINED]


Material animations will be implemented by creating a new effect
Material animations will be implemented by creating a new effect
Line 42: Line 61:


=Examples=
=Examples=
The Effects directory contains the effects definitions; look there for
The $FGDATA/Effects directory contains the effects definitions; look there for
examples. Effects/crop.eff is a good example of a complex effect.
examples. Effects/crop.eff is a good example of a complex effect.


Line 111: Line 130:


Note that parameters can use the <use> tags to enable properties to specify the values.
Note that parameters can use the <use> tags to enable properties to specify the values.
==Generate==
Often shader effects need tangent vectors to work properly. These
tangent vectors, usually called tangent and binormal, are computed
on the CPU and given to the shader as vertex attributes. These
vectors are computed on demand on the geometry using the effect if
the 'generate' clause is present in the effect file. Exemple :
<syntaxhighlight lang="xml">
<generate>
<tangent type="int">6</tangent>
<binormal type="int">7</binormal>
<normal type="int">8</normal>
</generate>
</syntaxhighlight>
Valid subnodes of 'generate' are 'tangent', 'binormal' or 'normal'.
The integer value of these subnode is the index of the attribute
that will hold the value of the vec3 vector.
The generate clause is located under PropertyList in the xml file.
In order to be available for the vertex shader, these data should
be bound to an attribute in the program clause, like this :
<syntaxhighlight lang="xml">
<program>
<vertex-shader>my_vertex_shader</vertex-shader>
<attribute>
<name>my_tangent_attribute</name>
<index>6</index>
</attribute>
<attribute>
<name>my_binormal_attribute</name>
<index>7</index>
</attribute>
</program>
</syntaxhighlight>
attribute names are whatever the shader use. The index is the one
declared in the 'generate' clause. So because generate/tangent has
value 6 and my_tangent_attribute has index 6, my_tangent_attribute
holds the tangent value for the vertex.


==Technique==
==Technique==
Line 116: Line 179:


===predicate===
===predicate===
Condition for this technique to be used. If this fails it will try the next technique in the effect.
A technique can contain a predicate that describes the OpenGL
functionality required to support the technique. The first
technique with a valid predicate in the list of techniques is used
to set up the graphics state of the effect. A technique with no
predicate is always assumed to be valid. The predicate is written in a
little expression language that supports the following primitives:
 
and, or, equal, less, less-equal
glversion - returns the version number of OpenGL
extension-supported - returns true if an OpenGL extension is supported
property - returns the boolean value of a property
float-property - returns the float value of a property, useful inside equal, less or less-equal nodes
shader-language - returns the version of GLSL supported, or 0 if there is none.
 
The proper way to test whether to enable a shader-based technique is:
<syntaxhighlight lang="xml">
<predicate>
  <and>
<property>/sim/rendering/shader-effects</property>
<less-equal>
  <value type="float">1.0</value>
  <shader-language/>
</less-equal>
  </and>
</predicate>
</syntaxhighlight>
 
There is also a property set by the user to indicate what is the level
of quality desired. This level of quality can be checked in the predicate
like this :
<syntaxhighlight lang="xml">
    <predicate>
      <and>
        <property>/sim/rendering/shader-effects</property>
<less-equal>
  <value type="float">2.0</value>
  <float-property>/sim/rendering/quality-level</float-property>
</less-equal>
<!-- other predicate conditions -->
      </and>
    </predicate>
</syntaxhighlight>
   
The range of /sim/rendering/quality-level is [0..5]
* 2.0 is the threshold for relief mapping effects,
* 4.0 is the threshold for geometry shader usage.


Example:
Example:


<syntaxhighlight lang="xml">
<predicate>
<predicate>
<and>
<and>
Line 138: Line 247:
</and>
</and>
  </predicate>
  </predicate>
</syntaxhighlight>


===pass===
===pass===
What is passed to the shaders/OSG.
A technique can consist of several passes. A pass is basically an Open
(Not sure, but think multiple passes are possible.)
Scene Graph StateSet. Ultimately all OpenGL and OSG modes and state
attributes  will be accessable in techniques. State attributes -- that
is, technique properties that have children and are not just boolean
modes -- have an <active> parameter which enables or disables the
attribute. In this way a technique can declare parameters it needs,
but not enable the attribute at all if it is not needed; the decision
can be based on a parameter in the parameters section of the
effect. For example, effects that support transparent and opaque
geometry could have as part of a technique:


Note that entries can use the <use> tags to enable parameters to specify the values.
<syntaxhighlight lang="xml">
  <blend>
<active><use>blend/active</use></active>
<source>src-alpha</source>
<destination>one-minus-src-alpha</destination>
  </blend>
</syntaxhighlight>
 
So if the blend/active parameter is true blending will be activated
using the usual blending equation; otherwise blending is disabled.
 
Values are assigned to technique properties in several ways:
 
* They can appear directly in the techniques section as a
constant. For example:
<syntaxhighlight lang="xml">
<uniform>
<name>ColorsTex</name>
<type>sampler-1d</type>
<value type="int">2</value>
</uniform>
</syntaxhighlight>
* The name of a property in the parameters section can be
referenced using a "use" clause. For example, in the technique
section:
<syntaxhighlight lang="xml">
<material>
<ambient><use>material/ambient</use></ambient>
</material>
</syntaxhighlight>
Then, in the parameters section of the effect:
<syntaxhighlight lang="xml">
<parameters>
<material>
<ambient type="vec4d">0.2 0.2 0.2 1.0</ambient>
</material>
</parameters>
</syntaxhighlight>
It's worth pointing out that the "material" property in a
technique specifies part of OpenGL's state, whereas "material"
in the parameters section is just a name, part of a
hierarchical namespace.
 
* A property in the parameters section doesn't need to contain
a constant value; it can also contain a "use" property. Here
the value of the use clause is the name of a node in an
external property tree which will be used as the source of a
value. If the name begins with '/', the node is in
FlightGear's global property tree; otherwise, it is in a local
property tree, usually belonging to a model [NOT IMPLEMENTED
YET]. For example:
<syntaxhighlight lang="xml">
<parameters>
<chrome-light><use>/rendering/scene/chrome-light</use></chrome-light>
</parameters>
</syntaxhighlight>
The type is determined by what is expected by the technique
attribute that will ultimately receive the value. [There is
no way to get vector values out of the main property system
yet; this will be fixed shortly.] Values that are declared
this way are dynamically updated if the property node
changes.


====lighting====
====lighting====
Line 158: Line 337:


Children values: dst-alpha, dst-color, one, one-minus-dst-alpha, one-minus-dst-color, one-minus-src-alpha, one-minus-src-color, src-alpha, src-alpha-saturate, src-color, constant-color, one-minus-constant-color, constant-alpha, one-minus-constant-alpha, zero
Children values: dst-alpha, dst-color, one, one-minus-dst-alpha, one-minus-dst-color, one-minus-src-alpha, one-minus-src-color, src-alpha, src-alpha-saturate, src-color, constant-color, one-minus-constant-color, constant-alpha, one-minus-constant-alpha, zero
Example:
<syntaxhighlight lang="xml">
                <blend>
                        <active>true</active>
                        <source>one-minus-dst-alpha</source>
<destination>src-alpha-saturate</destination>
</blend>
</syntaxhighlight>


====shade-model====
====shade-model====
Line 165: Line 353:
front, back, front-back, off
front, back, front-back, off


====rendering-hint====
====texture-unit====
Sent to OSG.
Example:


default, opaque, transparent
<syntaxhighlight lang="xml">
 
                <texture-unit>
====texture-unit====
                        <unit>3</unit>
<image>Textures/Terrain/void.png</image>
<type>2d</type>
<filter>linear-mipmap-linear</filter>
                        <mag-filter>linear-mipmap-linear</mag-filter>
<wrap-s>repeat</wrap-s>
<wrap-t>repeat</wrap-t>
                        <wrap-r>repeat</wrap-r>
<internal-format>normalized</internal-format>
                        <mipmap-control>
                            <function-r>average</function-r>
    <function-g>min</function-g>
                            <function-b>sum</function-b>
    <function-a>product</function-a>
                        </mitmap-control>
                        <environment>
                            <mode>decal</mode>
                            <color>0.0 0.1 0.6 1.0</color>
                        </environment>
                        <point-sprite>true</point-sprite>
                        <texenv-combine>operand0-rgb</texenv-combine>
                        <texgen>
                            <mode>S</mode>
                            <planes>0.075, 0.0, 0.0, 0.5</planes>
                        </texgen>
</texture-unit>
</syntaxhighlight>


====vertex-program-two-side====
====vertex-program-two-side====
true or false
true or false
====polygon-mode====
children: front, back
Valid values:  fill, line, point


====vertex-program-point-size====
====vertex-program-point-size====
Line 180: Line 399:
====uniform====
====uniform====
Data accessible by shaders.
Data accessible by shaders.
=====name=====


=====type=====
name: the name
bool, int, float, float-vec3, float-vec4, sampler-1d, sampler-2d, sampler-3d, sampler-1d-shadow, sampler-2d-shadow, sampler-cube
 
type: bool, int, float, float-vec3, float-vec4, sampler-1d, sampler-2d, sampler-3d, sampler-1d-shadow, sampler-2d-shadow, sampler-cube


====alpha-test====
====alpha-test====


=====active=====
active: true, false
true, false


=====comparison=====
comparison: never, less, equal, lequal, greater, notequal, gequal, always
never, less, equal, lequal, greater, notequal, gequal, always


=====reference=====
reference: 0 to 1
?


====render-bin====
====render-bin====
Sent to OSG.
Sent to OSG.
=====bin-number=====


=====bin-name=====
bin-number: This is an integer defining the order stuff will be rendered in, it can be negative also.
RenderBin, DepthSortedBin
 
bin-name: RenderBin, DepthSortedBin
 
====rendering-hint====
Sent to OSG.
 
default, opaque, transparent
 
This basically just sets Renderbin:
 
opaque = bin 10, depthsortedbin
 
transparent = bin 0, renderbin
 
default = inherit renderbin details from parent node


====program====
====program====
Line 212: Line 441:
* geometry-output-type - points, line-strip, triangle-strip
* geometry-output-type - points, line-strip, triangle-strip


===Generate===
example:
 
Often shader effects need tangent vectors to work properly. These
tangent vectors, usually called tangent and binormal, are computed
on the CPU and given to the shader as vertex attributes. These
vectors are computed on demand on the geometry using the effect if
the 'generate' clause is present in the effect file. Exemple :
 
<syntaxhighlight lang="xml">
<generate>
<tangent type="int">6</tangent>
<binormal type="int">7</binormal>
<normal type="int">8</normal>
</generate>
</syntaxhighlight>
 
Valid subnodes of 'generate' are 'tangent', 'binormal' or 'normal'.
The integer value of these subnode is the index of the attribute
that will hold the value of the vec3 vector.
 
The generate clause is located under PropertyList in the xml file.
 
In order to be available for the vertex shader, these data should
be bound to an attribute in the program clause, like this :


<syntaxhighlight lang="xml">
<syntaxhighlight lang="xml">
<program>
<program>
<vertex-shader>my_vertex_shader</vertex-shader>
<vertex-shader n="0">Shaders/lcd.vert</vertex-shader>
<attribute>
<fragment-shader n="0">Shaders/lcd.frag</fragment-shader>
<name>my_tangent_attribute</name>
<fragment-shader n="1">Shaders/noise.frag</fragment-shader>
<index>6</index>
<fragment-shader n="2">Shaders/filters-ALS.frag</fragment-shader>
</attribute>
</program>
<attribute>
<name>my_binormal_attribute</name>
<index>7</index>
</attribute>
</program>
</syntaxhighlight>
</syntaxhighlight>


attribute names are whatever the shader use. The index is the one
See this page for more about shaders: [[Howto:Shader programming in FlightGear]]
declared in the 'generate' clause. So because generate/tangent has
value 6 and my_tangent_attribute has index 6, my_tangent_attribute
holds the tangent value for the vertex.


=Uniforms passed to shaders outside the xml effect framework=
=Uniforms passed to shaders outside the xml effect framework=
mat4 osg_ViewMatrixInverse
mat4 osg_ViewMatrix
vec2 fg_BufferSize


float osg_SimulationTime
{| class="wikitable"
!Name
!Type
!Purpose
|-
|<tt>fg_ViewMatrix</tt>
|<tt>mat4</tt>
|In fullscreen pass only, view matrix used to transform from world to view space. Same as osg_ViewMatrix, but for fullscreen pass.
|-
|<tt>fg_ViewMatrixInverse</tt>
|<tt>mat4</tt>
|In fullscreen pass only, view matrix inverse used to transform from view to world space. Same as osg_ViewMatrixInverse but for fullscreen pass.
|-
|<tt>fg_ProjectionMatrixInverse</tt>
|<tt>mat4</tt>
|In fullscreen pass only, projection matrix inverse
|-
|<tt>fg_CameraPositionCart</tt>
|<tt>vec3</tt>
|Position of the camera in world space, expressed in cartesian coordinates
|-
|<tt>fg_CameraPositionGeod</tt>
|<tt>vec3</tt>
|Position of the camera in world space, expressed in geodesic coordinates (longitude in radians, latitude in radians, elevation in meters)
|-
|<tt>fg_SunAmbientColor</tt>
|<tt>vec4</tt>
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.
|-
|<tt>fg_SunDiffuseColor</tt>
|<tt>vec4</tt>
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.
|-
|<tt>fg_SunSpecularColor</tt>
|<tt>vec4</tt>
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.
|-
|<tt>fg_SunDirection</tt>
|<tt>vec3</tt>
|For fullscreen pass only, sun information as lightsource[0] is not available in fullscreen pass.
|-
|<tt>fg_FogColor</tt>
|<tt>vec4</tt>
|
|-
|<tt>fg_FogDensity</tt>
|<tt>float</tt>
|
|-
|<tt>fg_ShadowNumber</tt>
|<tt>int</tt>
|
|-
|<tt>fg_ShadowDistances</tt>
|<tt>vec4</tt>
|
|-
|<tt>fg_DepthInColor</tt>
|<tt>bool</tt>
|Tells if the depth is stored in a depth texture or a color texture
|-
|<tt>fg_Planes</tt>
|<tt>vec3</tt>
|Used to convert the value of the depth buffer to a depth that can be used to compute the eye space position of the fragment
|-
|<tt>fg_BufferSize</tt>
|<tt>vec2</tt>
|Dimensions of the buffer, used to convert gl_FragCoord into the range [0..1][0..1]
|-
|<tt>osg_ViewMatrix</tt>
|<tt>mat4</tt>
|Defined by OSG, used only when working on actual geometry. Transforms from world to view space.
|-
|<tt>osg_ViewMatrixInverse</tt>
|<tt>mat4</tt>
|Defined by OSG, used only when working on actual geometry. Transforms from view to world space.
|-
|<tt>osg_SimulationTime</tt>
|<tt>float</tt>
|Defined by OSG
|-
|<tt>osg_FrameTime</tt>
|<tt>float</tt>
|Defined by OSG
|-
|<tt>osg_DeltaFrameTime</tt>
|<tt>float</tt>
|Defined by OSG
|-
|<tt>osg_FrameTime</tt>
|<tt>float</tt>
|Defined by OSG
|-
|<tt>osg_FrameNumber</tt>
|<tt>int</tt>
|Defined by OSG
|}


[[Category:Shader development]]
[[Category:Shader development]]
574

edits

Navigation menu