|
|
@@ -1,12 +1,16 @@
|
|
|
|
|
|
import { normalLocal } from './Normal.js';
|
|
|
-import { positionLocal } from './Position.js';
|
|
|
+import { positionLocal, positionPrevious } from './Position.js';
|
|
|
import { vec3, mat3, mat4, int, ivec2, float, Fn } from '../tsl/TSLBase.js';
|
|
|
import { textureLoad } from './TextureNode.js';
|
|
|
import { textureSize } from './TextureSizeNode.js';
|
|
|
import { tangentLocal } from './Tangent.js';
|
|
|
import { instanceIndex, drawIndex } from '../core/IndexNode.js';
|
|
|
import { varyingProperty } from '../core/PropertyNode.js';
|
|
|
+import { OnObjectUpdate } from '../utils/EventNode.js';
|
|
|
+import { DataTexture } from '../../textures/DataTexture.js';
|
|
|
+
|
|
|
+const _previousBatchingMatrices = /*@__PURE__*/ new WeakMap();
|
|
|
|
|
|
/**
|
|
|
* TSL function that retrieves the batching color for a given instance ID from a colors texture.
|
|
|
@@ -41,6 +45,61 @@ const getIndirectIndex = /*@__PURE__*/ Fn( ( [ indirectTexture, id ] ) => {
|
|
|
|
|
|
} );
|
|
|
|
|
|
+/**
|
|
|
+ * Creates the node that reads a batching matrix from the given matrices texture.
|
|
|
+ *
|
|
|
+ * @param {Texture} matricesTexture - The matrices texture.
|
|
|
+ * @param {Node<uint>} id - The indirect instance ID.
|
|
|
+ * @returns {Node<mat4>} The matrix node.
|
|
|
+ */
|
|
|
+function createBatchingMatrixNode( matricesTexture, id ) {
|
|
|
+
|
|
|
+ const size = int( textureSize( textureLoad( matricesTexture ), 0 ).x ).toConst();
|
|
|
+ const j = float( id ).mul( 4 ).toInt().toConst();
|
|
|
+
|
|
|
+ const x = j.mod( size ).toConst();
|
|
|
+ const y = j.div( size ).toConst();
|
|
|
+
|
|
|
+ return mat4(
|
|
|
+ textureLoad( matricesTexture, ivec2( x, y ) ),
|
|
|
+ textureLoad( matricesTexture, ivec2( x.add( 1 ), y ) ),
|
|
|
+ textureLoad( matricesTexture, ivec2( x.add( 2 ), y ) ),
|
|
|
+ textureLoad( matricesTexture, ivec2( x.add( 3 ), y ) )
|
|
|
+ );
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Retrieves or initializes the previous frame batching matrix node for motion vectors.
|
|
|
+ * Uses a WeakMap to cache previous frame matrices textures and their TSL nodes.
|
|
|
+ *
|
|
|
+ * @param {BatchedMesh} batchMesh - The batched mesh.
|
|
|
+ * @param {Node<uint>} id - The indirect instance ID.
|
|
|
+ * @returns {Node<mat4>} The previous frame batching matrix node.
|
|
|
+ */
|
|
|
+function getPreviousNode( batchMesh, id ) {
|
|
|
+
|
|
|
+ let data = _previousBatchingMatrices.get( batchMesh );
|
|
|
+
|
|
|
+ if ( data === undefined ) {
|
|
|
+
|
|
|
+ const { image, format, type } = batchMesh._matricesTexture;
|
|
|
+
|
|
|
+ const previousMatricesTexture = new DataTexture( image.data.slice(), image.width, image.height, format, type );
|
|
|
+
|
|
|
+ data = {
|
|
|
+ previousMatricesTexture,
|
|
|
+ node: createBatchingMatrixNode( previousMatricesTexture, id )
|
|
|
+ };
|
|
|
+
|
|
|
+ _previousBatchingMatrices.set( batchMesh, data );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return data.node;
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* TSL object representing a varying property for the batching color vector.
|
|
|
*
|
|
|
@@ -63,19 +122,7 @@ export const batch = /*@__PURE__*/ Fn( ( [ batchMesh ], builder ) => {
|
|
|
|
|
|
const indirectId = getIndirectIndex( batchMesh._indirectTexture, int( batchingIdNode ) );
|
|
|
|
|
|
- const matricesTexture = batchMesh._matricesTexture;
|
|
|
-
|
|
|
- const size = int( textureSize( textureLoad( matricesTexture ), 0 ).x ).toConst();
|
|
|
- const j = float( indirectId ).mul( 4 ).toInt().toConst();
|
|
|
-
|
|
|
- const x = j.mod( size ).toConst();
|
|
|
- const y = j.div( size ).toConst();
|
|
|
- const batchingMatrix = mat4(
|
|
|
- textureLoad( matricesTexture, ivec2( x, y ) ),
|
|
|
- textureLoad( matricesTexture, ivec2( x.add( 1 ), y ) ),
|
|
|
- textureLoad( matricesTexture, ivec2( x.add( 2 ), y ) ),
|
|
|
- textureLoad( matricesTexture, ivec2( x.add( 3 ), y ) )
|
|
|
- );
|
|
|
+ const batchingMatrix = createBatchingMatrixNode( batchMesh._matricesTexture, indirectId );
|
|
|
|
|
|
const colorsTexture = batchMesh._colorsTexture;
|
|
|
|
|
|
@@ -91,6 +138,22 @@ export const batch = /*@__PURE__*/ Fn( ( [ batchMesh ], builder ) => {
|
|
|
|
|
|
positionLocal.assign( batchingMatrix.mul( positionLocal ) );
|
|
|
|
|
|
+ if ( builder.needsPreviousData() ) {
|
|
|
+
|
|
|
+ OnObjectUpdate( ( { object } ) => {
|
|
|
+
|
|
|
+ const previousBatchData = _previousBatchingMatrices.get( object );
|
|
|
+
|
|
|
+ previousBatchData.previousMatricesTexture.image.data.set( object._matricesTexture.image.data );
|
|
|
+ previousBatchData.previousMatricesTexture.needsUpdate = true;
|
|
|
+
|
|
|
+ } );
|
|
|
+
|
|
|
+ const previousBatchingMatrixNode = getPreviousNode( batchMesh, indirectId );
|
|
|
+ positionPrevious.assign( previousBatchingMatrixNode.mul( positionPrevious ).xyz );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
const transformedNormal = normalLocal.div( vec3( bm[ 0 ].dot( bm[ 0 ] ), bm[ 1 ].dot( bm[ 1 ] ), bm[ 2 ].dot( bm[ 2 ] ) ) );
|
|
|
|
|
|
const batchingNormal = bm.mul( transformedNormal ).xyz;
|