Skip to content

Commit

Permalink
feat(model): improve anti-aliasing for models using alpha-keyed blending
Browse files Browse the repository at this point in the history
  • Loading branch information
fallenoak committed Feb 5, 2024
1 parent 199ec9e commit 0d0032b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 11 deletions.
8 changes: 4 additions & 4 deletions src/lib/blend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ const THREE_BLEND_STATE = {
blendDstAlpha: THREE.ZeroFactor,
},
[THREE_BLEND.BLEND_ALPHA_KEY]: {
blending: THREE.NoBlending,
blendSrc: THREE.OneFactor,
blendDst: THREE.ZeroFactor,
blending: THREE.CustomBlending,
blendSrc: THREE.SrcAlphaFactor,
blendDst: THREE.OneMinusSrcAlphaFactor,
blendSrcAlpha: THREE.OneFactor,
blendDstAlpha: THREE.ZeroFactor,
blendDstAlpha: THREE.OneMinusSrcAlphaFactor,
},
[THREE_BLEND.BLEND_ALPHA]: {
blending: THREE.CustomBlending,
Expand Down
19 changes: 15 additions & 4 deletions src/lib/model/ModelMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class ModelMaterial extends THREE.RawShaderMaterial {
this.defines['USE_SKINNING'] = 1;
}

if (this.#blend === M2_MATERIAL_BLEND.BLEND_ALPHA_KEY) {
this.defines['ALPHA_TO_COVERAGE'] = 1;
this.alphaToCoverage = true;
}

this.glslVersion = THREE.GLSL3;
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
Expand Down Expand Up @@ -101,14 +106,20 @@ class ModelMaterial extends THREE.RawShaderMaterial {

this.#materialParams.x = alpha;

// Opaque - keep all pixels, regardless of alpha
// Alpha key - scale pixel test by alpha
// Other - keep all pixels that aren't fully transparent
// Alpha test behavior
if (this.#blend === M2_MATERIAL_BLEND.BLEND_OPAQUE) {
// Disable alpha test
this.#materialParams.y = 0.0;
} else if (this.#blend === M2_MATERIAL_BLEND.BLEND_ALPHA_KEY) {
this.#materialParams.y = alpha * (224.0 / 255.0);
if (Math.trunc(alpha * 224.0) >= 1) {
// Scale alpha test by current alpha value
this.#materialParams.y = alpha * (224.0 / 255.0);
} else {
// Disable alpha test
this.#materialParams.y = 0.0;
}
} else {
// Lower alpha test threshold
this.#materialParams.y = 1.0 / 255.0;
}

Expand Down
13 changes: 10 additions & 3 deletions src/lib/model/shader/fragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,16 @@ void combineModMod2x(inout vec4 color, in vec4 tex0, in vec4 tex1) {

const FRAGMENT_SHADER_MAIN_ALPHATEST = `
// Alpha test
if (color.a < materialParams.y) {
discard;
}
#ifdef ALPHA_TO_COVERAGE
color.a = smoothstep(materialParams.y, materialParams.y + fwidth(color.a), color.a);
if (color.a == 0.0) {
discard;
}
#else
if (color.a < materialParams.y) {
discard;
}
#endif
`;

const FRAGMENT_SHADER_MAIN_LIGHTING = `
Expand Down

0 comments on commit 0d0032b

Please sign in to comment.