Skip to content

Commit

Permalink
Rendering Engine: Fix alpha support (#16144)
Browse files Browse the repository at this point in the history
* Fix alpha support

* Remove the _forceAlphaTest property

* Deprecate needAlphaTesting and needAlphaBlending
  • Loading branch information
Popov72 authored Feb 5, 2025
1 parent 6f6d383 commit 69cdc19
Show file tree
Hide file tree
Showing 24 changed files with 72 additions and 51 deletions.
4 changes: 2 additions & 2 deletions packages/dev/core/src/Layers/thinEffectLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ export class ThinEffectLayer {

// Diffuse
if (material) {
const needAlphaTest = material.needAlphaTesting();
const needAlphaTest = material.needAlphaTestingForMesh(mesh);

const diffuseTexture = material.getAlphaTestTexture();
const needAlphaBlendFromDiffuse =
Expand Down Expand Up @@ -941,7 +941,7 @@ export class ThinEffectLayer {
}

if (!renderingMaterial) {
const needAlphaTest = material.needAlphaTesting();
const needAlphaTest = material.needAlphaTestingForMesh(effectiveMesh);

const diffuseTexture = material.getAlphaTestTexture();
const needAlphaBlendFromDiffuse =
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/core/src/Lights/Shadows/shadowGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1608,9 +1608,9 @@ export class ShadowGenerator implements IShadowGenerator {
}

// Alpha test
const needAlphaTesting = material.needAlphaTesting();
const needAlphaTesting = material.needAlphaTestingForMesh(mesh);

if (needAlphaTesting || material.needAlphaBlending()) {
if (needAlphaTesting || material.needAlphaBlendingForMesh(mesh)) {
if (this.useOpacityTextureForTransparentShadow) {
this._opacityTexture = (material as any).opacityTexture;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ export class BackgroundMaterial extends PushMaterial {
}

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Values that need to be evaluated on every frame
PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, subMesh.getRenderingMesh().hasThinInstances);
Expand Down
16 changes: 7 additions & 9 deletions packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -749,12 +749,6 @@ export abstract class PBRBaseMaterial extends PushMaterial {
*/
public _alphaCutOff = 0.4;

/**
* Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
* @internal
*/
public override _forceAlphaTest = false;

/**
* A fresnel is applied to the alpha of the model to ensure grazing angles edges are not alpha tested.
* And/Or occlude the blended part. (alpha is converted to gamma to compute the fresnel)
Expand Down Expand Up @@ -1040,6 +1034,10 @@ export abstract class PBRBaseMaterial extends PushMaterial {
* @returns whether or not this material should be rendered in alpha blend mode.
*/
public override needAlphaBlending(): boolean {
if (this._hasTransparencyMode) {
return this._transparencyModeIsBlend;
}

if (this._disableAlphaBlending) {
return false;
}
Expand All @@ -1051,8 +1049,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
* @returns whether or not this material should be rendered in alpha test mode.
*/
public override needAlphaTesting(): boolean {
if (this._forceAlphaTest) {
return true;
if (this._hasTransparencyMode) {
return this._transparencyModeIsTest;
}

if (this.subSurface?.disableAlphaBlending) {
Expand Down Expand Up @@ -1951,7 +1949,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
this._useLogarithmicDepth,
this.pointsCloud,
this.fogEnabled,
this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest,
this.needAlphaTestingForMesh(mesh),
defines,
this._applyDecalMapAfterDetailMap
);
Expand Down
39 changes: 29 additions & 10 deletions packages/dev/core/src/Materials/material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1091,11 +1091,6 @@ export class Material implements IAnimatable, IClipPlanesHolder {
return this.sideOrientation !== null ? this.sideOrientation : mesh.sideOrientation;
}

/**
* Enforces alpha test in opaque or blend mode in order to improve the performances of some situations.
*/
protected _forceAlphaTest = false;

/**
* The transparency mode of the material.
*/
Expand Down Expand Up @@ -1127,11 +1122,21 @@ export class Material implements IAnimatable, IClipPlanesHolder {

this._transparencyMode = value;

this._forceAlphaTest = value === Material.MATERIAL_ALPHATESTANDBLEND;

this._markAllSubMeshesAsTexturesAndMiscDirty();
}

protected get _hasTransparencyMode(): boolean {
return this._transparencyMode != null;
}

protected get _transparencyModeIsBlend(): boolean {
return this._transparencyMode === Material.MATERIAL_ALPHABLEND || this._transparencyMode === Material.MATERIAL_ALPHATESTANDBLEND;
}

protected get _transparencyModeIsTest(): boolean {
return this._transparencyMode === Material.MATERIAL_ALPHATEST || this._transparencyMode === Material.MATERIAL_ALPHATESTANDBLEND;
}

/**
* Returns true if alpha blending should be disabled.
*/
Expand All @@ -1142,8 +1147,13 @@ export class Material implements IAnimatable, IClipPlanesHolder {
/**
* Specifies whether or not this material should be rendered in alpha blend mode.
* @returns a boolean specifying if alpha blending is needed
* @deprecated Please use needAlphaBlendingForMesh instead
*/
public needAlphaBlending(): boolean {
if (this._hasTransparencyMode) {
return this._transparencyModeIsBlend;
}

if (this._disableAlphaBlending) {
return false;
}
Expand All @@ -1157,6 +1167,10 @@ export class Material implements IAnimatable, IClipPlanesHolder {
* @returns a boolean specifying if alpha blending is needed for the mesh
*/
public needAlphaBlendingForMesh(mesh: AbstractMesh): boolean {
if (this._hasTransparencyMode) {
return this._transparencyModeIsBlend;
}

if (mesh.visibility < 1.0) {
return true;
}
Expand All @@ -1171,10 +1185,11 @@ export class Material implements IAnimatable, IClipPlanesHolder {
/**
* Specifies whether or not this material should be rendered in alpha test mode.
* @returns a boolean specifying if an alpha test is needed.
* @deprecated Please use needAlphaTestingForMesh instead
*/
public needAlphaTesting(): boolean {
if (this._forceAlphaTest) {
return true;
if (this._hasTransparencyMode) {
return this._transparencyModeIsTest;
}

return false;
Expand All @@ -1185,7 +1200,11 @@ export class Material implements IAnimatable, IClipPlanesHolder {
* @param mesh defines the mesh to check
* @returns a boolean specifying if alpha testing should be turned on for the mesh
*/
protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean {
public needAlphaTestingForMesh(mesh: AbstractMesh): boolean {
if (this._hasTransparencyMode) {
return this._transparencyModeIsTest;
}

return !this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting();
}

Expand Down
2 changes: 1 addition & 1 deletion packages/dev/core/src/Materials/shaderMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ export class ShaderMaterial extends PushMaterial {
}

// Alpha test
if (mesh && this._shouldTurnAlphaTestOn(mesh)) {
if (mesh && this.needAlphaTestingForMesh(mesh)) {
defines.push("#define ALPHATEST");
}

Expand Down
10 changes: 7 additions & 3 deletions packages/dev/core/src/Materials/standardMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,10 @@ export class StandardMaterial extends PushMaterial {
* @returns a boolean specifying if alpha blending is needed
*/
public override needAlphaBlending(): boolean {
if (this._hasTransparencyMode) {
return this._transparencyModeIsBlend;
}

if (this._disableAlphaBlending) {
return false;
}
Expand All @@ -895,8 +899,8 @@ export class StandardMaterial extends PushMaterial {
* @returns a boolean specifying if an alpha test is needed.
*/
public override needAlphaTesting(): boolean {
if (this._forceAlphaTest) {
return true;
if (this._hasTransparencyMode) {
return this._transparencyModeIsTest;
}

return this._hasAlphaChannel() && (this._transparencyMode == null || this._transparencyMode === Material.MATERIAL_ALPHATEST);
Expand Down Expand Up @@ -1237,7 +1241,7 @@ export class StandardMaterial extends PushMaterial {
this._useLogarithmicDepth,
this.pointsCloud,
this.fogEnabled,
this._shouldTurnAlphaTestOn(mesh) || this._forceAlphaTest,
this.needAlphaTestingForMesh(mesh),
defines,
this._applyDecalMapAfterDetailMap
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {

// Alpha test
if (material) {
const needAlphaTesting = material.needAlphaTesting();
const needAlphaTesting = material.needAlphaTestingForMesh(mesh);
if (needAlphaTesting) {
defines.push("#define ALPHATEST");
}
Expand Down Expand Up @@ -466,7 +466,7 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
effect.setMatrix("viewProjection", scene.getTransformMatrix());

// Alpha test
if (material.needAlphaTesting()) {
if (material.needAlphaTestingForMesh(effectiveMesh)) {
const alphaTexture = material.getAlphaTestTexture();

if (alphaTexture) {
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/core/src/Rendering/depthRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ export class DepthRenderer {

if (!renderingMaterial) {
// Alpha test
if (material.needAlphaTesting()) {
if (material.needAlphaTestingForMesh(effectiveMesh)) {
const alphaTexture = material.getAlphaTestTexture();

if (alphaTexture) {
Expand Down Expand Up @@ -407,7 +407,7 @@ export class DepthRenderer {
let uv2 = false;

// Alpha test
if (material.needAlphaTesting() && material.getAlphaTestTexture()) {
if (material.needAlphaTestingForMesh(mesh) && material.getAlphaTestTexture()) {
defines.push("#define ALPHATEST");
if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
attribs.push(VertexBuffer.UVKind);
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/core/src/Rendering/geometryBufferRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ export class GeometryBufferRenderer {
if (material) {
let needUv = false;
// Alpha test
if (material.needAlphaTesting() && material.getAlphaTestTexture()) {
if (material.needAlphaTestingForMesh(mesh) && material.getAlphaTestTexture()) {
defines.push("#define ALPHATEST");
defines.push(`#define ALPHATEST_UV${material.getAlphaTestTexture().coordinatesIndex + 1}`);
needUv = true;
Expand Down Expand Up @@ -1099,7 +1099,7 @@ export class GeometryBufferRenderer {
material._preBind(drawWrapper, sideOrientation);

// Alpha test
if (material.needAlphaTesting()) {
if (material.needAlphaTestingForMesh(effectiveMesh)) {
const alphaTexture = material.getAlphaTestTexture();
if (alphaTexture) {
effect.setTexture("diffuseSampler", alphaTexture);
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/core/src/Rendering/outlineRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ export class OutlineRenderer implements ISceneComponent {
}

// Alpha test
if (material && material.needAlphaTesting()) {
if (material && material.needAlphaTestingForMesh(effectiveMesh)) {
const alphaTexture = material.getAlphaTestTexture();
if (alphaTexture) {
effect.setTexture("diffuseSampler", alphaTexture);
Expand Down Expand Up @@ -291,7 +291,7 @@ export class OutlineRenderer implements ISceneComponent {
let uv2 = false;

// Alpha test
if (material.needAlphaTesting()) {
if (material.needAlphaTestingForMesh(mesh)) {
defines.push("#define ALPHATEST");
if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
attribs.push(VertexBuffer.UVKind);
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/core/src/Rendering/renderingGroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ export class RenderingGroup {
if (material.needAlphaBlendingForMesh(mesh)) {
// Transparent
this._transparentSubMeshes.push(subMesh);
} else if (material.needAlphaTesting()) {
} else if (material.needAlphaTestingForMesh(mesh)) {
// Alpha test
if (material.needDepthPrePass) {
this._depthOnlySubMeshes.push(subMesh);
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/cell/cellMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export class CellMaterial extends PushMaterial {
defines.CELLBASIC = !this.computeHighLevel;

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Lights
defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/fur/furMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export class FurMaterial extends PushMaterial {
}

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Lights
defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/gradient/gradientMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export class GradientMaterial extends PushMaterial {

PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances ? true : false);

PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);

Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/lava/lavaMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ export class LavaMaterial extends PushMaterial {
}

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Lights
defines._needNormals = true;
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/mix/mixMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ export class MixMaterial extends PushMaterial {
}

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Lights
defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/normal/normalMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export class NormalMaterial extends PushMaterial {
}

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Lights
defines._needNormals = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export class ShadowOnlyMaterial extends PushMaterial {

PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances ? true : false);

PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, 1);

Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/simple/simpleMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export class SimpleMaterial extends PushMaterial {
}

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Lights
defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/terrain/terrainMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export class TerrainMaterial extends PushMaterial {
}

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Lights
defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/triPlanar/triPlanarMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export class TriPlanarMaterial extends PushMaterial {
}

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

// Lights
defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
Expand Down
2 changes: 1 addition & 1 deletion packages/dev/materials/src/water/waterMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ export class WaterMaterial extends PushMaterial {

PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances ? true : false);

PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this.needAlphaTestingForMesh(mesh), defines);

if (defines._areMiscDirty) {
defines.FRESNELSEPARATE = this._fresnelSeparate;
Expand Down
Loading

0 comments on commit 69cdc19

Please sign in to comment.