• 01 - Critter Models 02
  • 02 - VantaJS Shaders
  • 03 - App Bundle 02
  • 04 - Cathedrals
  • 05 - App Bundle 01
  • 06 - Retroscopic
  • 07 - Games
  • 08 - Voronoi
  • 09 - Terrain
  • 10 - Critter Models 01
  • 11 - Chromatophores
  • 12 - Conformal Maps
  • 13 - Echo Logix
  • 14 - Music
  • 15 - Colour Theory
MIKE'S NOTEBOOK
Notes
Number:
Project:
01Critter Models 02
└ Locust└ Butterfly└ Cockroach└ Spider└ Scorpion└ Dragon└ Brazilian Treehopper└ Tardigrade└ Diatoms└ Bumblebee└ Wasp└ Hammerhead Worm└ Giraffe Weevil└ Trilobite Beetle
02VantaJS Shaders
└ Clouds└ Waves└ Cells└ Rings└ Halo└ Globe└ Net└ Dots└ Birds└ Trunk└ Topology└ About VantaJS
03App Bundle 02
└ Gutindex└ Insect Builder└ OpenLayers
04Cathedrals
└ Lattice└ Lost└ Lucent└ Lumen└ Glass└ Disco└ Hyperion└ Latent
05App Bundle 01
└ Robohash└ PrismJS└ Horoscope└ Binary Jazz└ Morse Code└ URL Extractor└ Entity Escaper└ Phonetic Alphabet└ Toki Pona└ Semaphore└ Cut Up Machine└ Text Mixer└ Currency Freaks└ Host IO└ CrUX API└ Logo Dev└ Web Speech API└ GEO DB
06Retroscopic
└ Galaxy└ Ocean└ Slime└ 24-Cell└ Unicorn└ Polyp└ Oneiric 1└ Oneiric 2└ Node└ Torus Knot└ GLSL Grid└ Liquid Crystal└ Silky└ Butterfly└ Ocean 2└ Icosahedron└ Luma└ Swarm└ Broken Solid└ Hypersphere└ Constraints└ Psycho Killer
01 / 03

BROKEN SOLID - RETROSCOPIC CRT SHADER SOURCE CODE

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <style>
        body { margin: 0; overflow: hidden; background: #000; }
        #stage {
            position: fixed;
            inset: 0;
            width: 100vw;
            height: 100vh;
            filter: grayscale(1) sepia(1) hue-rotate(80deg) saturate(5) brightness(1.15) contrast(1.2);
            z-index: 2;
        }
        /* Retroscopic Overlay */
        #scope {
            position: fixed;
            inset: 0;
            z-index: 4;
            pointer-events: none;
            display: block;
        }
        #scope>div {
            position: absolute;
            inset: 0;
        }
        #scope .glow {
            background: radial-gradient(circle at 50% 46%, rgba(30, 255, 130, .08), rgba(0, 0, 0, 0) 62%);
            animation: nvflick 3.6s steps(24) infinite;
        }
        #scope .scan {
            background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0) 0 2px, rgba(0, 25, 8, .45) 2px 3px);
            animation: nvscan 7s linear infinite;
        }
        #scope .vig {
            box-shadow: inset 0 0 200px 50px rgba(0, 0, 0, .8);
        }
        #scope .mask {
            background: radial-gradient(circle at 50% 50%, rgba(0, 0, 0, 0) 54%, rgba(0, 0, 0, .5) 72%, rgba(0, 0, 0, .94) 100%);
        }
        @keyframes nvscan {
            from { background-position: 0 0; }
            to { background-position: 0 240px; }
        }
        @keyframes nvflick {
            0%, 100% { opacity: .55; }
            40% { opacity: .9; }
            62% { opacity: .4; }
            80% { opacity: .75; }
        }
    </style>
</head>
<body>
    <div id="scope">
        <div class="glow"></div>
        <div class="scan"></div>
        <div class="vig"></div>
        <div class="mask"></div>
    </div>
    <div id="stage"></div>
    <script>
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer({antialias:true});
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.getElementById('stage').appendChild(renderer.domElement);

        scene.add(new THREE.AmbientLight(0xffffff, 0.6));
        const light = new THREE.DirectionalLight(0xffffff, 0.8);
        light.position.set(5, 5, 5);
        scene.add(light);

        const a = 3;
        const vertices = [
            new THREE.Vector3(a, a, 3*a),
            new THREE.Vector3(a, 3*a, a),
            new THREE.Vector3(3*a, a, a),
            new THREE.Vector3(-a, -a, 3*a),
            new THREE.Vector3(-a, 3*a, -a),
            new THREE.Vector3(3*a, -a, -a),
            new THREE.Vector3(a, -a, -3*a),
            new THREE.Vector3(a, -3*a, -a),
            new THREE.Vector3(-3*a, -a, -a),
            new THREE.Vector3(-a, a, -3*a),
            new THREE.Vector3(-a, -3*a, a),
            new THREE.Vector3(-3*a, a, a)
        ];

        vertices.forEach(v => v.multiplyScalar(0.2));

        const indices = [
            // Triangle faces
            0, 1, 2,
            3, 4, 5,
            6, 7, 8,
            9, 10, 11,

            0, 3, 5,  0, 5, 2,  0, 2, 4,  0, 4, 3,

            1, 0, 4,  1, 4, 7,  1, 7, 10, 1, 10, 0,

            2, 1, 7,  2, 7, 6,  2, 6, 5,  2, 5, 1,

            3, 8, 11, 3, 11, 9, 3, 9, 4,  3, 4, 8
        ];

        const geometry = new THREE.BufferGeometry();
        const positions = [];
        vertices.forEach(v => positions.push(v.x, v.y, v.z));
        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
        geometry.setIndex(indices);
        geometry.computeVertexNormals();

        const faceMaterial = new THREE.MeshPhongMaterial({
            color: 0x00bcd4,
            transparent: true,
            opacity: 0.9
        });

        const wireMaterial = new THREE.MeshBasicMaterial({
            color: 0xffffff,
            wireframe: true,
            transparent: true,
            opacity: 0.3
        });

        const shape = new THREE.Group();
        shape.add(new THREE.Mesh(geometry, faceMaterial));
        shape.add(new THREE.Mesh(geometry, wireMaterial));
        scene.add(shape);

        camera.position.z = 4;

        function animate() {
            requestAnimationFrame(animate);
            shape.rotation.x += 0.005;
            shape.rotation.y += 0.01;
            renderer.render(scene, camera);
        }

        animate();

        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>
</html>
MikeHiggins.me.uk LinkedIn GitHub Bluesky Contra Upwork
© 2026 Mike Higgins. All rights reserved.