chandlerprall / Physijs

Physics plugin for Three.js
MIT License
2.75k stars 455 forks source link

How to deform an Physijs.SphereMesh like a WaterDrop? #314

Open davidmartinezros opened 5 years ago

davidmartinezros commented 5 years ago

Hi,

I need to implements a WaterDrop and I'm using Physijs.js with Three.js.

The gravity is going ok, but I don't know how to deform the Sphere when collisions with the ground like a water drop.

This is my code:

var noiseTexture = this.loaderTextures.load( 'assets/textures/cloud.png' );
noiseTexture.wrapS = noiseTexture.wrapT = THREE.RepeatWrapping; 

var waterTexture = this.loaderTextures.load( 'assets/textures/water.jpg' );
waterTexture.wrapS = waterTexture.wrapT = THREE.RepeatWrapping;

this.customUniforms2 = {
        baseTexture:    { type: "t", value: waterTexture },
        baseSpeed:      { type: "f", value: 1.15 },
        noiseTexture:   { type: "t", value: noiseTexture },
        noiseScale:     { type: "f", value: 0.2 },
        alpha:          { type: "f", value: 0.8 },
        time:           { type: "f", value: 1.0 }
    };

var customMaterial2 = new THREE.ShaderMaterial( 
    {
        uniforms: this.customUniforms2,
        vertexShader:   document.getElementById( 'vertexShader'   ).textContent,
        fragmentShader: document.getElementById( 'fragmentShader' ).textContent
    });

customMaterial2.side = THREE.DoubleSide;
customMaterial2.transparent = true;

var flatGeometry = new THREE.SphereGeometry( 30, 30, 30 );

this.waterDrop = new Physijs.SphereMesh(
        flatGeometry,
        customMaterial2,
        undefined,
        { restitution: Math.random() * 1.5 }
    );

this.waterDrop.position.set(60,50,150);
this.waterDrop.receiveShadow = true;
this.waterDrop.castShadow = true;

this.scene.add( this.waterDrop );

In the index.html file:

<script id="vertexShader" type="x-shader/x-vertex">
  varying vec2 vUv;
  void main() 
  { 
      vUv = uv;
      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  }
  </script>

  <!-- fragment shader a.k.a. pixel shader -->
  <script id="fragmentShader" type="x-shader/x-vertex"> 
  uniform sampler2D baseTexture;
  uniform float baseSpeed;
  uniform sampler2D noiseTexture;
  uniform float noiseScale;
  uniform float alpha;
  uniform float time;
  varying vec2 vUv;
  void main() 
  {
    vec2 uvTimeShift = vUv + vec2( -0.7, 1.5 ) * time * baseSpeed;  
    vec4 noiseGeneratorTimeShift = texture2D( noiseTexture, uvTimeShift );
    vec2 uvNoiseTimeShift = vUv + noiseScale * vec2( noiseGeneratorTimeShift.r, noiseGeneratorTimeShift.b );
    vec4 baseColor = texture2D( baseTexture, uvNoiseTimeShift );
    baseColor.a = alpha;
    gl_FragColor = baseColor;
  }  
  </script>

Can anyone helps me with my project?

Thanks,

David