2016-11-25 77 views
0

我正在three.js創建布料模擬器像hermes'網站只是區別是我想要自上而下的波浪,而不是herozontal波在hermes。布料模擬器使用three.js

但是我成功了,使垂直波,因爲我想(在這裏是live下方還增加了片段) 但正如你所看到的頂面是不固定的同時,還輕微地移動我要打頂側固定不應該移動像hermes網站一樣,並且希望在網頁加載時使這一波連續而不是一次,我也注意到曾經有線的事情,當我在瀏覽器中打開我的修改版本5-10分鐘時,它的大小縮小(高度爲&寬度)和過一段時間後會變得更小。我不知道爲什麼!

這裏的任何一位專家都可以幫助我做這三件事嗎?

  • 使頂端固定像hermes。
  • 連續波。
  • 擺脫尺寸減少。

function Particle(x, y, z, mass, drag, clothFunction) { 
 

 
    this.position = clothFunction(x, y); // position 
 
    this.previous = clothFunction(x, y); // previous 
 
    this.original = clothFunction(x, y); 
 
    
 
    this.a = new THREE.Vector3(0, 0, 0); // acceleration 
 
    
 
    this.mass = mass; 
 
    
 
    this.drag = drag; 
 
    
 
    this.invMass = 1/mass; 
 
    
 
    this.tmp = new THREE.Vector3(); 
 
    this.tmp2 = new THREE.Vector3(); 
 

 
} 
 

 
Particle.prototype.addForce = function(force) { 
 
    this.a.add(
 
     this.tmp2.copy(force).multiplyScalar(this.invMass) 
 
    ); 
 

 
}; 
 

 
Particle.prototype.integrate = function(timesq) { 
 

 
    var newPos = this.tmp.subVectors(this.position, this.previous); 
 
    // newPos.multiplyScalar(this.drag).add(this.position); 
 
    newPos.add(this.position); 
 
    newPos.add(this.a.multiplyScalar(timesq)); 
 

 
    this.tmp = this.previous; 
 
    this.previous = this.position; 
 
    this.position = newPos; 
 

 
    this.a.set(0, 0, 0); 
 

 
}; 
 

 
function Cloth(mass, w, h, restDistance, drag, clothFunction) { 
 
    function index(u, v) { 
 

 
     return u + v * (w + 1); 
 

 
    } 
 

 
    w = w || 10; 
 
    h = h || 10; 
 
    this.w = w; 
 
    this.h = h; 
 

 
    var particles = []; 
 
    var constraints = []; 
 

 
    var u, v; 
 

 
    // Create particles 
 
    for (v = 0; v <= h; v ++) { 
 
     for (u = 0; u <= w; u ++) { 
 

 
      particles.push(
 
       new Particle(u/w, -v/h, 0, mass, drag, clothFunction) 
 
      ); 
 
     } 
 
    } 
 

 
    // Structural 
 
    for (v = 0; v < h; v ++) { 
 
     for (u = 0; u < w; u ++) { 
 
      constraints.push([ 
 
       particles[ index(u, v) ], 
 
       particles[ index(u, v + 1) ], 
 
       restDistance 
 
      ]); 
 

 
      constraints.push([ 
 
       particles[ index(u, v) ], 
 
       particles[ index(u + 1, v) ], 
 
       restDistance 
 
      ]); 
 
     } 
 
    } 
 

 
    for (u = w, v = 0; v < h; v ++) { 
 
     constraints.push([ 
 
      particles[ index(u, v) ], 
 
      particles[ index(u, v + 1) ], 
 
      restDistance 
 

 
     ]); 
 
    } 
 

 
    for (v = h, u = 0; u < w; u ++) { 
 
     constraints.push([ 
 
      particles[ index(u, v) ], 
 
      particles[ index(u + 1, v) ], 
 
      restDistance 
 
     ]); 
 
    } 
 

 
    this.particles = particles; 
 
    this.constraints = constraints; 
 

 
    this.index = index; 
 

 
} 
 

 

 
function animatedProduct(container, size, canvas, image) { 
 
    this.DAMPING = .02; 
 
    this.DRAG = 1 - this.DAMPING 
 
    this.MASS = 2000; 
 
    this.STIFFNESS = 1; 
 
    this.SEGMENTS = 40; 
 
    this.canvas = canvas; 
 
    this.size = size; 
 
    this.demoMode = !0; 
 
    this.startTime = Date.now(); 
 
    this.image = image; 
 
    this.restDistance = this.size/this.SEGMENTS; 
 
    this.container = container; 
 
    this.gravity = new THREE.Vector3(0, -80, 0).multiplyScalar(this.MASS); 
 
    this.TIMESTEP_SQ = Math.pow(.01, 2); 
 

 
    this.tmpForce = new THREE.Vector3; 
 
    this.diff = new THREE.Vector3; 
 

 
    this.pins = []; 
 
    
 
    for(var i = 0; i <= this.SEGMENTS; i++) 
 
     this.pins.push(i); 
 

 

 
    this.degree = 0; 
 
    this.wave = 0; 
 
} 
 

 
animatedProduct.prototype = { 
 
    createPlane: function(width, height) { 
 
     return function(c, d) { 
 
      var e = (c - .5) * width, 
 
       f = (d + .5) * height, 
 
       g = 0; 
 

 
      return new THREE.Vector3(e, f, g) 
 
     } 
 
    }, 
 
    satisfyConstraints: function(p1, p2, distance) { 
 
     this.diff.subVectors(p2.position, p1.position); 
 

 
     var currentDist = this.diff.length(); 
 

 
     if (currentDist === 0) 
 
      return; // prevents division by 0 
 

 
     this.diff.normalize(); 
 

 
     var correction = this.diff.multiplyScalar(currentDist - distance); 
 
     var correctionHalf = correction.multiplyScalar(0.5); 
 

 
     p1.position.add(correctionHalf); 
 
     p2.position.sub(correctionHalf); 
 
    }, 
 
    simulate: function(timestep_sq) { 
 
     var b, c, d, e, f, g, h, i, j = this.clothGeometry.faces; 
 
     
 
     for (d = this.cloth.particles, b = 0, c = d.length; c > b; b++) { 
 
      e = d[b]; 
 
      e.addForce(this.gravity); 
 
      e.integrate(timestep_sq); 
 
     } 
 
     
 
     for (f = this.cloth.constraints, c = f.length, b = 0; c > b; b++) { 
 
      g = f[b]; 
 
      this.satisfyConstraints(g[0], g[1], g[2]); 
 
     } 
 

 
     for (d = this.cloth.particles, b = 0, c = d.length; c > b; b++) { 
 
      e = d[b]; 
 

 
      e.position.x = e.original.x; 
 
     } 
 

 
     for (b = 0, c = this.pins.length; c > b; b++) { 
 
      var k = this.pins[ b ], 
 
       l = d[ k ]; 
 

 
      l.position.y = l.original.y; 
 
      l.position.x = l.original.x; 
 

 
      l.position.z = l.position.z + this.wave; 
 
     } 
 

 
     if(this.degree <= 6) { 
 
      this.wave = Math.sin(this.degree) * 6; 
 

 
      this.degree += 0.017 * 42; 
 
     } 
 
     else 
 
      this.wave = 0; 
 
    }, 
 
    init: function() { 
 
     this.clothFunction = this.createPlane(this.size, this.size); 
 
     
 
     this.cloth = new Cloth(this.MASS, this.SEGMENTS, this.SEGMENTS, this.restDistance, this.DRAG, this.createPlane(this.size, this.size)); 
 
     
 
     this.scene = new THREE.Scene; 
 

 
     this.camera = new THREE.PerspectiveCamera(45, this.canvas.width/this.canvas.height, 1, 1e4); 
 
     this.camera.position.y = 0; 
 
     this.camera.position.z = 1e3; 
 

 
     this.scene.add(this.camera); 
 

 
     this.light = new THREE.DirectionalLight(16777215, 1); 
 
     this.light.position.set(20, -20, 100); 
 

 
     this.scene.add(this.light); 
 

 
     THREE.ImageUtils.crossOrigin = ""; 
 

 
     var texture = THREE.ImageUtils.loadTexture(this.image, {}, function() { 
 
      this.canvas.classList.add("play") 
 
     }.bind(this)); 
 

 
     texture.flipY = !1; 
 
     texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 
 
     texture.anisotropy = 16; 
 
     
 
     var b = new THREE.MeshPhongMaterial({ 
 
      ambient: 16777215, 
 
      shininess: 20, 
 
      map: texture, 
 
      side: THREE.DoubleSide 
 
     }); 
 

 
     this.clothGeometry = new THREE.ParametricGeometry(this.clothFunction, this.cloth.w, this.cloth.h); 
 
     this.clothGeometry.dynamic = !0; 
 
     this.clothGeometry.computeFaceNormals(); 
 
     
 
     var c = { 
 
       texture: { 
 
        type: "t", 
 
        value: texture 
 
       } 
 
      }, 
 
      d = "varying vec2 vUV;void main() {vUV = 0.75 * uv;vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);gl_Position = projectionMatrix * mvPosition;}", 
 
      e = "uniform sampler2D texture;varying vec2 vUV;vec4 pack_depth(const in float depth) {const vec4 bit_shift = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);vec4 res = fract(depth * bit_shift);res -= res.xxyz * bit_mask;return res;}void main() {vec4 pixel = texture2D(texture, vUV);if (pixel.a < 0.5) discard;gl_FragData[ 0 ] = pack_depth(gl_FragCoord.z);}"; 
 
     
 
     this.object = new THREE.Mesh(this.clothGeometry, b); 
 
     
 
     this.object.position.set(0, 0, 0); 
 
     this.scene.add(this.object); 
 
     this.object.customDepthMaterial = new THREE.ShaderMaterial({ 
 
      uniforms: c, 
 
      vertexShader: d, 
 
      fragmentShader: e 
 
     }); 
 

 
     this.renderer = new THREE.WebGLRenderer({ 
 
      antialias: !0, 
 
      canvas: this.canvas 
 
     }); 
 

 
     this.renderer.setSize(this.canvas.width, this.canvas.height); 
 
     this.renderer.setClearColor(16777215, 1); 
 
     this.renderer.autoClear = !1; 
 
     this.renderer.autoClearDepth = !1; 
 

 
     this.container.appendChild(this.renderer.domElement); 
 
     this.renderer.gammaInput = !0; 
 
     this.renderer.gammaOutput = !0; 
 
     this.canvas.addEventListener("mousedown", this.onClick.bind(this), !1); 
 

 
     for (var f = 0; 20 > f; f++) this.simulate(this.TIMESTEP_SQ); 
 

 
     this.play(); 
 
    }, 
 
    onClick: function(a) { 
 
    }, 
 
    animate: function() { 
 
     this.animationFrame = window.requestAnimationFrame(this.animate.bind(this)); 
 
     
 
     this.simulate(this.TIMESTEP_SQ); 
 
     this.render(); 
 
    }, 
 
    pause: function() { 
 
     window.cancelAnimationFrame(this.animationFrame); 
 
    }, 
 
    play: function() { 
 
     this.scene ? this.animate() : this.init(); 
 
    }, 
 
    render: function() { 
 
     for (var a = this.cloth.particles, b = 0, c = a.length; c > b; b++) 
 
      this.clothGeometry.vertices[ b ].copy(a[ b ].position); 
 

 
     this.clothGeometry.computeFaceNormals(); 
 
     this.clothGeometry.computeVertexNormals(); 
 
     this.clothGeometry.normalsNeedUpdate = !0; 
 
     this.clothGeometry.verticesNeedUpdate = !0; 
 
     
 
     this.camera.lookAt(this.scene.position); 
 
     
 
     this.renderer.clear(); 
 
     this.renderer.render(this.scene, this.camera); 
 
    }, 
 
    stop: function() { 
 
     this.pause(); 
 
     this.canvas.parentNode.removeChild(this.canvas); 
 
    } 
 
}; 
 

 
var size = 700, 
 
    container = document.getElementById("product-container"), 
 
    image = "http://media.hermes.com/media/catalog/product/import/S/S01/S011/item/flat/hd/H001485S-17.jpg", 
 
    canvas = document.createElement("canvas"); 
 
    canvas.width = canvas.height = 600 + 20, 
 
    canvas.id = "product", 
 
    container.appendChild(canvas), 
 
    productAnimation = new animatedProduct(container, size, canvas, image); 
 

 
productAnimation.play();
<script src="http://maksible.com/cloth/cloth_slower_v2/cloth/three.min.js"></script> 
 
<body> 
 
    <div id="product-container"></div> 
 
    <script type="text/javascript" src="three.min.js"></script> 
 
    <script type="text/javascript" src="logic.js"></script> 
 
</body>

回答

0

這裏是three.js所但具有不同的邏輯比你的溶液。希望它對你有用。

var size = 500; 
var img = 'Image.jpg'; 

window.onload = function() { 

     createWGL(); 
     render(); 

    } 

    // render 
    // 
    function render() { 

     requestAnimationFrame(render); 

     if(window.mat) 
     mat.uniforms.time.value = now(); 

     ctx.render(scn, cam); 

    } 

    // create renderer 
    // 
    function createWGL() { 

     // check desktop/mobile 
     window.desk = !(/Android|webOS|iPhone|iPad|BlackBerry|Windows Phone|Opera Mini|IEMobile|Mobile/i.test(navigator.userAgent)); 

     window.ctx = new THREE.WebGLRenderer({antialias:window.desk}); 
     ctx.setClearColor(0xffffff); 
     ctx.setPixelRatio(window.devicePixelRatio); 
     ctx.setSize(size, size); 

     // camera 
     window.cam = new THREE.PerspectiveCamera(90, 1, 1, 30); 
     cam.position.z = 25; 

     // scene 
     window.scn = new THREE.Scene(); 

     // canvas 
     window.cvs = createCanvas(); 
     scn.add(cvs); 
     loadCanvasTexture(img); 

     // clear viewport 
     ctx.render(scn, cam); 
     document.body.appendChild(ctx.domElement); 

    } 

    // now 
    // 
    function now(){ 

     return performance.now() * 0.001; 

    } 

    // load canvas texture 
    // 
    function loadCanvasTexture(path) { 

     if(window.tex) 
     window.tex.dispose(); 

     cvs.visible = false; 

     window.tex = new THREE.TextureLoader().load(path, function(){ 
     cvs.visible = true; 
     }); 
     window.tex.anisotropy = ctx.getMaxAnisotropy(); 
     window.mat.uniforms.tex.value = window.tex; 

    } 

    // create canvas 
    // 
    function createCanvas() { 

     window.mat = new THREE.RawShaderMaterial({ 
     uniforms: { 
      time: { value: now() }, 
      tex: { value: null } 
     }, 
     vertexShader: 'precision mediump float;precision mediump int;uniform mat4 modelViewMatrix;'+ 
      'uniform mat4 projectionMatrix;attribute vec2 pos;uniform float time;varying vec2 uv;varying float amb;'+ 
      'float d(float y){return cos(sin(time/2.)+time/2.+y/2.14)*sin(time+y/4.17)*(.5-y/40.)*1.5;}'+ 
      'void main(){vec3 p=vec3(pos.x+sin(time/3.)*(.5-pos.y/40.), pos.y+sin(time)*(.5-pos.y/40.)/2., d(pos.y));amb=(d(pos.y-1.)-d(pos.y+1.))/4.;'+ 
      'uv=vec2(pos.x/40.+.5,pos.y/40.+.5);gl_Position=projectionMatrix*modelViewMatrix*vec4(p,1.);}', 
     fragmentShader: 'precision mediump float;precision mediump int;uniform sampler2D tex;varying vec2 uv;varying float amb;'+ 
      'void main(){vec4 col=texture2D(tex,uv)+amb;gl_FragColor=vec4(col.xyz,1.);}' 
     }); 

     var d = 40,d2=~~(d/2),i,j,k,n,fi,v,m,z1=-1,z2; 

     fi = new Uint16Array(d * d * 6); 
     v = new Int8Array((d+1) * (d+1) * 2); 
     for(j=0;j<=d;j++) 
     for(i=0;i<=d;i++) { 
      k = i + j*(d+1); 
      v[k*2] = i - d2; 
      v[k*2+1] = j - d2; 
      if(i<d&&j<d) { 
      n = (i + j*d) * 6; 
      fi[n] = k; 
      fi[n+1] = k + 1; 
      fi[n+2] = k + d + 1; 
      fi[n+3] = k + d + 1; 
      fi[n+4] = k + 1; 
      fi[n+5] = k + d + 2; 
      } 
     } 

     for(i=0,j=-1;i<fi.length;i++) 
     if(j<fi[i]) 
      j = fi[i]; 

     m = new THREE.Mesh(new THREE.BufferGeometry(), mat); 
     m.geometry.setIndex(new THREE.BufferAttribute(fi, 1)); 
     m.geometry.addAttribute('pos', new THREE.BufferAttribute(v, 2)); 

     return m; 

    } 

只是改變你的邏輯代碼,並運行。 歡呼!

+0

謝謝@muhammad這是我想要的,你救了我的命。 – maksible