Skip to content

Commit

Permalink
Wrap the material with batched mesh uniforms
Browse files Browse the repository at this point in the history
  • Loading branch information
gkjohnson committed Dec 24, 2024
1 parent bc734d5 commit 654666d
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 70 deletions.
73 changes: 3 additions & 70 deletions src/plugins/three/fade/FadeMaterialManager.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { wrapFadeMaterial } from './wrapFadeMaterial.js';

export class FadeMaterialManager {

constructor() {
Expand Down Expand Up @@ -93,76 +95,7 @@ export class FadeMaterialManager {

}

const params = {
fadeIn: { value: 0 },
fadeOut: { value: 0 },
};

material.defines = {
FEATURE_FADE: 0,
};

material.onBeforeCompile = shader => {

shader.uniforms = {
...shader.uniforms,
...params,
};

shader.fragmentShader = shader.fragmentShader
.replace( /void main\(/, value => /* glsl */`
#if FEATURE_FADE
// adapted from https://www.shadertoy.com/view/Mlt3z8
float bayerDither2x2( vec2 v ) {
return mod( 3.0 * v.y + 2.0 * v.x, 4.0 );
}
float bayerDither4x4( vec2 v ) {
vec2 P1 = mod( v, 2.0 );
vec2 P2 = floor( 0.5 * mod( v, 4.0 ) );
return 4.0 * bayerDither2x2( P1 ) + bayerDither2x2( P2 );
}
uniform float fadeIn;
uniform float fadeOut;
#endif
${ value }
` )
.replace( /#include <dithering_fragment>/, value => /* glsl */`
${ value }
#if FEATURE_FADE
float bayerValue = bayerDither4x4( floor( mod( gl_FragCoord.xy, 4.0 ) ) );
float bayerBins = 16.0;
float dither = ( 0.5 + bayerValue ) / bayerBins;
if ( dither >= fadeIn ) {
discard;
}
if ( dither < fadeOut ) {
discard;
}
#endif
` );


};

fadeParams.set( material, params );
fadeParams.set( material, wrapFadeMaterial( material ) );

}

Expand Down
122 changes: 122 additions & 0 deletions src/plugins/three/fade/wrapFadeMaterial.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
export function wrapFadeMaterial( material ) {

const params = {
fadeIn: { value: 0 },
fadeOut: { value: 0 },
fadeTexture: { value: null },
};

material.defines = {
FEATURE_FADE: 0,
};

material.onBeforeCompile = shader => {

shader.uniforms = {
...shader.uniforms,
...params,
};

shader.vertexShader = shader.vertexShader
.replace(
/void\s+main()\s+{/,
value => /* glsl */`
#ifdef USE_BATCHING
varying float vBatchId;
#endif
${ value }
#ifdef USE_BATCHING
// add 0.5 to the value to avoid floating error that may cause flickering
vBatchId = batchId + 0.5;
#endif
`
);

shader.fragmentShader = shader.fragmentShader
.replace( /void main\(/, value => /* glsl */`
#if FEATURE_FADE
// adapted from https://www.shadertoy.com/view/Mlt3z8
float bayerDither2x2( vec2 v ) {
return mod( 3.0 * v.y + 2.0 * v.x, 4.0 );
}
float bayerDither4x4( vec2 v ) {
vec2 P1 = mod( v, 2.0 );
vec2 P2 = floor( 0.5 * mod( v, 4.0 ) );
return 4.0 * bayerDither2x2( P1 ) + bayerDither2x2( P2 );
}
#ifdef USE_BATCHING
uniform sampler2D fadeTexture;
varying float vBatchId;
vec2 getFadeValues( const in float i ) {
int size = textureSize( fadeTexture, 0 ).x;
int j = int( i );
int x = j % size;
int y = j / size;
return texelFetch( fadeTexture, ivec2( x, y ), 0 ).rg;
}
#else
uniform float fadeIn;
uniform float fadeOut;
#endif
#endif
${ value }
` )
.replace( /#include <dithering_fragment>/, value => /* glsl */`
${ value }
#if FEATURE_FADE
#ifdef USE_BATCHING
vec2 fadeValues = getFadeValues( vBatchId );
float fadeIn = fadeValues.r;
float fadeOut = fadeValues.g;
#endif
float bayerValue = bayerDither4x4( floor( mod( gl_FragCoord.xy, 4.0 ) ) );
float bayerBins = 16.0;
float dither = ( 0.5 + bayerValue ) / bayerBins;
if ( dither >= fadeIn ) {
discard;
}
if ( dither < fadeOut ) {
discard;
}
#endif
` );

};

return params;

}

0 comments on commit 654666d

Please sign in to comment.