Maison  >  Article  >  interface Web  >  Three.js implémente le partage d'exemples de cinéma 3D sympas

Three.js implémente le partage d'exemples de cinéma 3D sympas

小云云
小云云original
2017-12-18 15:48:292109parcourir

Vous pouvez imaginer que nous sommes dans une pièce. La pièce est un cube Si vous avez bon goût dans la vie, vous pouvez mettre du papier peint dans la pièce. Three.js peut facilement créer un cube et ajouter des textures autour. , placez la caméra dans le cube et la caméra peut pivoter à 360 degrés pour simuler une scène réelle. Cet article vous expliquera comment implémenter un cinéma 3D sympa à l'aide de three.js.

Convertir en code :

    const path = 'assets/image/'
    const format = '.jpg'
    const urls = [
      `${path}px${format}`, `${path}nx${format}`,
      `${path}py${format}`, `${path}ny${format}`,
      `${path}pz${format}`, `${path}nz${format}`
    ]
    const materials = []
    urls.forEach(url => {
      const textureLoader = new TextureLoader()
      textureLoader.setCrossOrigin(this.crossOrigin)
      const texture = textureLoader.load(url)
      materials.push(new MeshBasicMaterial({
        map: texture,
        overdraw: true,
        side: BackSide
      }))
    })
    const cube = new Mesh(new CubeGeometry(9000, 9000, 9000), new MeshFaceMaterial(materials))
    this.scene.add(cube)
  • CubeGeometry crée un cube surdimensionné

  • MeshFaceMaterial attache une texture au cube, puisque la perspective est à l'intérieur du cube, côté : BackSide

2. Effet particule

Un modèle 3D est composé de points, de lignes et de surfaces, et le modèle peut être parcouru Pour chaque point, convertissez chaque point en modèle géométrique, attachez-y une texture, copiez la position de chaque point et utilisez ces modèles géométriques pour reconstruire un modèle avec uniquement des points.

this.points = new Group()
    const vertices = []
    let point
    const texture = new TextureLoader().load('assets/image/dot.png')
    geometry.vertices.forEach((o, i) => {
      // 记录每个点的位置
      vertices.push(o.clone())
      const _geometry = new Geometry()
     // 拿到当前点的位置
      const pos = vertices[i]
      _geometry.vertices.push(new Vector3())
      const color = new Color()
      color.r = Math.abs(Math.random() * 10)
      color.g = Math.abs(Math.random() * 10)
      color.b = Math.abs(Math.random() * 10)
      const material = new PointsMaterial({
        color,
        size: Math.random() * 4 + 2,
        map: texture,
        blending: AddEquation,
        depthTest: false,
        transparent: true
      })
      point = new Points(_geometry, material)
      point.position.copy(pos)
      this.points.add(point)
    })
    return this.points
  • un nouveau groupe crée un groupe, qui peut être considéré comme un ensemble de particules

  • Définissez les particules via point.position. copy(pos) La position et les coordonnées sont les mêmes que la position du point correspondant dans le modèle

3. Traitement de l'événement de clic

L'événement de clic sur trois. js nécessite l'utilisation d'un lanceur de rayons (Raycaster), pour une compréhension facile, veuillez d'abord regarder une image :

Three.js implémente le partage d'exemples de cinéma 3D sympas

Raycaster émet un rayon, et intersectObject surveille l'objet touché par le rayon

this.raycaster = new Raycaster()

// 把你要监听点击事件的物体用数组储存起来
this.seats.push(seat)

onTouchStart(event) {
    event.preventDefault()
    event.clientX = event.touches[0].clientX;
    event.clientY = event.touches[0].clientY;
    this.onClick(event)
  }

  onClick(event) {
    const mouse = new Vector2()
    mouse.x = ( event.clientX / this.renderer.domElement.clientWidth ) * 2 - 1
    mouse.y = - ( event.clientY / this.renderer.domElement.clientHeight ) * 2 + 1;
    this.raycaster.setFromCamera(mouse, this.camera)
   // 检测命中的座位
    const intersects = this.raycaster.intersectObjects(this.seats)
    if (intersects.length > 0) {
        intersects[0].object.material = new MeshLambertMaterial({
            color: 0xff0000
        })
    }
  }
  • intersects.length > 0 signifie que le rayon atteint une certaine géométrie

  • Être paresseux, je n'ai implémenté l'implémentation du clic que du côté mobile. Si vous voulez voir comment l'implémenter sur PC, veuillez consulter le site officiel de thee.js

4. Utilisation préliminaire des shaders.

Les shaders sont divisés en vertex shaders et fragment shaders, écrits en langage GLSL Un langage qui communique avec le GPU, nous parlons ici uniquement de la façon de l'utiliser

const vertext = `
   void main()
    {
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
    }
  `

const fragment = `
    uniform vec2 resolution;
    uniform float time;

    vec2 rand(vec2 pos)
    {
    return fract( 0.00005 * (pow(pos+2.0, pos.yx + 1.0) * 22222.0));
    }
    vec2 rand2(vec2 pos)
    {
    return rand(rand(pos));
    }

    float softnoise(vec2 pos, float scale)
    {
    vec2 smplpos = pos * scale;
    float c0 = rand2((floor(smplpos) + vec2(0.0, 0.0)) / scale).x;
    float c1 = rand2((floor(smplpos) + vec2(1.0, 0.0)) / scale).x;
    float c2 = rand2((floor(smplpos) + vec2(0.0, 1.0)) / scale).x;
    float c3 = rand2((floor(smplpos) + vec2(1.0, 1.0)) / scale).x;

    vec2 a = fract(smplpos);
    return mix(
    mix(c0, c1, smoothstep(0.0, 1.0, a.x)),
    mix(c2, c3, smoothstep(0.0, 1.0, a.x)),
    smoothstep(0.0, 1.0, a.y));
    }

    void main(void)
    {
    vec2 pos = gl_FragCoord.xy / resolution.y;
    pos.x += time * 0.1;
    float color = 0.0;
    float s = 1.0;
    for(int i = 0; i < 8; i++)
    {
    color += softnoise(pos+vec2(i)*0.02, s * 4.0) / s / 2.0;
    s *= 2.0;
    }
    gl_FragColor = vec4(color);
    }
  `
// 设置物体的质材为着色器质材
 let material = new ShaderMaterial({
        uniforms: uniforms,
        vertexShader: vertext,
        fragmentShader: fragment,
        transparent: true,
      })

5. Halo. effet

Puisqu'il s'agit d'un cinéma simulé, je souhaite réaliser un projecteur et simuler l'émission de lumière du projecteur.

 // 光晕效果必须设置alpha = true
 const renderer = this.renderer = new WebGLRenderer({alpha: true, antialias: true})

 let textureFlare = new TextureLoader().load('assets/image/lensflare0.png')
      let textureFlare3 = new TextureLoader().load('assets/image/lensflare3.png')
      let flareColor = new Color(0xffffff)
      let lensFlare = new LensFlare(textureFlare, 150, 0.0 , AdditiveBlending, flareColor)
      lensFlare.add(textureFlare3, 60, 0.6, AdditiveBlending);
      lensFlare.add(textureFlare3, 70, 0.7, AdditiveBlending);
      lensFlare.add(textureFlare3, 120, 0.9, AdditiveBlending);
      lensFlare.add(textureFlare3, 70, 1.0, AdditiveBlending);
      lensFlare.position.set(0, 150, -85)
  • La lumière principale est toujours simulée par lensflare0.png

  • textureFlare3 définit la portée du halo

Recommandations associées :

Introduction de base de la bibliothèque JS à Three.js

Comment créer une scène avec Three.js

Mur de photos 3D basé sur three.js et WeChat

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn