Skip to content

Commit

Permalink
comments, clarification
Browse files Browse the repository at this point in the history
  • Loading branch information
gkjohnson committed Dec 25, 2024
1 parent c98cf43 commit 23f4e50
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 56 deletions.
55 changes: 47 additions & 8 deletions src/plugins/three/fade/FadeBatchedMesh.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { PassThroughBatchedMesh } from './PassThroughBatchedMesh.js';
import { InstanceDataTexture } from './InstanceDataTexture.js';
import { RGFormat, UnsignedByteType } from 'three';
import { RGFormat, UnsignedByteType, DataTexture } from 'three';
import { wrapFadeMaterial } from './wrapFadeMaterial.js';

export class FadeBatchedMesh extends PassThroughBatchedMesh {
Expand All @@ -9,48 +8,55 @@ export class FadeBatchedMesh extends PassThroughBatchedMesh {

super( ...args );

// construct a version of the material that supports fading
const material = this.material;
const params = wrapFadeMaterial( material, material.onBeforeCompile );
material.defines.FEATURE_FADE = 1;
material.defines.USE_BATCHING_FRAG = 1;
material.needsUpdate = true;

// fade parameters
this.fadeTexture = null;
this._fadeParams = params;

this._initFadeTexture();


}

// Set the fade state
setFadeAt( index, fadeIn, fadeOut ) {

this._initFadeTexture();
this.fadeTexture.setValueAt( index, fadeIn * 255, fadeOut * 255 );

}

// initialize the texture and resize it if needed
_initFadeTexture() {

// calculate the new size
let size = Math.sqrt( this._maxInstanceCount );
size = Math.ceil( size );

const length = size * size * 2;
const oldFadeTexture = this.fadeTexture;
if ( ! this.fadeTexture || this.fadeTexture.image.data.length !== size * size * 2 ) {
if ( ! oldFadeTexture || oldFadeTexture.image.data.length !== length ) {

// 4 floats per RGBA pixel initialized to white
const fadeArray = new Uint8Array( size * size * 2 );
// 2 bytes per RG pixel
const fadeArray = new Uint8Array( length );
const fadeTexture = new InstanceDataTexture( fadeArray, size, size, RGFormat, UnsignedByteType );

// copy the data from the old fade texture if it exists
if ( oldFadeTexture ) {

oldFadeTexture.dispose();

const src = oldFadeTexture.image.data;
const dst = this.fadeTexture.image.data;
const len = Math.min( src.length, dst.length );
dst.set( new src.constructor( src.buffer, 0, len ) );

}

// assign the new fade texture to the uniform, member variable
this.fadeTexture = fadeTexture;
this._fadeParams.fadeTexture.value = fadeTexture;
fadeTexture.needsUpdate = true;
Expand All @@ -59,10 +65,43 @@ export class FadeBatchedMesh extends PassThroughBatchedMesh {

}

// dispose the fade texture. Super cannot be used here due to proxy
dispose() {

this.fadeTexture.dispose();

}

}

// Version of data texture that can assign pixel values
class InstanceDataTexture extends DataTexture {

setValueAt( instance, ...values ) {

const { data, width, height } = this.image;
const itemSize = Math.floor( data.length / ( width * height ) );
let needsUpdate = false;
for ( let i = 0; i < itemSize; i ++ ) {

const index = instance * itemSize + i;
const prevValue = data[ index ];
const newValue = values[ i ] || 0;
if ( prevValue !== newValue ) {

data[ index ] = newValue;
needsUpdate = true;

}

}

if ( needsUpdate ) {

this.needsUpdate = true;

}

}

}
3 changes: 3 additions & 0 deletions src/plugins/three/fade/FadeMaterialManager.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { wrapFadeMaterial } from './wrapFadeMaterial.js';

// Class for managing and updating extended fade parameters
export class FadeMaterialManager {

constructor() {
Expand All @@ -18,6 +19,7 @@ export class FadeMaterialManager {

}

// traverse the scene and update the fade parameters of all materials
const fadeParams = this._fadeParams;
scene.traverse( child => {

Expand Down Expand Up @@ -69,6 +71,7 @@ export class FadeMaterialManager {

}

// revert the materials
const fadeParams = this._fadeParams;
scene.traverse( child => {

Expand Down
32 changes: 0 additions & 32 deletions src/plugins/three/fade/InstanceDataTexture.js

This file was deleted.

27 changes: 11 additions & 16 deletions src/plugins/three/fade/PassThroughBatchedMesh.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { MeshBasicMaterial } from 'three';

// NOTE this will not automatically delete instances on geometry delete.
// A hacky version of BatchedMesh that passes through functions and geometry and other fields from the underlying
// BatchedMesh. Calls to "this" or "super" will not work in subfunctions.
export class PassThroughBatchedMesh {

constructor( other, material = new MeshBasicMaterial() ) {

// the other batched mesh
this.other = other;

// guarded fields
this.material = material;
this.visible = true;
this.parent = null;
this._instanceInfo = [];
this._visibilityChanged = true;

// the proxy instance tht pass through arguments to the underlying mesh
const proxyTarget = new Proxy( this, {

get( target, key ) {
Expand All @@ -22,6 +27,7 @@ export class PassThroughBatchedMesh {

} else {

// sync instances on function call and call functions on "this" instance
const value = other[ key ];
if ( value instanceof Function ) {

Expand Down Expand Up @@ -58,7 +64,6 @@ export class PassThroughBatchedMesh {

},


deleteProperty( target, key ) {

if ( key in target ) {
Expand All @@ -73,20 +78,10 @@ export class PassThroughBatchedMesh {

},

// ownKeys() {

// },

// has(target, key) {

// },

// defineProperty(target, key, descriptor) {
// },

// getOwnPropertyDescriptor(target, key) {
// },

// ownKeys() {},
// has(target, key) {},
// defineProperty(target, key, descriptor) {},
// getOwnPropertyDescriptor(target, key) {},

} );

Expand Down
4 changes: 4 additions & 0 deletions src/plugins/three/fade/wrapFadeMaterial.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Adjusts the provided material to support fading in and out using a bayer pattern. Providing a "previous"
// before compile can be used to chain shader adjustments. Returns the added uniforms used for fading.
export function wrapFadeMaterial( material, previousOnBeforeCompile ) {

const params = {
Expand Down Expand Up @@ -64,8 +66,10 @@ export function wrapFadeMaterial( material, previousOnBeforeCompile ) {
}
// the USE_BATCHING define is not available in fragment shaders
#ifdef USE_BATCHING_FRAG
// functions for reading the fade state of a given batch id
uniform sampler2D fadeTexture;
varying float vBatchId;
vec2 getFadeValues( const in float i ) {
Expand Down

0 comments on commit 23f4e50

Please sign in to comment.