JSFiddle - React, Tailwind, and code Playground

by spacorum

HTML

<script src='//cdnjs.cloudflare.com/ajax/libs/three.js/r75/three.js'></script> 
<script id="frag1" type="x-shader/x-fragment">
// SHADERTOY: https://www.shadertoy.com/view/4dBcRD

    uniform float iGlobalTime;
    uniform vec2 iResolution;
    uniform vec4      iMouse;
    uniform sampler2D iChannel0;
    varying vec2 fragCoord;
    varying vec2 vUv;
    
    
#define WATER_DEPTH 2.1
#define DRAG_MULT 0.048
#define ITERATIONS_RAYMARCH 13
#define ITERATIONS_NORMAL 48
#define Mouse (iMouse.xy / iResolution.xy)
#define Resolution (iResolution.xy)
#define Time (iGlobalTime)

vec2 wavedx(vec2 position, vec2 direction, float speed, float frequency, float timeshift) {
    float x = dot(direction, position) * frequency + timeshift * speed;
    float wave = exp(sin(x) - 1.0);
    float dx = wave * cos(x);
    return vec2(wave, -dx);
}

float getwaves(vec2 position, int iterations){
	  float iter = 0.0;
    float phase = 6.0;
    float speed = 2.0;
    float weight = 1.0;
    float w = 0.0;
    float ws = 0.0;
    
    const int iterations_fix = 25; //RVB
    //const int iterations_fix = iterations + 1; //RVB
    
    for(int ia=0;ia<iterations_fix;ia++){
    	  //if( ia < iterations ) break;
        vec2 p = vec2(sin(iter), cos(iter));
        vec2 res = wavedx(position, p, speed, phase, Time);
        position += normalize(p) * res.y * weight * DRAG_MULT;
        w += res.x * weight;
        iter += 12.0;
        ws += weight;
        weight = mix(weight, 0.0, 0.2);
        phase *= 1.18;
        speed *= 1.07;
    }
    return w / ws;
}

float raymarchwater(vec3 camera, vec3 start, vec3 end, float depth){
    vec3 pos = start;
    float h = 0.0;
    float hupper = depth;
    float hlower = 0.0;
    vec2 zer = vec2(0.0);
    vec3 dir = normalize(end - start);
    for(int ii=0;ii<318;ii++){
        h = getwaves(pos.xz * 0.1, ITERATIONS_RAYMARCH) * depth - depth;
        if(h + 0.01 > pos.y) {
            return distance(pos, camera);
        }
        pos += dir * (pos.y...

JavaScript

var myInstance = {
      scene: new THREE.Scene(),
      camera: new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000),
      gameObjects: [],
      gameObjectsDict: {},
    };
    (function(myInstance) {
      myInstance.camera.position.x = 0;
      myInstance.camera.position.y = 0;
      myInstance.camera.position.z = 3;
      var webgl = new THREE.WebGLRenderer();
      webgl.setSize(window.innerWidth, window.innerHeight);
      document.body.appendChild(webgl.domElement);

      function onWindowResize() {
        myInstance.camera.aspect = window.innerWidth / window.innerHeight;
        myInstance.camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
      }
      window.addEventListener('resize', onWindowResize, false);
      renderer = webgl
      var light = new THREE.HemisphereLight(0xeeeeee, 0x888888, 1);
      light.position.set(0, 20, 0);
      //myInstance.scene.add(light);
      counter = 0;

      function render() {
        myInstance.gameObjects.forEach(function(item) {
          item.update(counter);
        });
        requestAnimationFrame(render);
        renderer.render(myInstance.scene, myInstance.camera);
      }
      render();
    })(myInstance);

    (function() {
      var gameObject = function(name, x, y, z, col, rx, ry) {
        this.name = name
        this.geometry = new THREE.PlaneGeometry(3, 3);
        uniforms = {
          iGlobalTime: {
            type: "f",
            value: 1.0
          },
          iResolution: {
            type: "v2",
            value: new THREE.Vector2()
          },          
        };
        uniforms.iResolution.value.x = 1; // window.innerWidth;
        uniforms.iResolution.value.y = 1; // window.innerHeight;
        this.material = new THREE.ShaderMaterial({
          uniforms: uniforms,
          side: THREE.DoubleSide,
          vertexShader: document.getElementById('general').textContent,
          fragmentShader:...