three实现一个三维遗迹建筑效果代码
代码语言:html
所属分类:三维
代码描述:three实现一个三维遗迹建筑效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> html, body { background: black; } body { height: 100vh; display: flex; justify-content: center; } #world { position: absolute; width: 100%; height: 100%; overflow: hidden; cursor: move; opacity: 0; animation: fadein 1s ease-out 3s forwards; } @keyframes fadein { from { opacity: 0; } to { opacity: 1; } } </style> </head> <body> <div id="world"></div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.123.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.126.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/LegacyJSONLoader.js"></script> <script> /* * The purpose is to easily create building structures. The building style was inspired by the Monument Valley game https://www.monumentvalleygame.com/mv2 * * Floorplan coordinates and building settings are at the very bottom of the page. */ let scene, renderer, controls, camera, floorplan, settings, light, grid, monumentSquareSize, monumentHeight, container; const width = window.innerWidth; const height = window.innerHeight; const aspectRatio = width / height; const fieldOfView = 25; const nearView = 1; const farView = 10000; const assetPath = '//repo.bfw.wiki/bfwrepo/json/model'; const blockSize = 20; // Value need to remain 20 in order to match assets ratio exported from Blender window.addEventListener('load', () => { settings = data.settings; document.body.style.background = `rgb(${settings.background})`; floorplan = data.floorplan; init(); animate(); }); function init() { grid = floorplan[0][0].length; monumentSquareSize = blockSize * grid; monumentHeight = blockSize * floorplan.length; // Scene Setting renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(width, height); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; // Create the scene. scene = new THREE.Scene(); // Camera Setting if (settings.perspectiveCamera) { // Perspective Camera camera = new THREE.PerspectiveCamera(fieldOfView, aspectRatio, nearView, farView); camera.position.set(800, -800, 800); camera.up = new THREE.Vector3(0, 0, 1); } else { // Orthographic Camera camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, -1000, 5000); camera.position.set(20, -20, 20); camera.up = new THREE.Vector3(0, 0, 1); } // Point Light Setting light = new THREE.PointLight(`rgb(${settings.globalLight})`, 12, 1000); light.position.set(600, -200, 250 + monumentHeight); light.castShadow = true; scene.add(light, new THREE.AmbientLight(`rgb(${settings.ambientLight})`)); // Floor Setting // const floorGeometry = new THREE.CircleGeometry(600, 600) // floorGeometry.translate(0, 0, -200) // const floorMaterial = new THREE.MeshLambertMaterial({ // color: `rgb(${settings.floor})` // }) // const floor = new THREE.Mesh(floorGeometry, floorMaterial) // floor.receiveShadow = true; // scene.add(floor) // Mouse Interaction Setting controls = new THREE.OrbitControls(camera, renderer.domElement); controls.minPolarAngle = Math.PI / 2 - 0.5; controls.maxPolarAngle = Math.PI / 2 - 0.5; controls.autoRotate = settings.autoRotate; controls.autoRotateSpeed = settings.rotationSpeed; controls.zoomSpeed = 0.3; controls.minZoom = 0.5; controls.maxZoom = 2.5; controls.enableDamping = true; controls.dampingFactor = 0.15; // Add the Renderer to the DOM, in the world div. container = document.getElementById('world'); container.appendChild(renderer.domElement); floorplanRenderer(); //RESPONSIVE LISTENER window.addEventListener('resize', onWindowResize, false); } function floorplanRenderer() { let zPos = -monumentSquareSize - settings.offsetY,yPos = 0,xPos = 0; for (let z = 0; z < floorplan.length; z++) { let reversedZ = floorplan.length - (z + 1); zPos += blockSize; xPos = monumentSquareSize / 2; for (let x = 0; x < floorplan[reversedZ].length; x++) { let reversedX = floorplan[reversedZ].length - (x + 1); xPos -= blockSize; yPos = monumentSquareSize / 2; for (let y = 0; y < floorplan[reversedZ][reversedX].length; y++) { let reversedY = floorplan[reversedZ][reversedX].length - (y + 1); let cell = floorplan[reversedZ][reversedX][reversedY]; let shape = null; yPos -= blockSize; switch (cell) { case 1: shape = new Cube(xPos, yPos, zPos, `rgb(${settings.cube})`, blockSize); break; case 2: shape = new Shape(xPos, yPos, zPos, `rgb(${settings.tale})`, `${assetPath}/tail1.json`, 1); break; case 3: shape = new Shape(xPos, yPos, zPos, `rgb(${settings.stairs})`, `${assetPath}/stairs1.json`, 1, 7.855); break; case 4: shape = new Light(xPos, yPos, zPos, `rgb(${settings.pointLight})`, settings.pointLightScale); break; case 5: shape = new Shape(xPos, yPos, zPos, `rgb(${settings.pillar})`, `${assetPath}/pillar1.json`, 1); break;} if (shape !== null) shape.render(); } } } } function onWindowResize() { camera.left = window.innerWidth / -2; camera.right = window.innerWidth / 2; camera.top = window.innerHeight / 2; camera.bottom = window.innerHeight / -2; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } function renderView() { // let time = Date.now() * 0.0005 // firefly.position.set(0, 0, Math.sin(time*3)*10) renderer.render(scene, camera); } function animate() { requestAnimationFrame(animate); controls.update(); renderView(); } class Cube { constructor(x, y, z, color, size, rotate = 0) { this.x = x; this.y = y; this.z = z; this.color = color; this.size = size; this.rotate = rotate; } render() { let boxGeometry = new THREE.BoxGeometry(this.size, this.size, this.size); let lambertMaterial = new THREE.MeshLambertMaterial({ color: this.color // overdraw: 1, }); let mesh = new THREE.Mesh(boxGeometry, lambertMaterial); mesh.position.x = this.x; mesh.position.y = this.y; mesh.position.z = this.z; mesh.rotation.y = this.rotate; scene.add(mesh); }} class Shape { constructor(x, y, z, color, source, scale = 1, rotate = 0) { this.x = x; this.y = y; this.z = z; this.color = color; this.source = source; this.scale = scale; this.rotate = rotate; } render() { let loader = new THREE.LegacyJSONLoader(); loader.load(this.source, geometry => { let mesh = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({ color: this.color // overdraw: 1 })); mesh.position.x = this.x; mesh.position.y = this.y; mesh.position.z = this.z; mesh.rotation.x = Math.PI / 2; mesh.rotation.y = this.rotate; mesh.scale.set(this.scale, this.scale, this.scale); scene.add(mesh); }); }} class Light { constructor(x, y, z, color, size = 0) { this.x = x; this.y = y; this.z = z; this.color = color; this.size = size; } render() { let pointLight = new THREE.PointLight(this.color, 1.1, 100); if (this.size !== 0) { let sphereGeometry = new THREE.SphereGeometry(this.size, 50, 50); let basicMaterial = new THREE.MeshBasicMaterial({ color: this.color }); let lightBulbe = new THREE.Mesh(sphereGeometry, basicMaterial); pointLight.add(lightBulbe); } let time = Date.now() * 0.0005; // firefly.position.set(0, 0, Math.sin(time*3)*10) pointLight.position.set(this.x, this.y, this.z + Math.sin(time * 3) * 10); pointLight.castShadow = true; scene.add(pointLight); }} /* * block = 1 * tile = 2 * staircase = 3 * firefly = 4 * 4 pillar = 5 */ let data = { "settings": { "perspectiveCamera": false, "autoRotate": true, "rotationSpeed": 0.25, "offsetY": -30, "background": "0, 0, 16", "globalLight": "255, 255, 255", "ambientLight": "0, 0, 32", "cube": "107, 126, 127", "tale": "81, 91, 95", "stairs": "107, 126, 127", "pointLight": "255, 255, 255", "pointLightScale": 2, "pillar": "107, 126, 127" }, "floorplan": [ [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, .........完整代码请登录后点击上方下载按钮下载查看
网友评论0