Skip to content

Instantly share code, notes, and snippets.

@zlrc
Last active November 22, 2023 00:48
Show Gist options
  • Save zlrc/833e4e2a2d2a32d9dd805231c135ba2e to your computer and use it in GitHub Desktop.
Save zlrc/833e4e2a2d2a32d9dd805231c135ba2e to your computer and use it in GitHub Desktop.
Configurable fragment shader for drawing equipotential lines. Demo: https://www.shadertoy.com/view/NlVfRD
// Electric Potential-inspired Fragment Shader
// Author: Mike "ZiRC" K.
// Demo: https://www.shadertoy.com/view/NlVfRD
//
// Works off of "Contour lines" by 8x as a starting point (most of the original code has been modified):
// https://www.shadertoy.com/view/lltBWM
//
// This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License
// Information about the license can be found here: http://creativecommons.org/licenses/by-nc-sa/4.0/
#version 300 es
precision highp float;
#define K 8.987551788 // coulomb's constant
#define LINE_THICKNESS 0.1 // thickness of the equipotential lines
#define BLUR_AMOUNT 0.15 // the amount of blurring / anti-aliasing applied to the lines def 0.1
#define HEIGHT_CUTOFF 5.10 // maximum electric potential to draw lines for (absolute value)
#define NUM_CHARGES 8
uniform vec3 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform vec3 scaleFactor; // the amount to scale charge values by
uniform vec3 fgColor; // foreground (line) color
uniform vec3 bgColor; // background color
/**
* The charges array, stores x and y position as
* texture coordinates (between 0 and 1), while
* z is the charge value (q) in coulombs.
*/
uniform vec3[NUM_CHARGES] charges;
out vec4 outColor;
/** Calculates electric potential at a point */
float potential(float q, float r) {
return K * (q / r);
}
/** Main shader function */
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord; // the pixel's coordinates
float radius = LINE_THICKNESS * 0.5;
// Calculating electric potential at that point
float z = 0.;
for (int i = 0; i < charges.length(); i++) {
vec3 c = charges[i] * scaleFactor;
float r = distance(c.xy, uv.xy);
z += potential(c.z, r);
}
// Clamp to the height cutoff
z = clamp(z, -HEIGHT_CUTOFF, HEIGHT_CUTOFF);
// Draw gradients from line-edge to line-edge
float d = fract(z+0.1) - radius; // distance from the edge (line's middle is where z is a whole number)
if(d > 0.5) d = 1. - d - radius; // assures that it's distance from the /nearest/ edge
d = d/(fwidth(z)+radius)/BLUR_AMOUNT; // dampens the length of the gradient
// Clamp the value of 'd' between 0 and 1
d = clamp(d, 0., 1.);
// Assign the color
vec4 fg = vec4(fgColor, 1.);
vec4 bg = vec4(bgColor, 1.);
fragColor = mix(fg, bg, vec4(d));
}
void main() {
mainImage(outColor, gl_FragCoord.xy);
}
@zlrc
Copy link
Author

zlrc commented Nov 22, 2023

Video Demo:

eqp_thumbnail.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment