///<reference path="../node_modules/three/build/three.js" /> //<reference path="../node_modules/three/examples/js/loaders/GLTFLoader.js" /> "use strict"; /** * Loads a GLTF resource and retruns the data as a promise. * @param {THREE.GLTFLoader} loader instance of the loader to use. * @param {string} path URL from where to download. * @returns {Promise<{scene: THREE.Scene}>} */ function downloadModel(loader, path) { return new Promise(function(resolve, reject){ loader.load( path, function onLoadModel(gltf){ resolve(gltf); }, null, function(error){ reject(error); } ); }); } document.addEventListener("DOMContentLoaded", async function pageInit(){ /** @type {HTMLCanvasElement} */ const canvas = document.getElementById("playground"); const canvasWidth = Math.floor(canvas.clientWidth); const canvasHeight = Math.floor(canvas.clientHeight); const scene = new THREE.Scene(); scene.background = new THREE.Color(0x020202); const camera = new THREE.PerspectiveCamera(50, canvasWidth / canvasHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById("playground"), antialias: true }); renderer.setSize(canvasWidth, canvasHeight); // renderer.shadowMap.enabled = true; // renderer.shadowMap.type = THREE.PCFSoftShadowMap; document.body.appendChild(renderer.domElement); const geometry = new THREE.BoxGeometry(1,1,1); const material = new THREE.MeshPhongMaterial({color: 0x4512ff}) const cube = new THREE.Mesh(geometry, material); cube.position.set(2,0,0); cube.castShadow = true; scene.add(cube); camera.position.z = 5; const light = new THREE.PointLight(0xffffff, 1, 50); light.position.set(5,5,5); light.castShadow = true; light.shadow.mapSize.width = 1024; light.shadow.mapSize.height = 1024; scene.add(light); const backLight = new THREE.PointLight(0xffffff, 0.1, 50); backLight.position.set(-5,5,5); scene.add(backLight); // const plane = new THREE.Mesh( // new THREE.PlaneBufferGeometry(5, 5, 10, 10), // new THREE.MeshPhongMaterial({color: 0xffffff}) // ); // plane.rotateX(-Math.PI/2); // plane.position.y = -1; // plane.receiveShadow = true; // scene.add(plane); const loader = new THREE.GLTFLoader(); const wordGLTF = await downloadModel(loader, "models/infinity-symbol.gltf"); const word = wordGLTF.scene.children.find(c => c.name == "infinity"); word.castShadow = true; // word.receiveShadow = true; word.rotation.set(0,0,0); word.position.set(-2,0,0); scene.add(word); /** @type {THREE.Object3D} */ let clonedWord = null; const randomScatter = (r) => (r || 5)*(Math.random()-0.5); const wordCloud = []; const wordGroup = new THREE.Group(); for(let i=0;i<100;i++) { clonedWord = word.clone(false); clonedWord.position.set(randomScatter(),randomScatter(),randomScatter()); clonedWord.rotation.set(randomScatter(Math.PI),randomScatter(Math.PI),randomScatter(Math.PI)); clonedWord.scale.set(1,1,1); wordGroup.add(clonedWord); wordCloud.push(clonedWord); } scene.add(wordGroup); renderer.gammaInput = true; renderer.gammaOutput = true; // const helper = new THREE.CameraHelper(light.shadow.camera); // scene.add(helper); // renderer.render(scene, camera); function animate(){ requestAnimationFrame(animate); word.rotation.x += 0.01; word.rotation.y += 0.01; cube.rotation.x += 0.01; cube.rotation.y -= 0.01; wordGroup.rotation.x -= 0.01; wordGroup.rotation.y += 0.01; wordCloud.forEach(w => { w.rotation.x += 0.02; w.rotation.y += 0.02; }); renderer.render(scene, camera); } animate(); });