JSFiddle - React, Tailwind, and code Playground

HTML

<script src='http://mrdoob.github.com/three.js/build/three.min.js'></script>
<script src="http://mrdoob.github.com/three.js/examples/js/Detector.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/libs/stats.min.js"></script>
<script src="http://mrdoob.github.com/three.js/examples/js/controls/OrbitControls.js"></script>
<!-- Render texture vertex shader. Does not modify anything. -->
<script id="vs_rt" type="x-shader/x-vertex">
    uniform sampler2D texture;
    varying vec2 vUv2;

    void main() {
        vUv2 = uv;

        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
</script>
<!-- Render texture fragment shader. Runs a simulation step. -->
<script id="fs_rt" type="x-shader/x-fragment">
    uniform sampler2D texture;
    uniform vec2 delta;
    varying vec2 vUv2;

    void main() {
        vec4 info = texture2D(texture, vUv2);

        vec2 dx = vec2(delta.x, 0.0);
        vec2 dy = vec2(0.0, delta.y);

        // gather info from adjacent pixels
        float newHeight = ((texture2D(texture, vUv2 - dx).r + 
                            texture2D(texture, vUv2 - dy).r + 
                            texture2D(texture, vUv2 + dx).r + 
                            texture2D(texture, vUv2 + dy).r) * 0.5) - info.r;

        // damp the value so ripples don't last forever
        newHeight *= 0.99;
        info.r = newHeight;

        // set the new vertex height (vs_setHeight uses color to determine height)
        gl_FragColor = info;
    }
</script>
<!-- Main scene vertex shader. Updates mesh vertex height based on render texture color. -->
<script id="vs_setHeight" type="x-shader/x-vertex">
    uniform sampler2D texture;
    varying vec2 vUv;

    void main() {
        vUv = uv;
        vec4 info = texture2D(texture, vUv);

        vec3 newpos = position;

        // Multiply new height so we can actually see the difference.
        newpos.z = info.r * 100.0;

        gl_Position = projectionMatrix *...

JavaScript

if (!Detector.webgl) {
    Detector.addGetWebGLMessage();
}

//------------------------------------------
// Globals
//------------------------------------------
var stats, rendererStats, cameraRTT, camera, sceneRTT, scene, renderer;
var rtTexture, material, quad;
var simRes = 64;
var cUniforms, cUniforms2;
var buf1;


//------------------------------------------
// Main init and loop
//------------------------------------------
init();
animate();


//------------------------------------------
// Initialization
//------------------------------------------
function init() {
    setupRTTScene();

    setupMainScene();

    renderer = new THREE.WebGLRenderer({
        antialias: true
    });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x808080);
    renderer.autoClear = false;

    document.body.appendChild(renderer.domElement);

    stats = new Stats();
    stats.domElement.style.position = 'absolute';
    stats.domElement.style.bottom = '0px';
    stats.domElement.style.left = '0px';
    document.body.appendChild(stats.domElement);

    controls = new THREE.OrbitControls(camera);
    controls.addEventListener('change', render);
}


//------------------------------------------
// Setup the render-to-texture scene
//------------------------------------------
function setupRTTScene() {
    cameraRTT = new THREE.OrthographicCamera(simRes / -2, simRes / 2, simRes / 2, simRes / -2, -10000, 10000);

    sceneRTT = new THREE.Scene();

    buf1 = generateDataTexture(simRes, simRes, new THREE.Color(0x000000));

    var delta = 1.0 / simRes;
    cUniforms = {
        texture: {
            type: "t",
            value: buf1
        },
        delta: {
            type: "v2",
            value: new THREE.Vector2(delta, delta)
        }
    };
    material = new THREE.ShaderMaterial({
        uniforms: cUniforms,
        vertexShader: document.getElementById('vs_rt').textContent,
        fragmentShader:...