|
|
@@ -37,7 +37,7 @@
|
|
|
<script type="module">
|
|
|
|
|
|
import * as THREE from 'three/webgpu';
|
|
|
- import { uniform, varying, vec4, add, sub, max, dot, sin, mat3, uint, negate, instancedArray, cameraProjectionMatrix, cameraViewMatrix, positionLocal, modelWorldMatrix, sqrt, attribute, property, float, Fn, If, cos, Loop, Continue, normalize, instanceIndex, length } from 'three/tsl';
|
|
|
+ import { uniform, varying, vec4, add, sub, max, dot, sin, mat3, uint, negate, instancedArray, cameraProjectionMatrix, cameraViewMatrix, positionLocal, modelWorldMatrix, sqrt, property, float, Fn, If, cos, Loop, Continue, normalize, instanceIndex, length, vertexIndex } from 'three/tsl';
|
|
|
|
|
|
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
|
|
|
|
@@ -64,17 +64,11 @@
|
|
|
|
|
|
super();
|
|
|
|
|
|
- const trianglesPerBird = 3;
|
|
|
- const triangles = BIRDS * trianglesPerBird;
|
|
|
- const points = triangles * 3;
|
|
|
+ const points = 3 * 3;
|
|
|
|
|
|
const vertices = new THREE.BufferAttribute( new Float32Array( points * 3 ), 3 );
|
|
|
- const references = new THREE.BufferAttribute( new Uint32Array( points ), 1 );
|
|
|
- const birdVertex = new THREE.BufferAttribute( new Uint32Array( points ), 1 );
|
|
|
|
|
|
this.setAttribute( 'position', vertices );
|
|
|
- this.setAttribute( 'reference', references );
|
|
|
- this.setAttribute( 'birdVertex', birdVertex );
|
|
|
|
|
|
let v = 0;
|
|
|
|
|
|
@@ -90,40 +84,26 @@
|
|
|
|
|
|
const wingsSpan = 20;
|
|
|
|
|
|
- for ( let f = 0; f < BIRDS; f ++ ) {
|
|
|
-
|
|
|
- // Body
|
|
|
- verts_push(
|
|
|
- 0, 0, - 20,
|
|
|
- 0, - 8, 10,
|
|
|
- 0, 0, 30
|
|
|
- );
|
|
|
-
|
|
|
- // Wings
|
|
|
- verts_push(
|
|
|
- 0, 0, - 15,
|
|
|
- - wingsSpan, 0, 5,
|
|
|
- 0, 0, 15
|
|
|
- );
|
|
|
-
|
|
|
- verts_push(
|
|
|
- 0, 0, 15,
|
|
|
- wingsSpan, 0, 5,
|
|
|
- 0, 0, - 15
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- for ( let v = 0; v < triangles * 3; v ++ ) {
|
|
|
-
|
|
|
- const triangleIndex = ~ ~ ( v / 3 );
|
|
|
- const birdIndex = ~ ~ ( triangleIndex / trianglesPerBird );
|
|
|
-
|
|
|
- references.array[ v ] = birdIndex;
|
|
|
+ // Body
|
|
|
+ verts_push(
|
|
|
+ 0, 0, - 20,
|
|
|
+ 0, - 8, 10,
|
|
|
+ 0, 0, 30
|
|
|
+ );
|
|
|
|
|
|
- birdVertex.array[ v ] = v % 9;
|
|
|
+ // Left Wing
|
|
|
+ verts_push(
|
|
|
+ 0, 0, - 15,
|
|
|
+ - wingsSpan, 0, 5,
|
|
|
+ 0, 0, 15
|
|
|
+ );
|
|
|
|
|
|
- }
|
|
|
+ // Right Wing
|
|
|
+ verts_push(
|
|
|
+ 0, 0, 15,
|
|
|
+ wingsSpan, 0, 5,
|
|
|
+ 0, 0, - 15
|
|
|
+ );
|
|
|
|
|
|
this.scale( 0.2, 0.2, 0.2 );
|
|
|
|
|
|
@@ -253,14 +233,11 @@
|
|
|
|
|
|
const birdVertexTSL = Fn( () => {
|
|
|
|
|
|
- const reference = attribute( 'reference' );
|
|
|
- const birdVertex = attribute( 'birdVertex' );
|
|
|
-
|
|
|
const position = positionLocal.toVar();
|
|
|
- const newPhase = phaseStorage.element( reference ).toVar();
|
|
|
- const newVelocity = normalize( velocityStorage.element( reference ) ).toVar();
|
|
|
+ const newPhase = phaseStorage.element( instanceIndex ).toVar();
|
|
|
+ const newVelocity = normalize( velocityStorage.element( instanceIndex ) ).toVar();
|
|
|
|
|
|
- If( birdVertex.equal( 4 ).or( birdVertex.equal( 7 ) ), () => {
|
|
|
+ If( vertexIndex.equal( 4 ).or( vertexIndex.equal( 7 ) ), () => {
|
|
|
|
|
|
// flap wings
|
|
|
position.y = sin( newPhase ).mul( 5.0 );
|
|
|
@@ -294,7 +271,7 @@
|
|
|
);
|
|
|
|
|
|
const finalVert = maty.mul( matz ).mul( newPosition );
|
|
|
- finalVert.addAssign( positionStorage.element( reference ) );
|
|
|
+ finalVert.addAssign( positionStorage.element( instanceIndex ) );
|
|
|
|
|
|
return cameraProjectionMatrix.mul( cameraViewMatrix ).mul( finalVert );
|
|
|
|
|
|
@@ -303,7 +280,7 @@
|
|
|
birdMaterial.vertexNode = birdVertexTSL();
|
|
|
birdMaterial.side = THREE.DoubleSide;
|
|
|
|
|
|
- const birdMesh = new THREE.Mesh( birdGeometry, birdMaterial );
|
|
|
+ const birdMesh = new THREE.InstancedMesh( birdGeometry, birdMaterial, BIRDS );
|
|
|
birdMesh.rotation.y = Math.PI / 2;
|
|
|
birdMesh.matrixAutoUpdate = false;
|
|
|
birdMesh.frustumCulled = false;
|