이 글은 three.js를 통해 3D 시네마의 기능과 원리 분석을 구현하는 방법을 주로 설명하고 있습니다.
이 글에서는 3D 시네마의 시각적 원리를 소개하고 three.js 이벤트 처리 프로세스를 소개하여 3D 시네마 구현에 대한 기본 지식을 종합적으로 분석합니다.
1. 3D 공간 만들기
방이 큐브라고 상상해 보세요. 생활 취향이 좋으면 Three.js를 통해 쉽게 만들 수 있습니다. 그리고 카메라가 큐브 안에 있고 카메라가 360도 회전할 수 있도록 주변에 텍스처를 추가하여 실제 장면을 시뮬레이션합니다.
코드로 변환됨:
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 모델은 점, 선 및 표면 예, 모델의 모든 점을 탐색하고, 각 점을 기하학적 모델로 변환하고, 텍스처와 함께 붙여넣고, 각 점의 위치를 복사하고, 이러한 기하학적 모델을 사용하여 점만으로 모델을 재구성할 수 있습니다. 이것이 바로 입자 효과입니다. . 기본 원칙.
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 그룹은 입자의 집합이라고 할 수 있는 그룹을 생성합니다. point.position.copy(pos)를 통해 입자와 위치를 설정합니다. 좌표는 모델의 해당 지점의 위치와 동일합니다. 3. 클릭 이벤트 처리
three.js 클릭 이벤트에는 레이 캐스터(Raycaster)의 도움이 필요합니다. 이해를 돕기 위해 먼저 그림을 보십시오.
Raycaster는 광선을 방출하고 intersectObject는 객체를 모니터링합니다. hit by the ray
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은 광선이 닿는다는 의미입니다. 특정 지오메트리를 구현하는 데 게을러서 모바일 측에서만 클릭 구현을 구현했습니다. PC에서 구현하는 방법을 보려면 다음을 참조하세요. 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. 헤일로 효과
시뮬레이션 영화관이기 때문에 프로젝터에서 나오는 빛을 시뮬레이션하는 프로젝터를 만들고 싶습니다.
// 光晕效果必须设置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)
위 내용은 모두를 위해 제가 정리한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다.
관련 기사:
jquery를 사용하여 왼쪽 및 오른쪽 사이드바 크기 조정 효과를 얻는 방법
in Vue How jquery에서 숫자 입력 상자 구성 요소를 구현하는 방법
jquery에서 사용자 지정 메시지 표시 수를 구현하는 방법
Angular2에서 구성 요소 상호 작용을 구현하는 방법
소프트 키보드가 입력을 차단하는 문제를 해결하는 방법 js의 상자
위 내용은 three.js를 사용하여 3D 시네마를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!