Skip to content

Instantly share code, notes, and snippets.

@strangerintheq
Last active January 2, 2019 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save strangerintheq/388b3363cacb07686c1b70669720c1ec to your computer and use it in GitHub Desktop.
Save strangerintheq/388b3363cacb07686c1b70669720c1ec to your computer and use it in GitHub Desktop.
menger sponge
license: gpl-3.0
height: 600
scrolling: no
border: yes

menger sponge

uniform vec2 resolution;
uniform vec3 eye;
uniform vec3 lookAt;
uniform vec3 lightPos;
uniform float time;
#pragma import scene.glsl
#pragma import https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/glsl/rayDirection.glsl
#pragma import https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/glsl/viewMatrix.glsl
#pragma import https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/glsl/castRay.glsl
#pragma import https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/glsl/normal.glsl
#pragma import phong.glsl
#pragma import https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/glsl/softShadow.glsl
#pragma import https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/glsl/ao.glsl
void drawBg() {
gl_FragColor = vec4(0.9, 0.9, 0.9, 1.0);
}
void drawScene(vec3 pt, float material) {
vec3 nor = estimateNormal( pt );
float occ = ao( pt, nor );
float shadow = softShadow( pt, normalize(lightPos-pt), 0.1, 22.2);
vec3 color = phong(pt, nor, eye, material)*sqrt(occ);
color += color * shadow;
gl_FragColor = vec4(color, 1.0);
}
void main(void) {
vec3 direction = rayDirection(60.0, resolution);
mat4 viewToWorld = viewMatrix(eye, lookAt, vec3(0.0, 1.0, 0.0));
vec3 worldDir = (viewToWorld * vec4(direction, 0.0)).xyz;
vec2 dist = castRay(eye, worldDir);
if (dist.x > 32.) {
drawBg();
} else {
drawScene(eye + dist.x * worldDir, dist.y);
}
}
<!DOCTYPE html>
<html>
<style>
body {
margin: 0;
overflow: hidden
}
canvas {
position: absolute;
width: 100%;
height: 100%;
}
</style>
<body>
<script src="https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/js/glx.js"></script>
<script src="https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/js/ShaderLoader.js"></script>
<script src="https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/js/FullScreenTriangle.js"></script>
<script src="https://cdn.jsdelivr.net/gh/strangerintheq/glx@0.0.2/js/mouse3d.js"></script>
<script>
ShaderLoader.load('fragment.glsl', init);
function init(fragCode) {
let fst = FullScreenTriangle(fragCode);
let resolution = fst.triangleProgram.uniform('2f', 'resolution');
let time = fst.triangleProgram.uniform('1f', 'time');
let eye = fst.triangleProgram.uniform('3f', 'eye');
let lightPos = fst.triangleProgram.uniform('3f', 'lightPos');
let started = new Date().getTime();
Mouse3D.init();
animate();
function animate() {
requestAnimationFrame(animate);
drawFrame();
}
function drawFrame() {
let t = (new Date().getTime() - started)/1000;
resolution.set(fst.gl.drawingBufferWidth, fst.gl.drawingBufferHeight);
time.set(t);
eye.set(Mouse3D.eye[0], Mouse3D.eye[1], Mouse3D.eye[2]);
lightPos.set(Math.cos(t/3)*0.8,0,Math.sin(t/3)*0.8);
fst.draw();
}
}
</script>
</body>
</html>
const vec3 K_a = vec3(.5, .5, .5);
const vec3 K_d = vec3(.5, .5, .5);
const vec3 K_s = vec3(.1, .1, .1);
const float shininess = 3.5;
const vec3 lightIntensity = vec3(1., 1., 1.);
/**
* Lighting contribution of a single point light source via Phong illumination.
*
* The vec3 returned is the RGB color of the light's contribution.
*
* k_a: Ambient color
* k_d: Diffuse color
* k_s: Specular color
* alpha: Shininess coefficient
* p: position of point being lit
* eye: the position of the camera
* lightPos: the position of the light
* lightIntensity: color/intensity of the light
*
* See https://en.wikipedia.org/wiki/Phong_reflection_model#Description
*/
vec3 phongContribForLight(vec3 k_d, vec3 k_s, float alpha, vec3 p, vec3 N, vec3 eye,
vec3 lightPos, vec3 lightIntensity) {
vec3 L = normalize(lightPos - p);
vec3 V = normalize(eye - p);
vec3 R = normalize(reflect(-L, N));
float dotLN = dot(L, N);
float dotRV = dot(R, V);
if (dotLN < 0.0) {
// Light not visible from this point on the surface
return vec3(0.0, 0.0, 0.0);
}
if (dotRV < 0.0) {
// Light reflection in opposite direction as viewer, apply only diffuse
// component
return lightIntensity * (k_d * dotLN);
}
return lightIntensity * (k_d * dotLN + k_s * pow(dotRV, alpha));
}
/**
* Lighting via Phong illumination.
*
* The vec3 returned is the RGB color of that point after lighting is applied.
* k_a: Ambient color
* k_d: Diffuse color
* k_s: Specular color
* alpha: Shininess coefficient
* p: position of point being lit
* eye: the position of the camera
*
* See https://en.wikipedia.org/wiki/Phong_reflection_model#Description
*/
vec3 phongIllumination(vec3 k_a, vec3 k_d, vec3 k_s, float alpha, vec3 p, vec3 nor, vec3 eye, vec3 materialColor) {
vec3 color = materialColor * k_a;
color += phongContribForLight(k_d, k_s, alpha, p, nor, eye, lightPos, lightIntensity);
//color += phongContribForLight(k_d, k_s, alpha, p, eye, light2Pos, light2Intensity);
return color;
}
vec3 decodeMaterial(float m) {
return vec3(1.-m/3.);
}
vec3 phong(vec3 p, vec3 nor, vec3 eye, float material) {
vec3 materialColor = decodeMaterial(material);
return phongIllumination(K_a, K_d, K_s, shininess, p, nor, eye, materialColor);
}
float sdBox( 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
}
vec3 sponge( in vec3 p ){
float d = sdBox(p,vec3(1.0));
vec3 res = vec3( d, 1.0, 0.0 );
float s = 1.;
for( int m=0; m<6; m++ )
{
vec3 a = mod( p*s, 2.0 )-1.0;
s *= 3.0;
vec3 r = abs(1.0 - 3.0*abs(a));
float da = max(r.x,r.y);
float db = max(r.y,r.z);
float dc = max(r.z,r.x);
float c = (min(da,min(db,dc))-1.0)/s;
if( c>d )
{
d = c;
res = vec3( d, 0.2*da*db*dc, (1.0+float(m))/4.0);
}
}
return res;
}
vec2 map(vec3 p) {
vec3 r =sponge(p);
return vec2(r.x, abs(r.y - r.z));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment