Garrett Johnson 5 years ago
parent
commit
d93a963a4f

+ 84 - 3
example/b3dmExample.js

@@ -10,16 +10,66 @@ import {
 	PCFSoftShadowMap,
 	PCFSoftShadowMap,
 	Vector2,
 	Vector2,
 	Raycaster,
 	Raycaster,
+	ShaderLib,
+	UniformsUtils,
+	ShaderMaterial,
+	Color,
 } from 'three';
 } from 'three';
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
 
 
 let camera, controls, scene, renderer;
 let camera, controls, scene, renderer;
 let box, dirLight;
 let box, dirLight;
 let raycaster, mouse;
 let raycaster, mouse;
+let model;
 
 
 init();
 init();
 animate();
 animate();
 
 
+// Adjusts the three.js standard shader to include batchid highlight
+function batchIdHighlightShaderMixin( shader ) {
+
+	const newShader = { ...shader };
+	newShader.uniforms = {
+		highlightedBatchId: { value: - 1 },
+		highlightColor: { value: new Color( 0xFFC107 ).convertSRGBToLinear() },
+		...UniformsUtils.clone( shader.uniforms ),
+	};
+	newShader.extensions = {
+		derivatives: true,
+	};
+	newShader.lights = true;
+	newShader.vertexShader =
+		`
+			attribute float _batchid;
+			varying float batchid;
+		` +
+		newShader.vertexShader.replace(
+			/#include <uv_vertex>/,
+			`
+			#include <uv_vertex>
+			batchid = _batchid;
+			`
+		);
+	newShader.fragmentShader =
+		`
+			varying float batchid;
+			uniform float highlightedBatchId;
+			uniform vec3 highlightColor;
+		` +
+		newShader.fragmentShader.replace(
+			/vec4 diffuseColor = vec4\( diffuse, opacity \);/,
+			`
+			vec4 diffuseColor =
+				abs( batchid - highlightedBatchId ) < 0.5 ?
+				vec4( highlightColor, opacity ) :
+				vec4( diffuse, opacity );
+			`
+		);
+
+	return newShader;
+
+}
+
 function init() {
 function init() {
 
 
 	scene = new Scene();
 	scene = new Scene();
@@ -70,8 +120,22 @@ function init() {
 		.then( res => {
 		.then( res => {
 
 
 			console.log( res );
 			console.log( res );
+			model = res.scene;
 			scene.add( res.scene );
 			scene.add( res.scene );
 
 
+			// reassign the material to use the batchid highlight variant.
+			// in practice this should copy over any needed uniforms from the
+			// original material.
+			res.scene.traverse( c => {
+
+				if ( c.isMesh ) {
+
+					c.material = new ShaderMaterial( batchIdHighlightShaderMixin( ShaderLib.standard ) );
+
+				}
+
+			} );
+
 		} );
 		} );
 
 
 	raycaster = new Raycaster();
 	raycaster = new Raycaster();
@@ -94,18 +158,35 @@ function onMouseMove( e ) {
 	raycaster.setFromCamera( mouse, camera );
 	raycaster.setFromCamera( mouse, camera );
 
 
 	const intersects = raycaster.intersectObject( scene, true );
 	const intersects = raycaster.intersectObject( scene, true );
+	let hoveredBatchid = - 1;
 	if ( intersects.length ) {
 	if ( intersects.length ) {
 
 
 		const { face, object } = intersects[ 0 ];
 		const { face, object } = intersects[ 0 ];
-		const batchid = object.geometry.getAttribute( '_batchid' );
-		if ( batchid ) {
+		const batchidAttr = object.geometry.getAttribute( '_batchid' );
+
+		if ( batchidAttr ) {
 
 
-			console.log( '_batchid', batchid.getX( face.a ), batchid.getX( face.b ), batchid.getX( face.c ) );
+			hoveredBatchid = batchidAttr.getX( face.a );
+			console.log( '_batchid', batchidAttr.getX( face.a ), batchidAttr.getX( face.b ), batchidAttr.getX( face.c ) );
 
 
 		}
 		}
 
 
 	}
 	}
 
 
+	if ( model ) {
+
+		model.traverse( c => {
+
+			if ( c.isMesh ) {
+
+				c.material.uniforms.highlightedBatchId.value = hoveredBatchid;
+
+			}
+
+		} );
+
+	}
+
 }
 }
 
 
 function onWindowResize() {
 function onWindowResize() {

File diff suppressed because it is too large
+ 51 - 5
example/bundle/b3dmExample.d88db709.js


File diff suppressed because it is too large
+ 1 - 1
example/bundle/b3dmExample.d88db709.js.map