Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Material: Add "material.alphaHash" transparency mode #24271

Merged
merged 7 commits into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/jsm/postprocessing/TAARenderPass.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class TAARenderPass extends SSAARenderPass {

this.sampleLevel = 0;
this.accumulate = false;
this.accumulateIndex = - 1;

}

Expand Down
1 change: 1 addition & 0 deletions src/loaders/MaterialLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class MaterialLoader extends Loader {
if ( json.opacity !== undefined ) material.opacity = json.opacity;
if ( json.transparent !== undefined ) material.transparent = json.transparent;
if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
if ( json.alphaHash !== undefined ) material.alphaHash = json.alphaHash;
if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
Expand Down
3 changes: 3 additions & 0 deletions src/materials/Material.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Material extends EventDispatcher {

this.opacity = 1;
this.transparent = false;
this.alphaHash = false;

this.blendSrc = SrcAlphaFactor;
this.blendDst = OneMinusSrcAlphaFactor;
Expand Down Expand Up @@ -353,6 +354,7 @@ class Material extends EventDispatcher {
if ( this.dithering === true ) data.dithering = true;

if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
if ( this.alphaHash === true ) data.alphaHash = this.alphaHash;
if ( this.alphaToCoverage === true ) data.alphaToCoverage = this.alphaToCoverage;
if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
if ( this.forceSinglePass === true ) data.forceSinglePass = this.forceSinglePass;
Expand Down Expand Up @@ -474,6 +476,7 @@ class Material extends EventDispatcher {
this.dithering = source.dithering;

this.alphaTest = source.alphaTest;
this.alphaHash = source.alphaHash;
this.alphaToCoverage = source.alphaToCoverage;
this.premultipliedAlpha = source.premultipliedAlpha;
this.forceSinglePass = source.forceSinglePass;
Expand Down
4 changes: 4 additions & 0 deletions src/renderers/shaders/ShaderChunk.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import alphahash_fragment from './ShaderChunk/alphahash_fragment.glsl.js';
import alphahash_pars_fragment from './ShaderChunk/alphahash_pars_fragment.glsl.js';
import alphamap_fragment from './ShaderChunk/alphamap_fragment.glsl.js';
import alphamap_pars_fragment from './ShaderChunk/alphamap_pars_fragment.glsl.js';
import alphatest_fragment from './ShaderChunk/alphatest_fragment.glsl.js';
Expand Down Expand Up @@ -121,6 +123,8 @@ import * as shadow from './ShaderLib/shadow.glsl.js';
import * as sprite from './ShaderLib/sprite.glsl.js';

export const ShaderChunk = {
alphahash_fragment: alphahash_fragment,
alphahash_pars_fragment: alphahash_pars_fragment,
alphamap_fragment: alphamap_fragment,
alphamap_pars_fragment: alphamap_pars_fragment,
alphatest_fragment: alphatest_fragment,
Expand Down
7 changes: 7 additions & 0 deletions src/renderers/shaders/ShaderChunk/alphahash_fragment.glsl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default /* glsl */`
#ifdef USE_ALPHAHASH

if ( diffuseColor.a < getAlphaHashThreshold( vPosition ) ) discard;

#endif
`;
68 changes: 68 additions & 0 deletions src/renderers/shaders/ShaderChunk/alphahash_pars_fragment.glsl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
export default /* glsl */`
#ifdef USE_ALPHAHASH

/**
* See: https://casual-effects.com/research/Wyman2017Hashed/index.html
*/

const float ALPHA_HASH_SCALE = 0.05; // Derived from trials only, and may be changed.

float hash2D( vec2 value ) {

return fract( 1.0e4 * sin( 17.0 * value.x + 0.1 * value.y ) * ( 0.1 + abs( sin( 13.0 * value.y + value.x ) ) ) );

}

float hash3D( vec3 value ) {

return hash2D( vec2( hash2D( value.xy ), value.z ) );

}

float getAlphaHashThreshold( vec3 position ) {

// Find the discretized derivatives of our coordinates
float maxDeriv = max(
length( dFdx( position.xyz ) ),
length( dFdy( position.xyz ) )
);
float pixScale = 1.0 / ( ALPHA_HASH_SCALE * maxDeriv );

// Find two nearest log-discretized noise scales
vec2 pixScales = vec2(
exp2( floor( log2( pixScale ) ) ),
exp2( ceil( log2( pixScale ) ) )
);

// Compute alpha thresholds at our two noise scales
vec2 alpha = vec2(
hash3D( floor( pixScales.x * position.xyz ) ),
hash3D( floor( pixScales.y * position.xyz ) )
);

// Factor to interpolate lerp with
float lerpFactor = fract( log2( pixScale ) );

// Interpolate alpha threshold from noise at two scales
float x = ( 1.0 - lerpFactor ) * alpha.x + lerpFactor * alpha.y;

// Pass into CDF to compute uniformly distrib threshold
float a = min( lerpFactor, 1.0 - lerpFactor );
vec3 cases = vec3(
x * x / ( 2.0 * a * ( 1.0 - a ) ),
( x - 0.5 * a ) / ( 1.0 - a ),
1.0 - ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) )
);

// Find our final, uniformly distributed alpha threshold (ατ)
float threshold = ( x < ( 1.0 - a ) )
? ( ( x < a ) ? cases.x : cases.y )
: cases.z;

// Avoids ατ == 0. Could also do ατ =1-ατ
return clamp( threshold , 1.0e-6, 1.0 );

}

#endif
`;
6 changes: 6 additions & 0 deletions src/renderers/shaders/ShaderChunk/begin_vertex.glsl.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export default /* glsl */`
vec3 transformed = vec3( position );

#ifdef USE_ALPHAHASH

vPosition = vec3( position );

#endif
`;
6 changes: 6 additions & 0 deletions src/renderers/shaders/ShaderChunk/common.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ struct GeometricContext {
#endif
};

#ifdef USE_ALPHAHASH

varying vec3 vPosition;

#endif

vec3 transformDirection( in vec3 dir, in mat4 matrix ) {

return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/depth.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const fragment = /* glsl */`
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>

Expand All @@ -72,6 +73,7 @@ void main() {
#include <map_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>

#include <logdepthbuf_fragment>

Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ varying vec3 vWorldPosition;
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <clipping_planes_pars_fragment>

void main () {
Expand All @@ -62,6 +63,7 @@ void main () {
#include <map_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>

float dist = length( vWorldPosition - referencePosition );
dist = ( dist - nearDistance ) / ( farDistance - nearDistance );
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/meshbasic.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ uniform float opacity;
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <envmap_common_pars_fragment>
Expand All @@ -76,6 +77,7 @@ void main() {
#include <color_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>
#include <specularmap_fragment>

ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/meshlambert.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ uniform float opacity;
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
Expand Down Expand Up @@ -92,6 +93,7 @@ void main() {
#include <color_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>
#include <specularmap_fragment>
#include <normal_fragment_begin>
#include <normal_fragment_maps>
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/meshmatcap.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ varying vec3 vViewPosition;
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <fog_pars_fragment>
#include <normal_pars_fragment>
#include <bumpmap_pars_fragment>
Expand All @@ -76,6 +77,7 @@ void main() {
#include <color_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>
#include <normal_fragment_begin>
#include <normal_fragment_maps>

Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/meshphong.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ uniform float opacity;
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
Expand Down Expand Up @@ -94,6 +95,7 @@ void main() {
#include <color_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>
#include <specularmap_fragment>
#include <normal_fragment_begin>
#include <normal_fragment_maps>
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/meshphysical.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ varying vec3 vViewPosition;
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
Expand Down Expand Up @@ -165,6 +166,7 @@ void main() {
#include <color_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>
#include <roughnessmap_fragment>
#include <metalnessmap_fragment>
#include <normal_fragment_begin>
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/meshtoon.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ uniform float opacity;
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <emissivemap_pars_fragment>
Expand Down Expand Up @@ -88,6 +89,7 @@ void main() {
#include <color_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>
#include <normal_fragment_begin>
#include <normal_fragment_maps>
#include <emissivemap_fragment>
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/points.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ uniform float opacity;
#include <color_pars_fragment>
#include <map_particle_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
Expand All @@ -71,6 +72,7 @@ void main() {
#include <map_particle_fragment>
#include <color_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>

outgoingLight = diffuseColor.rgb;

Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderLib/sprite.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ uniform float opacity;
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <alphahash_pars_fragment>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
Expand All @@ -67,6 +68,7 @@ void main() {
#include <map_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
#include <alphahash_fragment>

outgoingLight = diffuseColor.rgb;

Expand Down
2 changes: 2 additions & 0 deletions src/renderers/webgl/WebGLProgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
parameters.alphaHash ? '#define USE_ALPHAHASH' : '',

parameters.transmission ? '#define USE_TRANSMISSION' : '',
parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
Expand Down Expand Up @@ -714,6 +715,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {

parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
parameters.alphaTest ? '#define USE_ALPHATEST' : '',
parameters.alphaHash ? '#define USE_ALPHAHASH' : '',

parameters.sheen ? '#define USE_SHEEN' : '',
parameters.sheenColorMap ? '#define USE_SHEEN_COLORMAP' : '',
Expand Down
3 changes: 3 additions & 0 deletions src/renderers/webgl/WebGLPrograms.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities

const HAS_ALPHATEST = material.alphaTest > 0;

const HAS_ALPHAHASH = !! material.alphaHash;

const HAS_EXTENSIONS = !! material.extensions;

const HAS_ATTRIBUTE_UV1 = !! geometry.attributes.uv1;
Expand Down Expand Up @@ -232,6 +234,7 @@ function WebGLPrograms( renderer, cubemaps, cubeuvmaps, extensions, capabilities

alphaMap: HAS_ALPHAMAP,
alphaTest: HAS_ALPHATEST,
alphaHash: HAS_ALPHAHASH,

combine: material.combine,

Expand Down