UNPKG

aframe-shader-buildings

Version:

An A-Frame WebVR component for cheaply creating thousands of boxy buildings.

217 lines (197 loc) 12.3 kB
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>aframe-shader-buildings example</title> <meta name="description" content="A low-cost VR city, using aframe-shader-buildings"> <script src="https://aframe.io/releases/1.4.0/aframe.min.js"></script> <script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras@fb96ab2/dist/aframe-extras.controls.min.js"></script> <script src="dist/main.js"></script> <script src="https://unpkg.com/aframe-simple-sun-sky@^1.2.3/simple-sun-sky.js"></script> <script> AFRAME.registerComponent('city', { init: function () { let sceneEl = this.el; const numStyles = 6; let buildings = this.randomBuildings(numStyles); // array of arrays let buildingEls = new Array(numStyles); buildingEls[0] = document.createElement('a-shader-buildings'); buildingEls[0].setAttribute('wall-src', '#brick'); buildingEls[0].setAttribute('wall-color', '#6e2b11'); // brick red buildingEls[0].setAttribute('px', '#px'); buildingEls[0].setAttribute('nx', '#nx'); buildingEls[0].setAttribute('py', '#py'); buildingEls[0].setAttribute('ny', '#ny'); buildingEls[0].setAttribute('nz', '#nz'); buildingEls[0].setAttribute('window-opacity', '0.2'); buildingEls[1] = document.createElement('a-shader-buildings'); buildingEls[1].setAttribute('x-proportion-geometry', 4); buildingEls[1].setAttribute('x-proportion-material', 4); buildingEls[1].setAttribute('z-proportion-geometry', 4); buildingEls[1].setAttribute('z-proportion-material', 4); buildingEls[1].setAttribute('y-proportion-geometry', 3.5); buildingEls[1].setAttribute('y-proportion-material', 3.5); buildingEls[1].setAttribute('window-width', -0.5); buildingEls[1].setAttribute('window-height', 0.0); buildingEls[1].setAttribute('wall-src', '#brick'); buildingEls[1].setAttribute('wall-zoom', 2.25); buildingEls[1].setAttribute('wall-color', '#6e2b11'); // brick red buildingEls[1].setAttribute('window-opacity', '0.9'); buildingEls[2] = document.createElement('a-shader-buildings'); buildingEls[2].setAttribute('x-proportion-geometry', 6); buildingEls[2].setAttribute('x-proportion-material', 6); buildingEls[2].setAttribute('z-proportion-geometry', 6); buildingEls[2].setAttribute('z-proportion-material', 6); buildingEls[2].setAttribute('y-proportion-geometry', 4.5); buildingEls[2].setAttribute('y-proportion-material', 4.5); buildingEls[2].setAttribute('window-width', -0.5); buildingEls[2].setAttribute('window-height', 0.3); buildingEls[2].setAttribute('wall-src', '#concrete'); buildingEls[2].setAttribute('wall-zoom', 1.5); buildingEls[2].setAttribute('wall-color', '#a0a0a0'); // light gray buildingEls[2].setAttribute('px', '#px'); buildingEls[2].setAttribute('nx', '#nx'); buildingEls[2].setAttribute('py', '#py'); buildingEls[2].setAttribute('ny', '#ny'); buildingEls[2].setAttribute('nz', '#nz'); buildingEls[2].setAttribute('window-opacity', '0.3'); buildingEls[3] = document.createElement('a-shader-buildings'); buildingEls[3].setAttribute('x-proportion-geometry', 6); buildingEls[3].setAttribute('x-proportion-material', 6); buildingEls[3].setAttribute('z-proportion-geometry', 6); buildingEls[3].setAttribute('z-proportion-material', 6); buildingEls[3].setAttribute('y-proportion-geometry', 5.5); buildingEls[3].setAttribute('y-proportion-material', 5.5); buildingEls[3].setAttribute('window-width', 0.95); buildingEls[3].setAttribute('window-height', 0.0); buildingEls[3].setAttribute('wall-src', '#concreteBlocks'); buildingEls[3].setAttribute('wall-zoom', 3.0); buildingEls[3].setAttribute('wall-color', '#a0a0a0'); // light gray buildingEls[3].setAttribute('equirectangular', '#equirectangular'); buildingEls[3].setAttribute('window-opacity', '0.8'); buildingEls[4] = document.createElement('a-shader-buildings'); buildingEls[4].setAttribute('y-proportion-geometry', 5); buildingEls[4].setAttribute('y-proportion-material', 5); buildingEls[4].setAttribute('window-width', 0.5); buildingEls[4].setAttribute('window-height', 0.0); buildingEls[4].setAttribute('wall-src', '#stoneBlocks'); buildingEls[4].setAttribute('wall-zoom', 4.5); buildingEls[4].setAttribute('wall-color', '#909090'); // light gray buildingEls[4].setAttribute('px', '#px'); buildingEls[4].setAttribute('nx', '#nx'); buildingEls[4].setAttribute('py', '#py'); buildingEls[4].setAttribute('ny', '#ny'); buildingEls[4].setAttribute('nz', '#nz'); buildingEls[4].setAttribute('window-opacity', '0.4'); buildingEls[5] = document.createElement('a-shader-buildings'); buildingEls[5].setAttribute('window-width', 0.8); buildingEls[5].setAttribute('window-height', -0.1); buildingEls[5].setAttribute('wall-src', '#stoneBlocks'); buildingEls[5].setAttribute('wall-zoom', 5.0); buildingEls[5].setAttribute('wall-color', '#675342'); // brown brick buildingEls[5].setAttribute('equirectangular', '#equirectangular'); buildingEls[5].setAttribute('window-opacity', '0.7'); for (let s=0; s<numStyles; ++s) { buildingEls[s].setAttribute('elevation-geometry', 10); buildingEls[s].setAttribute('elevation-material', 10); buildingEls[s].setAttribute('sun-position', "-0.3 1.0 0.7"); buildingEls[s].setAttribute('buildings', JSON.stringify(buildings[s])); buildingEls[s].classList.add('landscape'); sceneEl.appendChild(buildingEls[s]); } }, randomBuildings: function (numStyles) { let buildings = new Array(numStyles); for (let s=0; s<numStyles; ++s) { buildings[s] = []; } for (let i=-15.5; i<=15.5; ++i) { for (let j = -15.5; j <= 15.5; ++j) { let xCoreSections = 1 + Math.floor(Math.random() * 4); let xWingSections = Math.floor(Math.random() * 4); let zCoreSections = 1 + Math.floor(Math.random() * 4); let zWingSections = Math.floor(Math.random() * 4); let ySections = Math.ceil((Math.exp(Math.random()) - 0.99999) * 20) + Math.random() * 0.2; // sanity-checks proportions if (xWingSections >= 2 && zCoreSections < 2) { ++zCoreSections } if (zWingSections >= 2 && xCoreSections < 2) { ++xCoreSections } if (ySections >= 2) { while (xCoreSections + xWingSections < 2) { ++xCoreSections; } while (zCoreSections + zWingSections < 2) { ++zCoreSections; } } if (ySections >= 10) { while (zCoreSections + zWingSections < 3) { ++zCoreSections; } } if (ySections >= 20) { while (xCoreSections + xWingSections < 3) { ++xCoreSections; } } let building = { x: i * 60, // common multiple of x-proportion for building styles z: j * 60, // common multiple of z-proportion for building styles xCoreSections: xCoreSections, xWingSections: xWingSections, zCoreSections: zCoreSections, zWingSections: zWingSections, ySections: ySections, }; let style = Math.floor(Math.random() * numStyles); if (0 === style % 2) { // makes some walls blank (only works if windowWidth is not too great) if (zCoreSections <= 2 && Math.random() < 0.3) { building.xWingSections += 0.13; } else if (xCoreSections <= 2 && Math.random() < 0.3) { building.zWingSections += 0.13; } else if (zCoreSections + zWingSections <= 4.5 && Math.random() < 0.1) { building.xCoreSections += 0.13; } else if (xCoreSections + xWingSections <= 4.5 && Math.random() < 0.1) { building.zCoreSections += 0.13; } } buildings[style].push(building); } } return buildings; } }); </script> </head> <body> <a-scene city gridhelperXXX="size: 2000; divisions: 400" background="color:#87cefa"> <a-assets> <img id="brick" src="./assets/TexturesCom_Wall_BrickPlain1_512_albedo.jpg"> <img id="concrete" src="./assets/TexturesCom_Concrete_ExposedAggregate_512_albedo.jpg"> <img id="concreteBlocks" src="./assets/TexturesCom_ConcreteBlocks_New_512_albedo.jpg"> <img id="stoneBlocks" src="./assets/TexturesCom_BrickMedievalBlocks0327_5_seamless_S_512.jpeg"> <img id="equirectangular" src="assets/reading_room_1k.jpg"> <img id="px" src="assets/MarriottMadisonWest/px.jpg"> <img id="nx" src="assets/MarriottMadisonWest/nx.jpg"> <img id="py" src="assets/MarriottMadisonWest/py.jpg"> <img id="ny" src="assets/MarriottMadisonWest/ny.jpg"> <img id="nz" src="assets/MarriottMadisonWest/nz.jpg"> </a-assets> <a-plane position="0 9.95 0" rotation="-90 0 0" width="2000" height="2000" color="#276B48"></a-plane> <!-- The "Burj Synthetica" --> <a-shader-buildings window-opacity="0.9" elevation-geometry="10" elevation-material="10" sun-position="-0.3 1.0 0.7" buildings= '[{"x":5,"z":-995,"xCoreSections":7,"xWingSections":5,"zCoreSections":7,"zWingSections":5,"ySections":30},{"x":0,"z":-1000,"y":120,"xCoreSections":5,"xWingSections":4,"zCoreSections":5,"zWingSections":4,"ySections":30},{"x":-5,"z":-1005,"y":240,"xCoreSections":3,"xWingSections":3,"zCoreSections":3,"zWingSections":3,"ySections":30},{"x":-5,"z":-1005,"y":360,"xCoreSections":2,"xWingSections":1,"zCoreSections":2,"zWingSections":1,"ySections":30}]' ></a-shader-buildings> <a-entity id="rig" movement-controls="fly:true; speed:0.9;" position="0 32 0"> <a-entity camera look-controls position="0 1.6 0"></a-entity> </a-entity> <a-simple-sun-sky radius="1500" sun-position="-0.3 1.0 0.7"></a-simple-sun-sky> <a-entity light="type: ambient; color: #BBB"></a-entity> <a-entity light="type: directional; color: #FFF; intensity: 0.6" position="-0.3 1.0 0.7"></a-entity> </a-scene> </body> </html>