Board index FlightGear Development Effects and shaders

LCD/LED shader for cockpit displays

An exciting "new" option in FlightGear, that includes reflections, lightmaps, the particle system etc.. A lot is yet to be discovered/implemented!

LCD/LED shader for cockpit displays

Postby Necolatis » Sun Oct 01, 2017 11:40 am

Hello,

I made a shader for LCD/LED displays.

Replace the JA37 folder references in the effect file to if you want to test as I haven't applied it to any aircraft yet. Notice some folder references are buried halfway down the effect file.

Features and missing features
- It tries to recreate the color distortion and inversion of brightness of old LCDs when viewed from an angle (sorta works like a negative). At very big angles it can be set to go dark. So no more peeking from co-pilots seat to pilots displays if the displays are old LCDs.
- It attempts to play nice with ALS filters.
- Should work for both Canvas displays or static texture displays.
- You will probably need to tune material values in your AC file. The lightning like ambient / diffuse / specular is added, not modulated in any way with the display output. Only emission is modulated with the actual texture colors.
I used: MATERIAL "screen" rgb 0.0 0.0 0.0 amb 0.000 0.000 0.000 emis 0.000 0.000 0.000 spec 0.5 0.5 0.5 shi 96 trans 0.000
- It probably only supports geometry loaded from AC files due to not taking vertex color into account.
- To turn up the brightness, just make a normal material animation and turn up the emission.
- No Rembrandt support yet.
- Doesn't work with display textures or materials that has transparency.
- No moonlight lightning yet.
- No secondary ALS lights yet.

Some feedback would be nice, both for how you think it works, and for the code itself. Or if there is bugs or something it does not play well with.

Its a work in progress, but if it ends up being usable, then next plan is to make CRT display shader.

Notice that I don't own an old LCD display so I could not investigate how it works, but luckily a friend gave me advice on how the colors distort.

Some pics, please note that this display as its mostly one tone of medium grey don't show the brightness inversion very good, but it does show the color distortion:

Image

Image

lcd.eff
Code: Select all
<!--
License: GPL v2
Author: Nikolai V. Chr.
-->
<PropertyList>
   <name>Aircraft/JA37/Models/Effects/displays/lcd</name>
   <parameters>
      <inner-angle type="float">35</inner-angle><!-- 0-90, use 90 for LED or plasma display-->
      <outer-angle type="float">60</outer-angle><!-- 0-90, but greater than inner -->
      <black-angle type="float">80</black-angle><!-- 0-90, but greater than outer -->

      



      <texture n="0">
         <type>white</type>
      </texture>

      <vertex-program-two-side type="bool">false</vertex-program-two-side>
      <material>
         <color-mode-uniform>1</color-mode-uniform>
      </material>
      <material-id>0</material-id>
      <use-als><use>/sim/rendering/shaders/skydome</use></use-als>
      <rendering-hint>opaque</rendering-hint>
      <transparent>false</transparent>
      <render-bin>
         <bin-number>1</bin-number>
         <bin-name>RenderBin</bin-name>
      </render-bin>
      <shade-model>smooth</shade-model>

      <use_filtering><use>/sim/rendering/als-filters/use-filtering</use></use_filtering>
          <gamma><use>/sim/rendering/als-filters/gamma</use></gamma>
          <brightness><use>/sim/rendering/als-filters/brightness</use></brightness>
          <delta_T><use>/environment/surface/delta-T-structure</use></delta_T>
      <fact_grey><use>/sim/rendering/als-filters/grey-factor</use></fact_grey>
               <fact_black><use>/sim/rendering/als-filters/black-factor</use></fact_black>
          <use_night_vision><use>/sim/rendering/als-filters/use-night-vision</use></use_night_vision>
          <use_IR_vision><use>/sim/rendering/als-filters/use-IR-vision</use></use_IR_vision>
      <display_xsize><use>/sim/startup/xsize</use></display_xsize>
      <display_ysize><use>/sim/startup/ysize</use></display_ysize>
   </parameters>
   <technique n="5">
      <predicate>
         <and>
            <property>/sim/rendering/shaders/quality-level</property>
            <property>/sim/rendering/shaders/model</property>
            <or>
               <less-equal>
                  <value type="float">2.0</value>
                  <glversion/>
               </less-equal>
               <and>
                  <extension-supported>GL_ARB_shader_objects</extension-supported>
                  <extension-supported>GL_ARB_shading_language_100</extension-supported>
                  <extension-supported>GL_ARB_vertex_shader</extension-supported>
                  <extension-supported>GL_ARB_fragment_shader</extension-supported>
               </and>
            </or>
         </and>
       </predicate>
      <pass>
         <lighting>true</lighting>
         <material>
            <active>
               <use>material/active</use>
            </active>
            <ambient>
               <use>material/ambient</use>
            </ambient>
            <diffuse>
               <use>material/diffuse</use>
            </diffuse>
            <specular>
               <use>material/specular</use>
            </specular>
            <emissive>
               <use>material/emissive</use>
            </emissive>
            <shininess>
               <use>material/shininess</use>
            </shininess>
            <color-mode>
               <use>material/color-mode</use>
            </color-mode>
         </material>
         <blend>
            <active>
               <use>blend/active</use>
            </active>
            <source>
               <use>blend/source</use>
            </source>
            <destination>
               <use>blend/destination</use>
            </destination>
         </blend>
         <shade-model>
            <use>shade-model</use>
         </shade-model>
         <cull-face>
            <use>cull-face</use>
         </cull-face>
         <rendering-hint>
            <use>rendering-hint</use>
         </rendering-hint>
         <blend>
            <use>transparent</use>
         </blend>
         <alpha-test>
            <use>transparent</use>
         </alpha-test>
         <render-bin>
            <bin-number>
               <use>render-bin/bin-number</use>
            </bin-number>
            <bin-name>
               <use>render-bin/bin-name</use>
            </bin-name>
            </render-bin>
            <!-- Albedo texture unit-->
         <texture-unit>
            <unit>0</unit>
            <image>
               <use>texture[0]/image</use>
            </image>
            <type>
               <use>texture[0]/type</use>
            </type>
            <filter>
               <use>texture[0]/filter</use>
            </filter>
            <wrap-s>
               <use>texture[0]/wrap-s</use>
            </wrap-s>
            <wrap-t>
               <use>texture[0]/wrap-t</use>
            </wrap-t>
            <internal-format>
               <use>texture[0]/internal-format</use>
            </internal-format>
            </texture-unit>
            <vertex-program-two-side>
               <use>vertex-program-two-side</use>
         </vertex-program-two-side>
         <program>
            <vertex-shader n="0">Aircraft/JA37/Models/Effects/displays/lcd.vert</vertex-shader>
            <fragment-shader n="0">Aircraft/JA37/Models/Effects/displays/lcd.frag</fragment-shader>
            <fragment-shader n="1">Shaders/noise.frag</fragment-shader>
            <fragment-shader n="2">Shaders/filters-ALS.frag</fragment-shader>
         </program>
         <uniform>
            <name>BaseTex</name>
            <type>sampler-2d</type>
            <value type="int">0</value>
         </uniform>
         <uniform>
            <name>innerAngle</name>
            <type>float</type>
            <value>
               <use>inner-angle</use>
            </value>
         </uniform>
         <uniform>
            <name>outerAngle</name>
            <type>float</type>
            <value>
               <use>outer-angle</use>
            </value>
         </uniform>
         <uniform>
            <name>blackAngle</name>
            <type>float</type>
            <value>
               <use>black-angle</use>
            </value>
         </uniform>
         <uniform>
            <name>use_als</name>
            <type>bool</type>
            <value>
               <use>use-als</use>
            </value>
         </uniform>

         <uniform>
                 <name>gamma</name>
                 <type>float</type>
                 <value><use>gamma</use></value>
               </uniform>
               <uniform>
                 <name>brightness</name>
                 <type>float</type>
                 <value><use>brightness</use></value>
               </uniform>
               <uniform>
                 <name>use_filtering</name>
                 <type>bool</type>
                 <value><use>use_filtering</use></value>
               </uniform>
               <uniform>
                    <name>use_night_vision</name>
                   <type>bool</type>
                       <value><use>use_night_vision</use></value>
                 </uniform>
                 <uniform>
                    <name>use_IR_vision</name>
                 <type>bool</type>
                    <value><use>use_IR_vision</use></value>
                  </uniform>
                 <uniform>
                 <name>delta_T</name>
                 <type>float</type>
                 <value><use>delta_T</use></value>
                  </uniform>
            <uniform>
            <name>fact_grey</name>
            <type>float</type>
            <value><use>fact_grey</use></value>
            </uniform>
            <uniform>
            <name>fact_black</name>
            <type>float</type>
            <value><use>fact_black</use></value>
            </uniform>
         <uniform>
              <name>display_xsize</name>
              <type>int</type>
              <value><use>display_xsize</use></value>
         </uniform>
            <uniform>
              <name>display_ysize</name>
              <type>int</type>
              <value><use>display_ysize</use></value>
         </uniform>
      </pass>
   </technique>
</PropertyList>


lcd.vert
Code: Select all
// Author: Nikolai V. Chr.
// License: GPL v2
#version 120

varying   vec3   VNormal;
varying vec3    eyeVec;

void main(void) {
      vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
      eyeVec = ecPosition.xyz;

      VNormal = normalize(gl_NormalMatrix * gl_Normal);

      gl_Position = ftransform();
      gl_ClipVertex = ecPosition;
      gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}


lcd.frag
Code: Select all
// Author: Nikolai V. Chr.
// License: GPL v2
#version 120

varying vec3    VNormal;
varying vec3    eyeVec;

uniform sampler2D BaseTex;
uniform float innerAngle;//inside this angle the display is perfect
uniform float outerAngle;//from inner to outer the display gets more color distorted.
uniform float blackAngle;//from outer to this angle the display gets more black. From this angle to 90 the display stays black.
uniform int use_als;

const vec4  kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);
const vec4  kRGBToI     = vec4 (0.596, -0.275, -0.321, 0.0);
const vec4  kRGBToQ     = vec4 (0.212, -0.523, 0.311, 0.0);

const vec4  kYIQToR   = vec4 (1.0, 0.956, 0.621, 0.0);
const vec4  kYIQToG   = vec4 (1.0, -0.272, -0.647, 0.0);
const vec4  kYIQToB   = vec4 (1.0, -1.107, 1.704, 0.0);

vec3 filter_combined (in vec3 color) ;

vec3 rotateHue (in vec4 color) {
    // Convert to YIQ
    float   YPrime  = dot (color, kRGBToYPrime);
    float   I      = dot (color, kRGBToI);
    float   Q      = dot (color, kRGBToQ);

    // Calculate the hue and chroma
    float   hue     = atan (Q, I);
    float   chroma  = sqrt (I * I + Q * Q);

    // Make the adjustment
    hue += radians(180.0);
    YPrime = 1 - YPrime;

    // Convert back to YIQ
    Q = chroma * sin (hue);
    I = chroma * cos (hue);

    // Convert back to RGB
    vec4    yIQ   = vec4 (YPrime, I, Q, 0.0);
    color.r = dot (yIQ, kYIQToR);
    color.g = dot (yIQ, kYIQToG);
    color.b = dot (yIQ, kYIQToB);

    // reduce contrast by alot
    color.rgb = ((color.rgb - vec3(0.5,0.5,0.5)) * vec3(0.15,0.15,0.15)) + vec3(0.5,0.5,0.5);

    return color.rgb;
}

// todo: rembrandt and stuff

void main (void) {
    vec3 gamma      = vec3(1.0/2.2);// standard monitor gamma correction
    vec3 gammaInv   = vec3(2.2);
    vec4 texel      = texture2D(BaseTex, gl_TexCoord[0].st);   

    vec3 eye = normalize(-eyeVec);
    vec3 N  = normalize(VNormal);
    float angle = degrees(acos(dot(N,eye)));//angle between normal and viewer
    vec3 color = vec3(0.0,0.0,0.0);
    if (angle <= innerAngle) {
        color = texel.rgb;
    } else if (angle <= outerAngle) {
        vec3 hsl = rotateHue(texel);
        float amount = (angle - innerAngle)/(outerAngle-innerAngle);
        color = mix(texel.rgb, hsl, amount);
    } else if (angle <= blackAngle) {
        vec3 hsl = rotateHue(texel);
        float amount = (angle - outerAngle)/(blackAngle-outerAngle);
        color = mix(hsl, vec3(0,0,0), amount);
    }
    color = pow(color, gammaInv);
    color = color * gl_FrontMaterial.emission.rgb;

    float phong = 0.0;
    vec3 Lphong = normalize(gl_LightSource[0].position.xyz);
    if (dot(N, Lphong) > 0.0) {
        // lightsource is not behind
        vec3 Rphong = normalize(-reflect(Lphong,N));
        phong = pow(max(dot(Rphong,eye),0.0),gl_FrontMaterial.shininess);
        phong = clamp(phong, 0.0, 1.0);
    }
    vec4 specular = gl_FrontMaterial.specular * gl_LightSource[0].diffuse * phong;
    vec3 ambient = gl_FrontMaterial.ambient.rgb * gl_LightSource[0].ambient.rgb * gl_LightSource[0].ambient.rgb * 2;//hack but works, pitch black at night. :)

    vec3 L = normalize((gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz);
    N = normalize((gl_ModelViewMatrixTranspose * vec4(N,0.0)).xyz);
    float nDotVP = dot(N,L);
    nDotVP = max(0.0, nDotVP);
    vec3 diffuse = gl_FrontMaterial.diffuse.rgb * gl_LightSource[0].diffuse.rgb * nDotVP;

    color = clamp(color+specular.rgb+ambient+diffuse, 0, 1);

    if (use_als > 0) {
        gl_FragColor = vec4(filter_combined(pow(color,gamma)), 0.0);
    } else {
        gl_FragColor = vec4(pow(color,gamma), 0.0);
    }
}


Edit: Now also reduces contrast. Code updated. And added some screenies below of reduced contrast at angle:

Image

Image
Last edited by Necolatis on Sun Oct 01, 2017 1:06 pm, edited 2 times in total.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 1999
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2019.1.2
OS: Windows 10

Re: LCD/LED shader for cockpit displays

Postby Thorsten » Sun Oct 01, 2017 11:57 am

Hm... as it happens, I have this display effect in the pipeline (currently with the Shuttle for testing and evaluation, scheduled to go to FGData in this release cycle).

Image

It'd be rather easy to add the color trafos with angle as a simple option. In particular, it already has the correct interaction with the interior shadowing via opacity maps (which is really one of the most pronounced effects in my view).

Edit: I knew I had it somewhere - I mean this

Image
Thorsten
 
Posts: 11133
Joined: Mon Nov 02, 2009 8:33 am

Re: LCD/LED shader for cockpit displays

Postby Necolatis » Sun Oct 01, 2017 12:13 pm

I am sad cause I used alot of time doing my first shader from the bottom, and you made something better.
I am happy cause we are going to get something cool added to flightgear.
Oh well. :)

Does it do CRT displays as well?
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 1999
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2019.1.2
OS: Windows 10

Re: LCD/LED shader for cockpit displays

Postby Thorsten » Sun Oct 01, 2017 12:27 pm

Does it do CRT displays as well?


I've mainly focused on perception effects - bloom and color desaturation for low ambient light, extinction of contrast for high ambient light.

So I suspect it does none of the specific transformations you have in mind, which is why I would propose to add them as option-switchable color transformations (I don't know what you specifically want to do for a CRT display).
Thorsten
 
Posts: 11133
Joined: Mon Nov 02, 2009 8:33 am

Re: LCD/LED shader for cockpit displays

Postby Icecode GL » Sun Oct 01, 2017 12:39 pm

I am sad cause I used alot of time doing my first shader from the bottom, and you made something better.


I worked on shadows for a few months before Rembrandt came by, but I learned A LOT in the process. No time is wasted when you are learning at the same time. :)
Icecode GL
 
Posts: 541
Joined: Thu Aug 12, 2010 12:17 pm
Location: Spain
Callsign: icecode
Version: GIT
OS: Arch Linux

Re: LCD/LED shader for cockpit displays

Postby Necolatis » Sun Oct 01, 2017 12:41 pm

I searched if somebody had already made a GPL GLSL CRT effect.
It turns out there is plenty out there on retro websites. Not sure any of them were meant to be used on textures in 3D world though.
I was planning to investigate them further and see if I could adapt one of them to work in FG. If its not too heavy for performance.

Here is an example of what one of them can do: http://mame32fx.altervista.org/forum/viewtopic.php?t=184

With maybe just half of those features, it would still be pretty cool.

Here is a bunch of them: https://github.com/libretro/glsl-shaders/tree/master/crt
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 1999
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2019.1.2
OS: Windows 10

Re: LCD/LED shader for cockpit displays

Postby Thorsten » Sun Oct 01, 2017 12:58 pm

I'm still not quite sure what specifically you want to do. We can sure bend the texture coordinates with a transformation, but, well, if you have a non-planar screen, you can actually model it in 3d, so what's the point?

Or are you after the pixely appearance? That's not too hard to do either.

(I'd much prefer to get an idea of the desired features rather than finished code, because it probably takes me 10 times as long to understand code I am not familiar with than to come up with code that merges into what we have - unless the problem is really tough of course...)
Thorsten
 
Posts: 11133
Joined: Mon Nov 02, 2009 8:33 am

Re: LCD/LED shader for cockpit displays

Postby Necolatis » Sun Oct 01, 2017 1:01 pm

Makes sense, will think about it, did not think it fully through as I planned it after doing LCD/LED display.
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 1999
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2019.1.2
OS: Windows 10

Re: LCD/LED shader for cockpit displays

Postby legoboyvdlp » Sun Oct 01, 2017 3:30 pm

The CRT sprt of looks kind of like it is glass over an image, it is hard to describe, but that is how it looks to me from videos and images.

It would be useful for the A320.
User avatar
legoboyvdlp
 
Posts: 7124
Joined: Sat Jul 26, 2014 1:28 am
Callsign: YV-LEGO
Version: 2018.3.1
OS: Windows 10 HP

Re: LCD/LED shader for cockpit displays

Postby Octal450 » Sun Oct 01, 2017 3:42 pm

This is for Canvas I assume, so could use it, yes.

Kind Regards,
Josh
Waste of time. Goodbye forever.
Octal450
 
Posts: 4398
Joined: Tue Oct 06, 2015 12:51 pm

Re: LCD/LED shader for cockpit displays

Postby Thorsten » Sun Oct 01, 2017 4:31 pm

@Necolatis:

If you want to experiment

https://sourceforge.net/p/fgspaceshuttl ... isplay.eff

https://sourceforge.net/p/fgspaceshuttl ... htmap.vert
https://sourceforge.net/p/fgspaceshuttl ... splay.frag

(Well, that's the extended space shader family, the Rolls Royce among the shaders - but they'll process aircraft fine :mrgreen: )
Thorsten
 
Posts: 11133
Joined: Mon Nov 02, 2009 8:33 am

Re: LCD/LED shader for cockpit displays

Postby Necolatis » Sun Oct 01, 2017 5:01 pm

Cool. So you use 12 lightmaps? Is that one for each light source in the shuttle cockpit?
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 1999
Joined: Mon Oct 29, 2012 12:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2019.1.2
OS: Windows 10

Re: LCD/LED shader for cockpit displays

Postby Thorsten » Sun Oct 01, 2017 5:40 pm

Yep - Wayne had made it his personal goal to make the lighting perfect, so we extended the shader to support the necessary amount of lightmaps.
Thorsten
 
Posts: 11133
Joined: Mon Nov 02, 2009 8:33 am

Re: LCD/LED shader for cockpit displays

Postby PINTO » Sun Oct 01, 2017 10:58 pm

I am a shader noob, so please forgive the fact that this is a question out of ignorance.

Would it be possible to extend it to an arbitrary amount of light maps? The MiG-21bis has over 30 lights on the front panel alone, and I'd like to do this accurately as well. I'm also not sure about the performance hit of so many light maps?
Actively developing the MiG-21bis (github repo) (forum thread) (dev discord) (fg wiki)

http://opredflag.com is an active flightgear dogfighting community (using a system that isn’t bombable)
User avatar
PINTO
 
Posts: 945
Joined: Wed Oct 21, 2015 6:28 pm
Callsign: pinto
Version: 2016.3.0
OS: Win10

Re: LCD/LED shader for cockpit displays

Postby Thorsten » Mon Oct 02, 2017 3:59 am

No - you can cram four lights into one texture, and we have eight textures max (including everything - specular, normal, opacity,...) mapping, so there's a limit dependent on what else the effect ought to do.

Okay - you could then think of compressing information and decoding it later, then you can pack more, but this gets ugly quickly.

The MiG-21bis has over 30 lights on the front panel alone


We're not talking front panel lights here - we're talking lights designed to illuminate the whole flightdeck - which is why you need 12 lightmaps for every point in there, because all these lights can affect it. Panel lights I just merged into the ambience model (they're unlikely to be treated well by the raytracer anyway).

A local light which doesn't illuminate the rest of the cabin can have its own effect for its own bit of surface around it, and then you can have a lot of bang for the buck even with just four channels.
Thorsten
 
Posts: 11133
Joined: Mon Nov 02, 2009 8:33 am

Next

Return to Effects and shaders

Who is online

Users browsing this forum: No registered users and 2 guests