Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ export class NativeShaderProcessor implements IShaderProcessor {
code = code.replace(/gl_FragData/g, "glFragData");
code = code.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension || hasOutput ? "" : "layout(location = 0) out vec4 glFragColor;\n") + "void main(");
} else {
if (defines.indexOf("#define VERTEXOUTPUT_INVARIANT") >= 0) {
code = "invariant gl_Position;\n" + code;
}
if (this._nativeProcessingContext?.injectInVertexMain) {
code = InjectStartingAndEndingCode(code, "void main", this._nativeProcessingContext.injectInVertexMain);
}
Expand Down
3 changes: 3 additions & 0 deletions packages/dev/core/src/Engines/WebGL/webGL2ShaderProcessors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export class WebGL2ShaderProcessor implements IShaderProcessor {
code = code.replace(/gl_FragData/g, "glFragData");
code = code.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension || hasOutput ? "" : outputDeclaration) + "void main(");
} else {
if (defines.indexOf("#define VERTEXOUTPUT_INVARIANT") >= 0) {
code = "invariant gl_Position;\n" + code;
}
const hasMultiviewExtension = defines.indexOf("#define MULTIVIEW") !== -1;
if (hasMultiviewExtension) {
return "#extension GL_OVR_multiview2 : require\nlayout (num_views = 2) in;\n" + code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,8 @@ export class WebGPUShaderProcessorGLSL extends WebGPUShaderProcessor {
defines: string[],
isFragment: boolean,
_processingContext: Nullable<_IShaderProcessingContext>,
_parameters?: { [key: string]: number | string | boolean | undefined }
_parameters: { [key: string]: number | string | boolean | undefined },
preProcessors: { [key: string]: string }
): string {
const hasDrawBuffersExtension = code.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;

Expand Down Expand Up @@ -325,6 +326,9 @@ export class WebGPUShaderProcessorGLSL extends WebGPUShaderProcessor {
code = InjectStartingAndEndingCode(code, "void main", fragCoordCode);
}
} else {
if ("VERTEXOUTPUT_INVARIANT" in preProcessors) {
code = "invariant gl_Position;\n" + code;
}
code = code.replace(/gl_InstanceID/g, "gl_InstanceIndex");
code = code.replace(/gl_VertexID/g, "gl_VertexIndex");
const hasMultiviewExtension = defines.indexOf("#define MULTIVIEW") !== -1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ export class WebGPUShaderProcessorWGSL extends WebGPUShaderProcessor {

code = this._convertDefinesToConst(preProcessors) + code;

if ("VERTEXOUTPUT_INVARIANT" in preProcessors) {
code = "#define VERTEXOUTPUT_INVARIANT\n" + code;
}

return code;
}

Expand Down Expand Up @@ -375,7 +379,8 @@ export class WebGPUShaderProcessorWGSL extends WebGPUShaderProcessor {
vertexInputs += "\n};\nvar<private> vertexInputs : VertexInputs_;\n";
}

let vertexOutputs = "struct FragmentInputs {\n @builtin(position) position : vec4<f32>,\n";
let vertexOutputs =
"struct FragmentInputs {\n @builtin(position)" + (vertexCode.indexOf("#define VERTEXOUTPUT_INVARIANT") >= 0 ? " @invariant" : "") + " position : vec4<f32>,\n";
if (this._varyingsWGSL.length > 0) {
vertexOutputs += this._varyingsWGSL.join("\n");
}
Expand Down
14 changes: 13 additions & 1 deletion packages/dev/core/src/Materials/Background/backgroundMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,19 @@ export class BackgroundMaterial extends PushMaterial {
}

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

// Values that need to be evaluated on every frame
PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, subMesh.getRenderingMesh().hasThinInstances);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,19 @@ export class GaussianSplattingMaterial extends PushMaterial {
const gsMesh = mesh as GaussianSplattingMesh;

// Misc.
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, false, defines);
PrepareDefinesForMisc(
mesh,
scene,
this._useLogarithmicDepth,
this.pointsCloud,
this.fogEnabled,
false,
defines,
undefined,
undefined,
undefined,
this._setVertexOutputInvariant
);

// Values that need to be evaluated on every frame
PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, true);
Expand Down
3 changes: 2 additions & 1 deletion packages/dev/core/src/Materials/PBR/pbrBaseMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,8 @@ export abstract class PBRBaseMaterial extends PushMaterial {
defines,
this._applyDecalMapAfterDetailMap,
this._useVertexPulling,
renderingMesh
renderingMesh,
this._setVertexOutputInvariant
);
defines.UNLIT = this._unlit || ((this.pointsCloud || this.wireframe) && !mesh.isVerticesDataPresent(VertexBuffer.NormalKind));
defines.DEBUGMODE = this._debugMode;
Expand Down
22 changes: 22 additions & 0 deletions packages/dev/core/src/Materials/material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,28 @@ export class Material implements IAnimatable, IClipPlanesHolder {
this._markAllSubMeshesAsMiscDirty();
}

@serialize()
protected _setVertexOutputInvariant = false;
/**
* Gets or sets the vertex output invariant state
* Setting this property to true will force the shader compiler to disable some optimization to make sure the vertex output is always calculated
* the same way across different compilation units.
* You may need to enable this option if you are seeing some depth artifacts when using a depth pre-pass, for e.g.
* Note that this may have an impact on performance, so leave this option disabled if not needed.
*/
public get setVertexOutputInvariant(): boolean {
return this._setVertexOutputInvariant;
}

public set setVertexOutputInvariant(value: boolean) {
if (this._setVertexOutputInvariant === value) {
return;
}

this._setVertexOutputInvariant = value;
this._markAllSubMeshesAsMiscDirty();
}

/**
* @internal
* Stores the effects for the material
Expand Down
2 changes: 2 additions & 0 deletions packages/dev/core/src/Materials/materialDefines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* Manages the defines for the Material
*/
export class MaterialDefines {
public VERTEXOUTPUT_INVARIANT = false;

/** @internal */
protected _keys: string[] = [];
private _isDirty = true;
Expand Down
6 changes: 5 additions & 1 deletion packages/dev/core/src/Materials/materialHelper.functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ export function GetFogState(mesh: AbstractMesh, scene: Scene) {
* @param applyDecalAfterDetail Defines if the decal is applied after or before the detail
* @param useVertexPulling Defines if vertex pulling is used
* @param renderingMesh The mesh used for rendering
* @param setVertexOutputInvariant Defines if the vertex output should be invariant
*/
export function PrepareDefinesForMisc(
mesh: AbstractMesh,
Expand All @@ -512,7 +513,8 @@ export function PrepareDefinesForMisc(
defines: any,
applyDecalAfterDetail: boolean = false,
useVertexPulling: boolean = false,
renderingMesh?: AbstractMesh
renderingMesh?: AbstractMesh,
setVertexOutputInvariant?: boolean
): void {
if (defines._areMiscDirty) {
defines["LOGARITHMICDEPTH"] = useLogarithmicDepth;
Expand All @@ -527,6 +529,8 @@ export function PrepareDefinesForMisc(

defines["VERTEX_PULLING_USE_INDEX_BUFFER"] = !!indexBuffer;
defines["VERTEX_PULLING_INDEX_BUFFER_32BITS"] = indexBuffer ? indexBuffer.is32Bits : false;

defines["VERTEXOUTPUT_INVARIANT"] = !!setVertexOutputInvariant;
}
}

Expand Down
3 changes: 2 additions & 1 deletion packages/dev/core/src/Materials/standardMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1250,7 +1250,8 @@ export class StandardMaterial extends PushMaterial {
defines,
this._applyDecalMapAfterDetailMap,
this._useVertexPulling,
subMesh.getRenderingMesh()
subMesh.getRenderingMesh(),
this._setVertexOutputInvariant
);

// Values that need to be evaluated on every frame
Expand Down
8 changes: 0 additions & 8 deletions packages/dev/core/src/Shaders/pbr.vertex.fx
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,6 @@ void main(void) {
// Bend the normal towards the viewer based on the diffuse roughness
vec3 viewDirectionW = normalize(vEyePosition.xyz - vPositionW);

#if !defined(NATIVE) && !defined(WEBGPU)
// Next two lines fixes a flickering that occurs on some specific circumstances on MacOS/iOS
// See https://forum.babylonjs.com/t/needdepthprepass-creates-flickering-in-8-6-2/58421/12
// Note that the variable passed to isnan doesn't matter...
bool bbb = any(isnan(position));
if (bbb) { }
#endif

float NdotV = max(dot(vNormalW, viewDirectionW), 0.0);
vec3 roughNormal = mix(vNormalW, viewDirectionW, (0.5 * (1.0 - NdotV)) * baseDiffuseRoughness);
vec3 reflectionVector = vec3(reflectionMatrix * vec4(roughNormal, 0)).xyz;
Expand Down
14 changes: 13 additions & 1 deletion packages/dev/materials/src/cell/cellMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,19 @@ export class CellMaterial extends PushMaterial {
defines.CELLBASIC = !this.computeHighLevel;

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

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

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

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

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

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

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

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

PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, false, this.fogEnabled, false, defines);
PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, false, this.fogEnabled, false, defines, undefined, undefined, undefined, this._setVertexOutputInvariant);

// Values that need to be evaluated on every frame
PrepareDefinesForFrameBoundValues(scene, scene.getEngine(), this, defines, !!useInstances);
Expand Down
14 changes: 13 additions & 1 deletion packages/dev/materials/src/lava/lavaMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,19 @@ export class LavaMaterial extends PushMaterial {
}

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

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

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

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

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

// Lights
defines._needNormals = true;
Expand Down
14 changes: 13 additions & 1 deletion packages/dev/materials/src/shadowOnly/shadowOnlyMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,19 @@ export class ShadowOnlyMaterial extends PushMaterial {

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

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

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

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

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

// Lights
defines._needNormals = PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
Expand Down
Loading