Skip to content

Instantly share code, notes, and snippets.

@ChinW
Created July 1, 2019 05:16
Show Gist options
  • Select an option

  • Save ChinW/f2c8e3964de697c1c1f74df9c21cbd8c to your computer and use it in GitHub Desktop.

Select an option

Save ChinW/f2c8e3964de697c1c1f74df9c21cbd8c to your computer and use it in GitHub Desktop.

Revisions

  1. ChinW created this gist Jul 1, 2019.
    7 changes: 7 additions & 0 deletions blackness-darkness-forever.markdown
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    Blackness, darkness, forever
    ----------------------------


    A [Pen](https://codepen.io/shubniggurath/pen/bmNGqZ) by [Liam Egan](https://codepen.io/shubniggurath) on [CodePen](https://codepen.io).

    [License](https://codepen.io/shubniggurath/pen/bmNGqZ/license).
    130 changes: 130 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>
    <script id="vertexShader" type="x-shader/x-vertex">
    void main() {
    gl_Position = vec4( position, 1.0 );
    }
    </script>
    <script id="fragmentShader" type="x-shader/x-fragment">
    uniform vec2 u_resolution;
    uniform vec2 u_mouse;
    uniform float u_time;
    uniform sampler2D u_noise;

    // Hash function. This particular one probably doesn't disperse things quite
    // as nicely as some of the others around, but it's compact, and seems to work.
    //
    vec3 hash33(vec3 p){
    float n = sin(dot(p, vec3(7, 157, 113)));
    return fract(vec3(2097152, 262144, 32768)*n);
    }

    float pn( in vec3 p ){

    vec3 i = floor(p); p -= i; p *= p*(3. - 2.*p);
    p.xy = texture2D(u_noise, (p.xy + i.xy + vec2(37, 17)*i.z + .5)/256., -100.).yx;
    return mix(p.x, p.y, p.z);
    }

    float trigNoise3D(in vec3 p){


    float res = 0., sum = 0.;

    float n = pn(p*8. + u_time*2.);

    vec3 t = sin(p.yzx*3.14159265 + cos(p.zxy*3.14159265+1.57/2.))*0.5 + 0.5;
    p = p*1.5 + (t - 1.5); // + u_time*0.1
    res += (dot(t, vec3(0.333)));

    t = sin(p.yzx*3.14159265 + cos(p.zxy*3.14159265+1.57/2.))*0.5 + 0.5;
    res += (dot(t, vec3(0.333)))*0.7071;

    return ((res/1.7071))*0.85 + n*0.15;
    }

    // Distance function.
    float map(vec3 p) {
    float n = trigNoise3D(p*0.2);
    float t = sin(u_time*.0001)*.5+.5;
    float c = cos(p.z*.05*t+n);
    float s = sin(p.z*.05+n*.5);
    p.xy *= mat2(c, -s, s, c);
    p -= n*1.5;
    p.y = mod(p.y, 4.0) - 2.;
    return abs(p.y) - .1;

    return trigNoise3D(p*0.5);

    }



    void mainImage( out vec4 fragColor, in vec2 fragCoord )
    {

    vec3 rd = normalize(vec3(fragCoord - u_resolution.xy*.5, u_resolution.y*.75));

    // Ray origin. Moving along the Z-axis.
    vec3 ro = vec3(0, 0, u_time*10.);

    vec3 lp = vec3( 0, -.5, 5);
    lp += ro;

    rd = (rd + (hash33(rd.zyx)*.006 - .003));
    rd *= (1. + fract(sin(dot(vec3(7, 157, 113), rd.zyx))*43758.5453)*0.06-0.03);

    float lDe = 0., td = 0., w = 0.;

    float d = 1., t = 0.;

    const float h = .5;

    vec3 col = vec3(0), sp;



    vec3 sn = normalize(vec3(-1));

    // Raymarching loop.
    for (int i=0; i<64; i++) {

    if((td>1.) || d<.001*t || t>80.)break;


    sp = ro + rd*t; // Current ray position.
    d = map(sp); // Closest distance to the surface... particle.

    lDe = (h - d)*step(d, h);
    w = (1. - td)*lDe;

    td += w*(1.-h)*1./abs(d); //w*w*5. + 1./50.;

    // Point light calculations.
    vec3 ld = lp-sp; // Direction vector from the surface to the light position.
    float lDist = max(length(ld), .001); // Distance from the surface to the light.
    ld/=lDist; // Normalizing the directional light vector.

    // Using the light distance to perform some falloff.
    float atten = 1./(lDist);

    float diff = max(dot( sn, ld ), 0.);
    float spec = pow(max( dot( reflect(-ld, sn), -rd ), 0. ), 4.);

    col += w*(d*5. - .1)*(.5 + diff)*atten;

    t += max(d*.5, .02); //

    }

    col = max(col, 0.);
    fragColor = col.gggg;
    }


    void main() {
    mainImage(gl_FragColor, gl_FragCoord.xy);
    }
    </script>


    <div id="container" touch-action="none"></div>
    122 changes: 122 additions & 0 deletions script.babel
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,122 @@
    /*
    Most of the stuff in here is just bootstrapping. Essentially it's just
    setting ThreeJS up so that it renders a flat surface upon which to draw
    the shader. The only thing to see here really is the uniforms sent to
    the shader. Apart from that all of the magic happens in the HTML view
    under the fragment shader.
    */

    let container;
    let camera, scene, renderer;
    let uniforms;

    let loader=new THREE.TextureLoader();
    let texture;
    loader.setCrossOrigin("anonymous");
    loader.load(
    'https://s3-us-west-2.amazonaws.com/s.cdpn.io/982762/noise.png',
    function do_something_with_texture(tex) {
    texture = tex;
    texture.wrapS = THREE.RepeatWrapping;
    texture.wrapT = THREE.RepeatWrapping;
    texture.minFilter = THREE.LinearFilter;
    init();
    animate();
    }
    );

    function init() {
    container = document.getElementById( 'container' );

    camera = new THREE.Camera();
    camera.position.z = 1;

    scene = new THREE.Scene();

    var geometry = new THREE.PlaneBufferGeometry( 2, 2 );

    uniforms = {
    u_time: { type: "f", value: 1.0 },
    u_resolution: { type: "v2", value: new THREE.Vector2() },
    u_noise: { type: "t", value: texture },
    u_mouse: { type: "v2", value: new THREE.Vector2() }
    };

    var material = new THREE.ShaderMaterial( {
    uniforms: uniforms,
    vertexShader: document.getElementById( 'vertexShader' ).textContent,
    fragmentShader: document.getElementById( 'fragmentShader' ).textContent
    } );
    material.extensions.derivatives = true;

    var mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );

    renderer = new THREE.WebGLRenderer();
    renderer.setPixelRatio( window.devicePixelRatio );

    container.appendChild( renderer.domElement );

    onWindowResize();
    window.addEventListener( 'resize', onWindowResize, false );

    document.addEventListener('pointermove', (e)=> {
    let ratio = window.innerHeight / window.innerWidth;
    uniforms.u_mouse.value.x = (e.pageX - window.innerWidth / 2) / window.innerWidth / ratio;
    uniforms.u_mouse.value.y = (e.pageY - window.innerHeight / 2) / window.innerHeight * -1;

    e.preventDefault();
    });
    }

    function onWindowResize( event ) {
    renderer.setSize( window.innerWidth, window.innerHeight );
    uniforms.u_resolution.value.x = renderer.domElement.width;
    uniforms.u_resolution.value.y = renderer.domElement.height;
    }

    function animate(delta) {
    requestAnimationFrame( animate );
    render(delta);
    }






    let capturer = new CCapture( {
    verbose: true,
    framerate: 60,
    // motionBlurFrames: 4,
    quality: 90,
    format: 'webm',
    workersPath: 'js/'
    } );
    let capturing = false;

    isCapturing = function(val) {
    if(val === false && window.capturing === true) {
    capturer.stop();
    capturer.save();
    } else if(val === true && window.capturing === false) {
    capturer.start();
    }
    capturing = val;
    }
    toggleCapture = function() {
    isCapturing(!capturing);
    }

    window.addEventListener('keyup', function(e) { if(e.keyCode == 68) toggleCapture(); });

    let then = 0;
    function render(delta) {

    uniforms.u_time.value = -11200 + delta * 0.0015;
    renderer.render( scene, camera );

    if(capturing) {
    capturer.capture( renderer.domElement );
    }
    }
    1 change: 1 addition & 0 deletions scripts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/982762/ccapture.js"></script>
    9 changes: 9 additions & 0 deletions style.scss
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    body {
    margin: 0;
    padding: 0;
    }

    #container {
    position: fixed;
    touch-action: none;
    }