(Demo) Electrical Arc


GeeXLab - Electrical arc effect - gamedev



Here is a simple demo that shows how to code an electrical arc. The principle is very simple. It only requires a quad, a pixel shader and a noise texture.

The demo requires GeeXLab 0.27.3+. As usual, download the demo, unzip it somewhere and drag an drop the main.xml file into GeeXLab.

Let’s see the important steps to render the electrical arc. The entire work is done in the pixel shader. But it costs nothing to give the vertex shader:

#version 120
void main()
{
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;		
  gl_TexCoord[0] = gl_MultiTexCoord0;
}

 
As you see, it’s a very basic OpenGL 2.1 vertex shader. Why I still use OpenGL 2.1 today when everyone talks about DXR, DX12, Vulkan and the end of OpenGL? The answer is simple: Raspberry Pi… And because OpenGL 2.1 still does the job perfectly (at least for that kind of effect)!

Now let’s look at the pixel shader.





 

1 – Render a vertical band

The first step is to render a vertical band with a specific width defined by the line_size uniform. The background color is defined by bkgcolor. The band is horizontally centered that’s why we test against 0.5:

#version 120
uniform float line_size;
uniform vec4 bkgcolor;

void main (void)
{
  vec2 uv = gl_TexCoord[0].xy;
  vec3 c = bkgcolor.rgb;

  if ((uv.x > 0.5 - line_size) && (uv.x < 0.5 + line_size))
  {
    c = vec3(1.0);
  }

  gl_FragColor = vec4(c, 1.0);
}

 
Here is the result with line_size=0.1:


GeeXLab - Electrical arc effect - gamedev

 
But for a nice effect, line_size will be set top 0.005:


GeeXLab - Electrical arc effect - gamedev

 

2 - Adding some noise

The noise is fetched from the following texture:


GeeXLab - Electrical arc effect - noise texture

 
This step is the core of the electrical arc effect. We fetch the noise texture (into noise), then we compute a value (lsize) in the [-1.0 ; 1.0] range. But since [-1.0 ; 1.0] is a bit too large, we scale down the value by noise_scale.

The arc animation is done by playing with texture coordinates (uv2).

arc_x will allow to move the electrical arc. The default value is 0.5 (center of the screen).

#version 120
uniform sampler2D tex0;
uniform float line_size;
uniform float time;
uniform float arc_x;
uniform float noise_scale;
uniform vec4 bkgcolor;

void main (void)
{
  vec2 uv = gl_TexCoord[0].xy;
  vec3 c = bkgcolor.rgb;

  vec2 uv2 = uv*vec2(1.0, 2.0) + vec2(time*0.8, time*0.8);
  float noise = texture2D(tex0,uv2).r;

  float lsize =  ((noise*2.0) - 1.0) * noise_scale;

  if ((uv.x > arc_x - (line_size + lsize)) && (uv.x < arc_x + (line_size - lsize)))
  {
    c = vec3(1.0);
  }

  gl_FragColor = vec4(c, 1.0);
}

 
And the result:


GeeXLab - Electrical arc effect - gamedev

 

3 - Adding some color

The final touch is to add some color to the white arc (even if a white electrical arc is perfect).

Here is the final electrical arc pixel shader:

#version 120
uniform sampler2D tex0;
uniform float line_size;
uniform float time;
uniform float arc_x;
uniform float noise_scale;
uniform vec4 bkgcolor;
uniform vec4 arc_color1;
uniform vec4 arc_color2;

void main (void)
{
  vec2 uv = gl_TexCoord[0].xy;
  vec3 c = bkgcolor.rgb;

  vec2 uv2 = uv*vec2(1.0, 2.0) + vec2(time*0.8, time*0.8);
  float noise = texture2D(tex0,uv2).r;

  float lsize =  ((noise*2.0) - 1.0) * noise_scale;

  if ((uv.x > arc_x - (line_size + lsize)) && (uv.x < arc_x + (line_size - lsize)))
  {
    c = mix(arc_color1.rgb, arc_color2.rgb, uv.y);
  }

  gl_FragColor = vec4(c, 1.0);
}

 


GeeXLab - Electrical arc effect - gamedev





Leave a Comment

Your email address will not be published. Required fields are marked *