Howto:Shader programming in FlightGear: Difference between revisions

Jump to navigation Jump to search
no edit summary
No edit summary
No edit summary
Line 347: Line 347:
= A Practical Application in [[Flightgear]] =
= A Practical Application in [[Flightgear]] =


== ALS Landing Lights \ Spotlight ==
== ALS Landing Lights - Spotlight ==
[[File:als secondary light.png|640px|thumbnail|Proof of Concept]]
[[File:als secondary light.png|640px|thumbnail|Proof of Concept]]
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 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.


In the case of ALS Lights, you have to add the effect to every visual item rendered on the screen that you want to see a light shining on. If you want it to be capable of shining on everything, you have to account for each separate item and how that item is rendered.  That is a lot of code to touch.
In the case of ALS Lights, you have to add the effect to every visual item rendered on the screen that you want to see a light shining on. If you want it to be capable of shining on everything, you have to account for each separate item and how that item is rendered.  That is a lot of code to touch.
Line 429: Line 429:
==== Uniforms ====
==== Uniforms ====
The uniforms section is the mechanism that feeds the parameter data to the shader program.
The uniforms section is the mechanism that feeds the parameter data to the shader program.
  <uniform>
  <small><uniform>
   <name>view_pitch_offset</name>
   <name>view_pitch_offset</name>
   <type>float</type>
   <type>float</type>
Line 478: Line 478:
   <type>int</type>
   <type>int</type>
   <value><use>display_ysize</use></value>
   <value><use>display_ysize</use></value>
  </uniform>  
  </uniform></small>
Note the name, "use_searchlight", which was originally defined in preferences.xml 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 Program ===
=== Shader Program ===
The shader programs used in this example are "tree-ALS.frag" and "secondary_lights.frag".
"secondary_lights.frag" consists of
*uniform inputs (data coming into the shader to be manipulated
*functions that manipulate the uniform data
Following it the actual GLSL code involved.
==== Uniform Input ====
==== Uniform Input ====
uniform int display_xsize;
uniform int display_ysize;
uniform float field_of_view;
uniform float view_pitch_offset;
uniform float view_heading_offset;
==== Functions ====
float light_distance_fading(in float dist)
{
  return min(1.0, 10000.0/(dist*dist));
}
float fog_backscatter(in float avisibility)
{
  return 0.5* min(1.0,10000.0/(avisibility*avisibility));
}
vec3 searchlight()
{
  vec2 center = vec2 (float(display_xsize) * 0.5, float(display_ysize) * 0.4);
  float headlightIntensity; 
  float lightRadius = (float(display_xsize) *9.16 /field_of_view);
  float angularDist = length(gl_FragCoord.xy -center);
  if (angularDist < lightRadius)
  {
    headlightIntensity = pow(cos(angularDist/lightRadius * 1.57075),2.0);
    //headlightIntensity = headlightIntensity *
    //headlightIntensity*= clamp(1.0 + 0.15 * log(1000.0/(dist*dist)),0.0,1.0);
    return  headlightIntensity * vec3 (0.5,0.5, 0.5);
  }
  else return vec3 (0.0,0.0,0.0);
}


==== Variable Assignments ====
vec3 landing_light(in float offset)
{
  float fov_h = field_of_view;
  float fov_v = float(display_ysize)/float(display_xsize) * field_of_view;
  float yaw_offset;
  if (view_heading_offset > 180.0)
    {yaw_offset = -360.0+view_heading_offset;}
  else
    {yaw_offset = view_heading_offset;}
  float x_offset = (float(display_xsize) / fov_h * (yaw_offset + offset));
  float y_offset = -(float(display_ysize) / fov_v * view_pitch_offset);
  vec2 center = vec2 (float(display_xsize) * 0.5 + x_offset, float(display_ysize) * 0.4 + y_offset);
  float landingLightIntensity; 
  float lightRadius = (float(display_xsize) *9.16 /field_of_view);
  float angularDist = length(gl_FragCoord.xy -center);
  if (angularDist < lightRadius)
  {
    landingLightIntensity = pow(cos(angularDist/lightRadius * 1.57075),2.0);
    //landingLightIntensity *= min(1.0, 10000.0/(dist*dist));
    return  landingLightIntensity * vec3 (0.5,0.5, 0.5);
  }
  else return vec3 (0.0,0.0,0.0);
}


==== Main Program ====
==== Main Program ====
330

edits

Navigation menu