|
|
@@ -15,9 +15,9 @@
|
|
|
<body>
|
|
|
<div id="info">
|
|
|
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> batch lod bvh - <a href="https://github.com/agargaro/batched-mesh-extensions" target="_blank" rel="noopener">@three.ez/batched-mesh-extensions</a><br/>
|
|
|
- BatchedMesh with 10 geometries and 500k instances. Each geometry has 5 LODs (4 generated with meshoptimizer). <br>
|
|
|
+ BatchedMesh with 10 geometries and 500k instances.<br>
|
|
|
+ Each geometry has 5 LODs (4 generated with meshoptimizer). <br>
|
|
|
Frustum culling and raycasting are accelerated by using BVHs (TLAS & BLAS). <br>
|
|
|
- See <a href="https://github.com/agargaro/batched-mesh-extensions" target="_blank" rel="noopener">main project repository</a> for more information and examples on BatchedMesh extensions.
|
|
|
</div>
|
|
|
|
|
|
<script type="importmap">
|
|
|
@@ -42,6 +42,7 @@
|
|
|
import * as THREE from 'three';
|
|
|
import Stats from 'three/addons/libs/stats.module.js';
|
|
|
import { MapControls } from 'three/addons/controls/MapControls.js';
|
|
|
+ import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
|
|
|
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
|
|
|
|
|
|
import { acceleratedRaycast, computeBatchedBoundsTree } from 'three-mesh-bvh';
|
|
|
@@ -63,7 +64,7 @@
|
|
|
let batchedMesh;
|
|
|
let lastHoveredInstance = null;
|
|
|
const lastHoveredColor = new THREE.Color();
|
|
|
- const yellow = new THREE.Color( 'yellow' );
|
|
|
+ const highlight = new THREE.Color( 'red' );
|
|
|
|
|
|
const raycaster = new THREE.Raycaster();
|
|
|
const mouse = new THREE.Vector2( 1, 1 );
|
|
|
@@ -77,25 +78,30 @@
|
|
|
|
|
|
async function init() {
|
|
|
|
|
|
- // environment
|
|
|
- camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 600 );
|
|
|
- camera.position.set( 0, 10, 50 );
|
|
|
-
|
|
|
- scene = new THREE.Scene();
|
|
|
- scene.fog = new THREE.Fog( 0x000000, 500, 600 );
|
|
|
-
|
|
|
- const ambient = new THREE.AmbientLight();
|
|
|
- scene.add( camera, ambient );
|
|
|
-
|
|
|
- const dirLight = new THREE.DirectionalLight( 'white', 2 );
|
|
|
- camera.add( dirLight, dirLight.target );
|
|
|
-
|
|
|
// renderer
|
|
|
renderer = new THREE.WebGLRenderer( { antialias: true } );
|
|
|
renderer.setPixelRatio( window.devicePixelRatio );
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
+ renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
|
+ renderer.toneMappingExposure = 0.8;
|
|
|
document.body.appendChild( renderer.domElement );
|
|
|
|
|
|
+ //
|
|
|
+
|
|
|
+ scene = new THREE.Scene();
|
|
|
+ // scene.fog = new THREE.Fog( 0x000000, 500, 600 );
|
|
|
+
|
|
|
+ const pmremGenerator = new THREE.PMREMGenerator( renderer );
|
|
|
+ scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture;
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
+ camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.1, 1000 );
|
|
|
+ camera.position.set( 0, 20, 55 );
|
|
|
+ scene.add( camera );
|
|
|
+
|
|
|
+ //
|
|
|
+
|
|
|
raycaster.firstHitOnly = true;
|
|
|
|
|
|
stats = new Stats();
|
|
|
@@ -122,7 +128,7 @@
|
|
|
|
|
|
// create BatchedMesh
|
|
|
const { vertexCount, indexCount, LODIndexCount } = getBatchedMeshLODCount( geometriesLODArray );
|
|
|
- batchedMesh = new THREE.BatchedMesh( instancesCount, vertexCount, indexCount, new THREE.MeshStandardMaterial( { metalness: 0.2, roughness: 0.2 } ) );
|
|
|
+ batchedMesh = new THREE.BatchedMesh( instancesCount, vertexCount, indexCount, new THREE.MeshStandardMaterial( { metalness: 1, roughness: 0.8 } ) );
|
|
|
|
|
|
// enable radix sort for better performance
|
|
|
batchedMesh.customSort = createRadixSort( batchedMesh );
|
|
|
@@ -132,8 +138,8 @@
|
|
|
|
|
|
const geometryLOD = geometriesLODArray[ i ];
|
|
|
const geometryId = batchedMesh.addGeometry( geometryLOD[ 0 ], - 1, LODIndexCount[ i ] );
|
|
|
- batchedMesh.addGeometryLOD( geometryId, geometryLOD[ 1 ], 15 );
|
|
|
- batchedMesh.addGeometryLOD( geometryId, geometryLOD[ 2 ], 75 );
|
|
|
+ batchedMesh.addGeometryLOD( geometryId, geometryLOD[ 1 ], 50 );
|
|
|
+ batchedMesh.addGeometryLOD( geometryId, geometryLOD[ 2 ], 100 );
|
|
|
batchedMesh.addGeometryLOD( geometryId, geometryLOD[ 3 ], 125 );
|
|
|
batchedMesh.addGeometryLOD( geometryId, geometryLOD[ 4 ], 200 );
|
|
|
|
|
|
@@ -252,7 +258,7 @@
|
|
|
if ( batchId ) {
|
|
|
|
|
|
batchedMesh.getColorAt( batchId, lastHoveredColor );
|
|
|
- batchedMesh.setColorAt( batchId, yellow );
|
|
|
+ batchedMesh.setColorAt( batchId, highlight );
|
|
|
|
|
|
}
|
|
|
|