Skip to content

Instantly share code, notes, and snippets.

@ritobanrc
Created June 8, 2019 23:29
Show Gist options
  • Save ritobanrc/a0462be91f00c95f218e73651a066c11 to your computer and use it in GitHub Desktop.
Save ritobanrc/a0462be91f00c95f218e73651a066c11 to your computer and use it in GitHub Desktop.
Some cool shaders I wrote, along with the html files to render them in a WebGL canvas
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
const float iterations = 100.0;
#define PI_TWO 1.570796326794897
#define PI 3.141592653589793
#define TWO_PI 6.283185307179586
void main() {
vec2 c = 10.0/u_time*(gl_FragCoord.xy/u_resolution.xy + vec2(-1, 0.5));
vec2 z = vec2(0.0);
// (a+bi)^2 = a^2 - b^2 + 2i*ab
vec3 color = vec3(0.0);
for (float count = 0.0; count < iterations; count++) {
z = vec2(z.x*z.x - z.y*z.y, 2.0*z.x*z.y) + c;
if (length(z) > 100.0) {
float dist = count/iterations;
color = vec3(dist, 0.0, 0.3-dist);
}
}
gl_FragColor = vec4(color, 1.0);
}
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mandelbrot Fractal Shader</title>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js"></script>
</head>
<body style="background-color:#EEEEFF">
<canvas class="glslCanvas" data-fragment-url="mandelbrot.glsl" width="500" height="500"></canvas>
</body>
</html>
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
const int MAX_STEPS = 100;
const float MIN_DIST = 0.0;
const float MAX_DIST = 100.0;
const float EPSILON = 0.0001;
#define HALF_PI 1.570796326794897
#define PI 3.141592653589793
#define TWO_PI 6.283185307179586
float rounding(in float sdf, in float r) {
return sdf - r;
}
float sphereSDF(vec3 p, float r) {
return length(p) - r;
}
float boxSDF( vec3 p, vec3 b ) {
vec3 d = abs(p) - b;
return length(max(d,0.0))
+ min(max(d.x,max(d.y,d.z)),0.0); // remove this line for an only partially signed sdf
}
float torusSDF( vec3 p, vec2 t ) {
vec2 q = vec2(length(p.xz)-t.x,p.y);
return length(q)-t.y;
}
float sceneSDF(in vec3 p) {
return torusSDF(p, vec2(1.0, 2.0));
}
vec3 estimate_normal(in vec3 p) {
return normalize(vec3(sceneSDF(vec3(p.x + EPSILON, p.y, p.z)) - sceneSDF(vec3(p.x - EPSILON, p.y, p.z)),
sceneSDF(vec3(p.x, p.y + EPSILON, p.z)) - sceneSDF(vec3(p.x, p.y - EPSILON, p.z)),
sceneSDF(vec3(p.x, p.y, p.z + EPSILON)) - sceneSDF(vec3(p.x, p.y, p.z - EPSILON))
));
}
vec3 view_ray_dir(in vec2 fragCoord, in float fov, in vec2 size) {
vec2 xy = fragCoord - size / 2.0; // centering at 0
float z = size.x / tan(radians(fov)/2.0);
return normalize(vec3(xy, z));
}
float ray_march(in vec3 camera, in vec3 viewRayDir, in float start, in float end, out vec3 intersection) {
float depth = start; // This is the computed distance from the pixel to the camera
intersection = camera.xyz;
for (int i = 0; i < MAX_STEPS; i++) {
float dist = sceneSDF(intersection);
if (dist < EPSILON) {
return depth;
}
depth += dist;
intersection += dist * viewRayDir;
if (depth > end) {
intersection = vec3(0.0);
return end;
}
}
return end;
}
struct Light {
vec3 position;
vec3 color;
float power;
};
struct PhongMaterial {
vec3 diffuseColor;
vec3 specularColor;
float specExponent;
};
vec3 add_light(vec3 position, vec3 normal, vec3 camera, PhongMaterial mat, Light light) {
vec3 lightDir = light.position - position;
float sq_dist = length(lightDir);
sq_dist = sq_dist * sq_dist;
lightDir = normalize(lightDir);
vec3 viewDir = normalize(camera - position);
vec3 reflected = normalize(reflect(-lightDir, normal));
float diffuseFactor = dot(lightDir, normal);
if (diffuseFactor < 0.0) {
return vec3(0);
}
float specularFactor = dot(viewDir, reflected);
specularFactor = pow(specularFactor, mat.specExponent);
if (specularFactor < 0.0) {
return light.color * light.power * mat.diffuseColor * diffuseFactor / sq_dist;
}
return light.color * light.power / sq_dist * (mat.diffuseColor * diffuseFactor + mat.specularColor * specularFactor);
}
const vec3 ambient_color = vec3(0.0, 0.06, 0.12);
vec3 calculate_lighting(vec3 position, vec3 normal, vec3 camera, PhongMaterial mat) {
vec3 col = ambient_color;
Light l1 = Light(vec3(3.0 * sin(u_time), 3.0, -5.0 * cos(u_time)), vec3(1.0, 1.0, 1.0), 40.0);
col += add_light(position, normal, camera, mat, l1);
Light l2 = Light(vec3(10.0 * cos(3.0*u_time), 5.0 * sin(3.0*u_time), 3.0), vec3(1.0, 0.6, 1.0), 80.0);
col += add_light(position, normal, camera, mat, l2);
return col;
}
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
vec3 camera = vec3(0.0, 0.0, -30.0);
vec3 viewRayDir = view_ray_dir(gl_FragCoord.xy, 45.0, u_resolution);
vec3 intersection;
float depth = ray_march(camera,viewRayDir, MIN_DIST, MAX_DIST, intersection);
vec3 normal = estimate_normal(intersection);
if (depth > MAX_DIST - EPSILON) {
gl_FragColor = vec4(0.5, 0.7, 0.9, 1.0); // Background color
return;
}
PhongMaterial mat = PhongMaterial(vec3(0.8, 0.5, 0.0), vec3(1.0, 1.0, 1.0), 20.0);
vec3 color = calculate_lighting(intersection, normal, camera, mat);
gl_FragColor = vec4(color, 1.0);
}
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Raymarching Demo</title>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js"></script>
</head>
<canvas class="glslCanvas" data-fragment-url="raymarching.glsl" width="500" height="500"></canvas>
<body bgcolor="#E6E6FA">
</body>
</html>
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
#define PI_TWO 1.570796326794897
#define PI 3.141592653589793
#define TWO_PI 6.283185307179586
vec2 coord(in vec2 p) {
p = p / u_resolution.xy;
// correct aspect ratio
if (u_resolution.x > u_resolution.y) {
p.x *= u_resolution.x / u_resolution.y;
p.x += (u_resolution.y - u_resolution.x) / u_resolution.y / 2.0;
} else {
p.y *= u_resolution.y / u_resolution.x;
p.y += (u_resolution.x - u_resolution.y) / u_resolution.x / 2.0;
}
// centering
p -= 0.5;
p *= vec2(-1.0, 1.0);
return p;
}
float random(in vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))
* 43758.5453123);
}
float noise (in vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
// Four corners in 2D of a tile
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
// Smooth Interpolation
// Cubic Hermine Curve. Same as SmoothStep()
vec2 u = f*f*(3.0-2.0*f);
// u = smoothstep(0.,1.,f);
// Mix 4 coorners percentages
return mix(a, b, u.x) +
(c - a)* u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
#define rx 1.0 / min(u_resolution.x, u_resolution.y)
#define uv gl_FragCoord.xy / u_resolution.xy
#define st coord(gl_FragCoord.xy)
#define mx coord(u_mouse)
void main() {
// Normalized pixel coordinates (from 0 to 1)
float min_dist = max(u_resolution.x, u_resolution.y); // Technically not, but basically max distance
// Let the N points be (noise(n, iTime), noise(iTime, n))
for (float n = 0.0; n < 8.0; n++) {
vec2 point = vec2(noise(vec2(n, u_time)),
noise(vec2(u_time, n)));
vec2 diff = uv - point;
min_dist = min(length(diff), min_dist);
}
min_dist = 1.0-min_dist;
min_dist = min_dist * min_dist;
vec3 col = vec3(min_dist, min_dist, min_dist);
// Output to screen
gl_FragColor = vec4(col,1.0);
}
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Voronoi Pattern Shader</title>
<script type="text/javascript" src="https://rawgit.com/patriciogonzalezvivo/glslCanvas/master/dist/GlslCanvas.js"></script>
</head>
<body>
<canvas class="glslCanvas" data-fragment-url="voronoi.glsl" width="498" height="500"></canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment