Maison >interface Web >js tutoriel >Comment implémenter le cinéma 3D à l'aide de three.js
Cet article explique principalement comment réaliser les fonctions et l'analyse des principes du cinéma 3D via three.js. Les amis dans le besoin peuvent s'y référer.
Dans cet article, nous analysons de manière approfondie les connaissances de base de la mise en œuvre du cinéma 3D en présentant les principes visuels du cinéma 3D et en introduisant le processus de traitement des événements three.js.
1. Créez un espace 3D
Vous pouvez imaginer que nous sommes dans une pièce, et que la pièce est un cube. Si vous avez goût à la vie, vous pouvez mettre du papier peint dans la pièce. , three.js Vous pouvez facilement créer un cube et attacher des textures autour de lui afin que la caméra soit à l'intérieur du cube et que la caméra puisse pivoter à 360 degrés pour simuler une scène réelle.
Converti 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 et 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. Vous pouvez parcourir chaque point du modèle, convertir chaque point en modèle géométrique et le coller avec des graphiques, copier la position de chaque point et utiliser ces éléments géométriques. modèles Le modèle est reconstruit en un modèle avec uniquement des points. C'est le principe de base des effets de particules.
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 une collection de particules. Définissez les particules et la position via point.position.copy(pos). le point correspondant dans le modèle 3. Traitement des événements de clic
L'événement de clic de three.js nécessite l'aide d'un lanceur de rayons (Raycaster) Pour faciliter la compréhension, veuillez d'abord regarder une image :
.Raycaster émet un rayon, 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 > implémente uniquement l'implémentation du clic côté mobile. Si vous souhaitez voir comment l'implémenter sur PC, veuillez consulter le site officiel de js
4. Utilisation initiale des shaders
Les shaders sont divisés. en vertex shaders et fragment shaders, écrits en langage GLSL, qui est un langage qui communique avec le GPU, ici Parlez simplement de comment 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. Effet Halo
Depuis c'est un cinéma simulé, je souhaite réaliser un projecteur pour simuler la lumière émise par le 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)
J'ai compilé ce qui précède pour vous, j'espère que cela vous sera utile à l'avenir.
Articles connexes :
Introduction détaillée à la mise à jour des objets dans mangouste
Introduction détaillée à setTimeout dans la fonction JS
Comment utiliser jquery pour obtenir l'effet télescopique gauche et droit de la barre latérale
Comment implémenter le composant de zone de saisie de nombres dans Vue
Comment personnaliser le nombre de messages affichés dans jquery
Comment implémenter l'interaction des composants dans Angular2
Comment résoudre soft problèmes dans le clavier js couvrant la zone de saisie
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!