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.
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
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
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 :
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
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, })
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!