> 웹 프론트엔드 > JS 튜토리얼 > Three.js는 멋진 3D 영화 예제 공유를 구현합니다.

Three.js는 멋진 3D 영화 예제 공유를 구현합니다.

小云云
풀어 주다: 2017-12-18 15:48:29
원래의
2199명이 탐색했습니다.

우리가 방에 있고 그 방이 큐브라고 상상할 수 있습니다. 생활 취향이 좋으면 방에 벽지를 놓을 수도 있습니다. Three.js는 쉽게 큐브를 만들고 그 주위에 텍스처를 붙여 넣을 수 있습니다. 카메라는 큐브 안에 있으며 360도 회전하여 실제 장면을 시뮬레이션할 수 있습니다. 이 기사에서는 three.js를 사용하여 멋진 3D 시네마를 구현하는 방법을 공유할 것입니다.

코드로 변환:

    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는 매우 큰 큐브를 만듭니다

  • MeshFaceMaterial은 큐브 내부에 텍스처를 첨부하므로 측면: BackSide

2. 3D 모델은 점, 선, 면으로 구성되어 있으며, 모델의 모든 점을 횡단하고, 각 점을 기하학적 모델로 변환하고, 여기에 텍스트와 그래픽을 첨부하고, 각 점의 위치를 ​​복사하여 이러한 기하학적 모델을 사용할 수 있습니다. 3D 모델을 점만으로 재구성하는 것이 입자 효과의 기본 원리입니다.

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
로그인 후 복사

    new Group은 파티클의 집합체라고 할 수 있는 그룹을 생성합니다
  • point.position.copy(pos)를 통해 파티클과 위치를 설정하면 좌표는 파티클의 위치와 동일합니다. 모델의 해당 지점
  • 3. 클릭 이벤트 처리

three.js의 클릭 이벤트에는 레이 캐스터(Raycaster)의 도움이 필요합니다. 먼저 그림을 살펴보세요.

Three.js는 멋진 3D 영화 예제 공유를 구현합니다.Raycaster는 광선을 방출하고 intersectObject는 광선에 맞은 객체를 모니터링합니다.

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은 광선이 특정 형상에 닿는 것을 의미합니다.
  • 게으르고 클릭 구현만 구현했습니다. 모바일측에서 어떻게 구현하는지 보고 싶으시면 thee.js 공식 홈페이지
  • 4. 셰이더의 초기 사용법

셰이더는 버텍스 셰이더와 프래그먼트 셰이더로 나누어져 있습니다. , GPU와 통신하는 언어입니다. 여기서는 사용법에 대해서만 이야기하겠습니다

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 effect

시뮬레이션 영화이기 때문에 프로젝터에서 나오는 빛을 시뮬레이션할 수 있는 프로젝터를 만들고 싶었습니다. .

r
 // 光晕效果必须设置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)
로그인 후 복사
re 메인 라이트는 여전히 Lensflare0.png

  • textureflare3에 의해 시뮬레이션되어 Halo related 권장 사항의 범위를 설정합니다. Three.js의 장면 만드는 방법

  • three.js와 WeChat을 기반으로 한 3D 포토월

위 내용은 Three.js는 멋진 3D 영화 예제 공유를 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿