[Shader Library] Night Vision Post Processing Filter (GLSL)

Shader Library - Night Vision PostFX

This shader officially starts Geeks3D’s shader library. The Shader Library is the place for all shaders I use in GeeXLab demos. Most of these shaders can be easily used in other softwares like Blender Game Engine for example.

This night vision shader is based on this algorithm with some modifications. I added a simple luminance analysis in order to amplify parts with low luminance.

You can download the demo to see the shader in real time:

Unzip the demo somewhere and run Night_Vision_Demo.exe. That’s all.

You need Python 2.6.3 (2.6.2 is also ok) to run the demo. If you don’t have yet Python, get the Windows installer HERE.

This demo uses GeeXLab. The source code of the night vision filter can be found in the PostFX_Night_Vision_Lib.xml file. The main source code (that is loaded first) is Night_Vision_Demo.xml.

Shader desription

Language: OpenGL 2 – GLSL

Type: Post processing filter.


  • sceneBuffer (sampler2D): the scene buffer.
  • noiseTex (sampler2D): noise texture to add some artifacts to the night vision device. The noise texture comes from this free noise texture pack.
  • maskTex (sampler2D): binocular mask of the night vision device.
  • elapsedTime (float): elapsed time in seconds.
  • luminanceThreshold (float): allows to change the luminance threshold. Default value: 0.2
  • colorAmplification (float): amplification factor for pixels with low luminance. Default value: 4.0
  • effectCoverage (float): effect screen coverage – only for demo needs! Default value: 0.5 (half screen)

Ouputs: color buffer

Shader code:

void main()
  gl_Position = ftransform();		
  gl_TexCoord[0] = gl_MultiTexCoord0;
uniform sampler2D sceneBuffer;
uniform sampler2D noiseTex; 
uniform sampler2D maskTex; 
uniform float elapsedTime; // seconds
uniform float luminanceThreshold; // 0.2
uniform float colorAmplification; // 4.0
uniform float effectCoverage; // 0.5
void main ()
  vec4 finalColor;
  // Set effectCoverage to 1.0 for normal use.  
  if (gl_TexCoord[0].x < effectCoverage) 
    vec2 uv;           
    uv.x = 0.4*sin(elapsedTime*50.0);                                 
    uv.y = 0.4*cos(elapsedTime*50.0);                                 
    float m = texture2D(maskTex, gl_TexCoord[0].st).r;
    vec3 n = texture2D(noiseTex, 
                 (gl_TexCoord[0].st*3.5) + uv).rgb;
    vec3 c = texture2D(sceneBuffer, gl_TexCoord[0].st 
                               + (n.xy*0.005)).rgb;
    float lum = dot(vec3(0.30, 0.59, 0.11), c);
    if (lum < luminanceThreshold)
      c *= colorAmplification; 
    vec3 visionColor = vec3(0.1, 0.95, 0.2);
    finalColor.rgb = (c + (n*0.2)) * visionColor * m;
    finalColor = texture2D(sceneBuffer, 
  gl_FragColor.rgb = finalColor.rgb;
  gl_FragColor.a = 1.0;

Before testing on ATI Radeon, the shader contained this line:

float lum = dot(vec4(0.30, 0.59, 0.11, 0.0), c);

where c is a vec3. NVIDIA GLSL compiler (based on Cg) accepts this instruction.
But Radeon GLSL compiler is strict and doesn't accept this line because it can't compile:

float lum = dot(vec4, vec3);

Little conclusion: always test your shaders on ATI and NVIDIA boards...

Related links and references:

11 thoughts on “[Shader Library] Night Vision Post Processing Filter (GLSL)”

  1. Pingback: Geeks3D – 2009 Retrospective | The Geeks Of 3D - 3D Tech News

  2. Letun

    But I’ll did not use Fragment Shader as a post filter, because it drops fps((
    sorry for my english

  3. JeGX Post Author

    Yes it’s what I saw in your demo. So the shader is executed for every mesh in the mesh ? And don’t worry for your english, it’s perfectly understandable 😉

  4. Letun

    Shader is executed only for those objects, which I refer to the variable ShaderObjects. So can use the scene without lighting

  5. Pingback: Night Vision Post Processing Shader in Blender Game Engine - 3D Tech News, Pixel Hacking, Data Visualization and 3D Programming - Geeks3D.com

  6. Pingback: Real-Time Rendering · 7 Things for February 10

  7. 0x69

    Nice shader !
    However, I would notice that real night vision device amplifies light equally in all luminance ranges (not just the low luminance parts as in this shader).

    Otherwise good shader usage !!!

Comments are closed.