Jump to: navigation, search

Howto:Shader programming in FlightGear

2,023 bytes added, 20:56, 1 September 2019
Effects file: added link to new page
{{forum|47|Effects & Shaders}}
{{WIP|More to follow}}
This is meant to become an introduction to '''shader programming in FlightGear''', for the time being (03/2010), this is work in progress, please feel free to ask questions or suggest topics.
User defined functions are supported, and a wide variety of commonly used functions are provided built-in as well. This allows the graphics card manufacturer the ability to optimize these built-in functions at the hardware level if they are inclined to do so. Many of these functions are similar to those found in the math library of the C programming language such as <code>exp()</code> and <code>abs()</code> while others are specific to graphics programming such as <code>smoothstep()</code> and <code>texture2D()</code>.
== Error Reports, Debugging, Troubleshooting ==
Shaders are compiled at FG startup.
Shader compilation errors can be found in the fgfs.log file. More about the [[Commonly_used_debugging_tools#fgfs.log|fgfs.log here]].
As of FG 2016.4.4, shaders do not seem to recompile upon Debug/Reload Aircraft Model or File/Reset. So the only option to re-compile/test a shader is to quit a re-start FG altogether.
== Shader types ==
In FlightGear, these files can be found in the <code>Shaders</code> subdirectory of the base package, in essence <code>$FG_ROOT/Shaders</code>.
For a list of currently available shaders, you may want to take a look at:{{fg/fgdata/trees/master/root file|Shaders}}.
So, shaders generally go around in pairs - one shader (the ''vertex shader'') is a short program that takes in one vertex from the main CPU and produces one vertex that is passed on to the GPU rasterizer which uses the vertices to create triangles - which it then chops up into individual pixel-sized fragments.
=== Vertex shaders ===
|The vertex shader doesn't know anything about the mesh it renders, it just knows one single vertex at a time and all the info that is attached to the vertex (normals, tangents, binormals, color,...) And the vertex shader doesn't really draw anything, it just takes care of all the things which have to do with 'where in space' you are.
The way this works is that for all the vertices of an object you want to render, the position of the object gets attached to all vertices (currently in the color spot). The vertex shader then just adds the offset vector to the vertex coordinate with respect to the origin.
|{{cite web |url=
|title=<nowiki>Re: [Flightgear-devel] cities in FG & how to move forward</nowiki>
|author=<nowiki>Renk Thorsten</nowiki>
{| class="wikitable"
! Input
=== Fragment shaders ===
|the fragment shader basically knows only the pixel it is about to render and whatever information is passed from the vertex shader. Based on 'where' the vertex shader says the pixel is, the rasterizer stage determines what the texture for the pixel should be.
But there are techniques to do this in a different way, for instance the water depth map uses world coordinates to look up a world texture, and the gardens would have to be drawn in a similar way.
|{{cite web |url=
|title=<nowiki>Re: [Flightgear-devel] cities in FG & how to move forward</nowiki>
|author=<nowiki>Renk Thorsten</nowiki>
{| class="wikitable"
! Input
== Practical application in FlightGear – ALS landing lights – spotlight ==
[[File:ALS Secondary Light Proof of Concept.png|thumb|300px|ALS secondary light proof of concept]]
[[File:Als Secondary Lights combined with Fog Effect.jpg|thumb|300px|Weather settings to produce fog and ALS landing lights on a runway.]]
[[File:ALS Lights over Model and Terrain.jpg|thumb|300px|ALS lights over model and terrain]]
=== ALS landing lights - spotlight ===
The ALS landing lights-spotlight (we'll call it ALS lights from now on) is a good example for showing how to incorporate a shader effect into FlightGear as it touches many parts of the visuals we see and many parts of the coding pipeline.
The example highlighted in this article is what was added to <code>tree.eff</code> to shine the lights on trees.
==== Program flow simplified ====
Preferences/Nasal/XML → Property tree → Effect file → Shader → Rendered to screen
==== Preferences/Nasal/XML ====
Any combination of Preferences, [[Nasal|Nasal]] or [[Xml|XML]] manipulates data in the [[Property Tree|property tree]].
In this case the switch to turn on the landing or spot light and a couple other needed data containers are defined in <code>$FG_ROOT/preferences.xml</code> with the following lines.
They show up in the property tree under <code>sim/rendering/als-secondary-lights</code> and can be activated or manipulated by normal Nasal calls or XML.
==== Property tree ====
The [[Property Tree|property tree]] is like the CPU of the [[FlightGear]] program at a user level. It's a go-between that allows the user to see and influence many aspects at the heart of the program in ALMOST real time. More of the internals of FlightGear are being exposed to the property tree than ever before. This allows us to have user level access in areas of the code that used to only be reserved for [[Programming Resources|programmers]]. Because of the manner in which the property tree is fed information, and the one step removed from the C source, care must be taken in how it is used. Depending on how it is used it won't be as responsive to manipulation as it would be if you were to change the same information at the C source level.
==== Effects file ====
The effects file is the mechanism we use to combine and manipulate all the necessary data to create stunning visual effects. It's the link between the data contained and produced in Nasal, XML and the property tree and the graphics rendering pipeline. It's there to allow us to create these affects without having to know or use the C++ code base. Its flexible framework allows for an almost infinite range of sophisticated effects.
=See this page for more details: [[Effect Framework]] ==== Parameters =====
Parameter entries defined in the Effect file correspond to a property tree data container (static or variable). They will contain the data needed by the shader program to perform its magic. The type of information contained in the property tree might be program control data or variable/static data that the shader program can manipulate prior to sending on to render.
In the case of ALS lights, below is some of the data passed to, and used by, the shader program.
There will also be other parameter entries that have nothing to do with ALS lights. They might be used for other actions or effects the shader is handling.
===== Technique =====
In general, the shader program and the uniforms are defined in between the technique tags. The technique is assigned an index to distinguish one technique from another (technique n="1"). As is the case with tree.eff, sometimes the shader program and its uniforms are defined and needed in more than one technique. In the case of <code>tree.eff</code> it is used in technique 4 and 5. Which means in FlightGear, the tree shader set to either of the the highest two shader settings still produces ALS lights when activated.
===== Shader program =====
Next comes the entry to define what shader program the parameters data is going to be passed to.
This is where you specify what shader program is to be used by the technique. ALS has the lowest techniques, with higher quality preceding lower quality.
We'll describe the contents of the shader programs below. For now, suffice it to say <code>tree-ALS.frag</code> contains the main program and <code>secondary_lights.frag</code> has functions that are passed uniform data that is manipulated and returned to main for processing.
===== Uniforms =====
The uniforms section is the mechanism that feeds the parameter data to the shader program.
<syntaxhighlight lang="xml">
Note the name, <code>use_searchlight</code>, which was originally defined in <code>preferences.xml</code> and then became an entry in parameters is now being passed to the program shader by the uniform. Below in the "Shader program" section, we will show you how the shader receives the uniform's data.
==== Shader programs ====
The shader programs used in this example are <code>tree-ALS.frag</code> and <code>secondary_lights.frag</code>.
==== secondary_lights.frag ====
<code>secondary_lights.frag</code> consists of
* Uniform inputs (data coming into the shader to be manipulated
Following it the actual GLSL code in <code>secondary_lights.frag</code>.
===== Uniform input =====
<syntaxhighlight lang="glsl">
uniform int display_xsize;
===== Functions =====
<syntaxhighlight lang="glsl">
float light_distance_fading(in float dist)
==== tree-ALS.frag ====
<code>tree-ALS.frag</code> consists of
* Uniform inputs (data coming into the shader to be manipulated
While there is significantly more code in <code>tree-ALS.frag</code>, only the code that was included for the ALS lights is being shown and discussed here.
===== Uniform input =====
Uniform data is brought into the shader in the following manner.
Note <code>use_searchlight</code> and how it is defined as incoming uniform data.
===== Variable data =====
Variable data can be defined in the shader program. An example of variable data defined in the shader program that is needed for ALS lights is
<syntaxhighlight lang="glsl">
===== Functions =====
Function calls to the function defined in <code>secondary_lights.frag</code> are
<syntaxhighlight lang="glsl">
Variable data can be passed to and returned from GLSL functions just like any other language.
===== Main program =====
The <code>main()</code> function is the heart of the shader program. This is where the shader program manipulates all the data made available to it.
<syntaxhighlight lang="glsl">
Some of the variable data contained in the shader program is used for other purposes and is introduced into the shader program from other property, parameter and uniform definitions not pertaining to ALS lights.
===== File list =====
Files that are directly touched by this effect include
* <code>preferences.xml</code>

Navigation menu