Recreating homunculus.jp with ripple effect on mouseover

So I am trying to create ripple effects on mouse over exactly like in homunculus.jp website, I have absolutely no idea on how to go about it, I was able to get some result using the following code

import * as THREE from "three";

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

// import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';

import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';

import { RGBShiftShader } from 'three/examples/jsm/shaders/RGBShiftShader.js';

import { DotScreenShader } from 'three/examples/jsm/shaders/DotScreenShader';

import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';

import { Custom } from "./shader/Custom";

import fragment from "./shader/fragment.glsl";

import vertex from "./shader/vertex.glsl";

import * as dat from "dat.gui";

import gsap from "gsap";

import brush from '../brush.png'

import { RGBAFormat } from "three";

import ocean from '../1.jpg'

import ocean2 from '../2.jpg'

export default class Sketch {

  constructor(options) {

    this.scene = new THREE.Scene();

    this.scene1 = new THREE.Scene();

    this.container = options.dom;

    this.width = this.container.offsetWidth;

    this.height = this.container.offsetHeight;

    this.renderer = new THREE.WebGLRenderer();

    this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

    this.renderer.setSize(this.width, this.height);

    this.renderer.setClearColor(0x000000, 1);

    // Get Images

    this.images = [...document.querySelectorAll('.project__media__image')];

    this.container.appendChild(this.renderer.domElement);

    this.camera = new THREE.PerspectiveCamera(

      70,

      window.innerWidth / window.innerHeight,

      0.001,

      1000

    );

    var frustumSize = this.height;

    var aspect = this.width/this.height;

    this.camera = new THREE.OrthographicCamera( frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, -1000, 1000 );

    this.camera.position.set(0, 0, 2);

    this.controls = new OrbitControls(this.camera, this.renderer.domElement);

    this.time = 0;

    this.isPlaying = true;

    this.mouse = new THREE.Vector2(0, 0);

    this.prevMouse = new THREE.Vector2(0, 0);

    this.currentWave = 0;

    this.base = new THREE.WebGLRenderTarget(this.width, this.height,{

      stencilBuffer: true,

      minFilter: THREE.LinearFilter,

      magFilter: THREE.LinearFilter,

      format: THREE.RGBAFormat

    })

    this.mouseEvents();

    // this.addBackPlane();

    this.addObjects();

    this.setPosition();

    this.resize();

    this.initPost();

    this.render();

    this.setupResize();

    this.settings();

  }

  initPost(){

    this.composer = new EffectComposer( this.renderer );

    this.renderOne = new RenderPass(this.scene1, this.camera);

    this.effect1 = new ShaderPass( Custom )

    this.effect1.renderToScreen = true;

    this.composer.addPass( this.renderOne );

    // this.composer.addPass(this.effect);

    this.composer.addPass(this.effect1)

  }

  mouseEvents(){

    window.addEventListener('mousemove',(e)=>{

      this.mouse.x = e.clientX - this.width/2;

      this.mouse.y = this.height/2 - e.clientY;

    })

  }

  settings() {

    let that = this;

    this.settings = {

      progress: 1,

      scale: 0.9

    };

    this.gui = new dat.GUI();

    this.gui.add(this.settings, "progress", 0, 1, 0.01);

    this.gui.add(this.settings, "scale", 0, 1, 10);

  }

  setupResize() {

    window.addEventListener("resize", this.resize.bind(this));

  }

  resize() {

    this.width = this.container.offsetWidth;

    this.height = this.container.offsetHeight;

    this.renderer.setSize(this.width, this.height);

    this.camera.aspect = this.width / this.height;

    this.camera.updateProjectionMatrix();

  }

  addObjects() {

    let that = this;

    this.meshImages = [];

    this.imageStore = this.images.map(img => {

      let bounds = img.getBoundingClientRect();

         

      let geometry = new THREE.PlaneBufferGeometry(bounds.width, bounds.height, 1, 1);

      this.materials = new THREE.ShaderMaterial({

        extensions: {

          derivatives: "#extension GL_OES_standard_derivatives : enable"

        },

        side: THREE.DoubleSide,

        uniforms: {

          time: { value: 0 },

          progress: {value: 1 },

          uDisplacement: {value: null},

          uTexture: { value: new THREE.TextureLoader().load(img.src)},

          shiftx: { value: -0.5 },

          shifty: { value: -0.5},

          damp: {value: 2.0}

        },

        vertexShader: vertex,

        fragmentShader: fragment

      })

      this.mainMesh = new THREE.Mesh(geometry, this.materials);

      this.scene1.add(this.mainMesh);

      this.meshImages.push(this.mainMesh);

      return{

        img: img,

        mesh: this.mainMesh,

        top: bounds.top,

        left: bounds.left,

        width: bounds.width,

        height: bounds.height,

    }

    })

       

    // the brushes

   

    this.meshes = [];

    this.max = 100;

    this.geometry = new THREE.PlaneGeometry(10, 10, 1, 1);

   

    for (let i = 0; i < this.max; i++) {

      let m  = new THREE.MeshBasicMaterial({

        map: new THREE.TextureLoader().load(brush),

        transparent: true,

        blending: THREE.AdditiveBlending,

        depthTest: false,

        depthWrite: false

      })

      let mesh = new THREE.Mesh(this.geometry, m);

      mesh.visible = false

      mesh.rotation.z = 2*Math.PI*Math.random();

      this.scene.add(mesh)

      this.meshes.push(mesh)

 

    }

    console.log(this.base)

   

  }

  setPosition(){

     

    this.imageStore.forEach(o=>{

      o.mesh.position.y = - o.top + this.height/2 - o.height/2;

      o.mesh.position.x = o.left - this.width/2 + o.width/2;

     

    })

  }

  stop() {

    this.isPlaying = false;

  }

  play() {

    if(!this.isPlaying){

      this.render()

      this.isPlaying = true;

    }

  }

  newWave(x, y, Index){

    let m = this.meshes[Index];

    m.visible = true;

    m.position.x = x;

    m.position.y = y;

    m.scale.x = m.scale.y = 1;

    m.material.opacity = 1

  }

  trackMouse(){

    if((Math.abs(this.mouse.x - this.prevMouse.x) < 4) && (Math.abs(this.mouse.y - this.prevMouse.y)<4)){

    }

    else{

      this.currentWave = (this.currentWave + 1)%this.max;

      this.newWave(this.mouse.x, this.mouse.y, this.currentWave);

    }

    this.prevMouse.x = this.mouse.x;

    this.prevMouse.y = this.mouse.y;

  }

  render() {

    this.trackMouse();

    if (!this.isPlaying) return;

    this.time += 0.003;

    // this.material.uniforms.time.value = this.time;

    this.effect1.uniforms[ 'time' ].value = this.time;

    this.effect1.uniforms[ 'scale' ].value = this.settings.scale;

    this.effect1.uniforms[ 'progress' ].value = this.settings.progress;

    requestAnimationFrame(this.render.bind(this));

   

    this.renderer.setRenderTarget(this.base);

    this.renderer.render(this.scene, this.camera);

   

    for (let index = 0; index < this.meshImages.length; index++) {

      this.materials.uniforms.uDisplacement.value = this.base.texture

     

    }

    this.renderer.setRenderTarget(null);

    this.renderer.clear();

    this.composer.render();

 

    this.meshes.forEach(m=>{

      if(m.visible){

        m.rotation.z += 0.02;

        m.material.opacity *= 0.98;

        m.scale.x = 0.9*m.scale.x + 1.0;

        m.scale.y = m.scale.x

        if(m.material.opacity < 0.002){

          m.visible = false

        }

      }

     

    })

  }

}

new Sketch({

  dom: document.getElementById("container")

});