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
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"**/.rollup.cache": true,
"**/packages/dev/**/Shaders/**/*.ts": true,
"**/packages/dev/**/shaders/**/*.ts": true,
"**/packages/dev/**/ShadersWGSL/**/*.ts": true,
"**/*.fragment.ts": true,
"**/*.vertex.ts": true,
"**/*.compute.ts": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,15 @@ export class WebGPUShaderProcessorWGSL extends WebGPUShaderProcessor {
return texture;
}

public postProcessor(code: string) {
return code;
public postProcessor(code: string, defines: string[]) {
const defineToValue: { [key: string]: string } = {};
for (const define of defines) {
const parts = define.split(/ +/);
defineToValue[parts[1]] = parts.length > 2 ? parts[2] : "";
}
return code.replace(/\$(\w+)\$/g, (_, p1) => {
return defineToValue[p1] ?? p1;
});
}

public finalizeShaders(vertexCode: string, fragmentCode: string): { vertexCode: string; fragmentCode: string } {
Expand Down
7 changes: 4 additions & 3 deletions packages/dev/core/src/Materials/materialHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ export class MaterialHelper {
defines["MORPHTARGETS_UV"] = manager.supportsUVs && defines["UV1"];
defines["MORPHTARGETS_TANGENT"] = manager.supportsTangents && defines["TANGENT"];
defines["MORPHTARGETS_NORMAL"] = manager.supportsNormals && defines["NORMAL"];
defines["MORPHTARGETS"] = manager.numInfluencers > 0;
defines["NUM_MORPH_INFLUENCERS"] = manager.numInfluencers;
defines["NUM_MORPH_INFLUENCERS"] = manager.numMaxInfluencers || manager.numInfluencers;
defines["MORPHTARGETS"] = defines["NUM_MORPH_INFLUENCERS"] > 0;

defines["MORPHTARGETS_TEXTURE"] = manager.isUsingTextureForTargets;
} else {
Expand Down Expand Up @@ -700,6 +700,7 @@ export class MaterialHelper {

if (defines["NUM_MORPH_INFLUENCERS"]) {
uniformsList.push("morphTargetInfluences");
uniformsList.push("morphTargetCount");
}

if (defines["BAKED_VERTEX_ANIMATION_TEXTURE"]) {
Expand Down Expand Up @@ -815,7 +816,7 @@ export class MaterialHelper {
/**
* Prepares the list of attributes required for baked vertex animations according to the effect defines.
* @param attribs The current list of supported attribs
* @param mesh The mesh to prepare the morph targets attributes for
* @param mesh The mesh to prepare for baked vertex animations
* @param defines The current Defines of the effect
*/
public static PrepareAttributesForBakedVertexAnimation(attribs: string[], mesh: AbstractMesh, defines: any): void {
Expand Down
28 changes: 26 additions & 2 deletions packages/dev/core/src/Morph/morphTargetManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,29 @@ export class MorphTargetManager implements IDisposable {
}
}

private _numMaxInfluencers = 0;

/**
* Gets or sets the maximum number of influencers (targets) (default value: 0).
* Setting a value for this property can lead to a smoother experience, as only one shader will be compiled, which will use this value as the maximum number of influencers.
* If you leave the value at 0 (default), a new shader will be compiled every time the number of active influencers changes. This can cause problems, as compiling a shader takes time.
* If you assign a non-zero value to this property, you need to ensure that this value is greater than the maximum number of (active) influencers you'll need for this morph manager.
* Otherwise, the number of active influencers will be truncated at the value you set for this property, which can lead to unexpected results.
* Note that this property has no effect if "useTextureToStoreTargets" is false.
*/
public get numMaxInfluencers(): number {
return this._numMaxInfluencers;
}

public set numMaxInfluencers(value: number) {
if (this._numMaxInfluencers === value) {
return;
}

this._numMaxInfluencers = value;
this._syncActiveTargets(true);
}

/**
* Gets the unique ID of this manager
*/
Expand Down Expand Up @@ -252,6 +275,7 @@ export class MorphTargetManager implements IDisposable {
effect.setFloat3("morphTargetTextureInfo", this._textureVertexStride, this._textureWidth, this._textureHeight);
effect.setFloatArray("morphTargetTextureIndices", this._morphTargetTextureIndices);
effect.setTexture("morphTargets", this._targetStoreTexture);
effect.setInt("morphTargetCount", this.numInfluencers);
}

/**
Expand Down Expand Up @@ -365,7 +389,7 @@ export class MorphTargetManager implements IDisposable {
return;
}

if (this.isUsingTextureForTargets && this._vertexCount) {
if (this.isUsingTextureForTargets && (this._vertexCount || this.numMaxInfluencers > 0)) {
this._textureVertexStride = 1;

if (this._supportsNormals) {
Expand All @@ -380,7 +404,7 @@ export class MorphTargetManager implements IDisposable {
this._textureVertexStride++;
}

this._textureWidth = this._vertexCount * this._textureVertexStride;
this._textureWidth = this._vertexCount * this._textureVertexStride || 1;
this._textureHeight = 1;

const maxTextureSize = this._scene.getEngine().getCaps().maxTextureSize;
Expand Down
34 changes: 20 additions & 14 deletions packages/dev/core/src/Shaders/ShadersInclude/morphTargetsVertex.fx
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
#ifdef MORPHTARGETS
#ifdef MORPHTARGETS_TEXTURE
vertexID = float(gl_VertexID) * morphTargetTextureInfo.x;
positionUpdated += (readVector3FromRawSampler({X}, vertexID) - position) * morphTargetInfluences[{X}];
vertexID += 1.0;

#ifdef MORPHTARGETS_NORMAL
normalUpdated += (readVector3FromRawSampler({X}, vertexID) - normal) * morphTargetInfluences[{X}];
vertexID += 1.0;
#endif
#ifdef MORPHTARGETS_TEXTURE
#if {X} == 0
for (int i = 0; i < NUM_MORPH_INFLUENCERS; i++) {
if (i >= morphTargetCount) break;

#ifdef MORPHTARGETS_UV
uvUpdated += (readVector3FromRawSampler({X}, vertexID).xy - uv) * morphTargetInfluences[{X}];
vertexID = float(gl_VertexID) * morphTargetTextureInfo.x;
positionUpdated += (readVector3FromRawSampler(i, vertexID) - position) * morphTargetInfluences[i];
vertexID += 1.0;
#endif

#ifdef MORPHTARGETS_NORMAL
normalUpdated += (readVector3FromRawSampler(i, vertexID) - normal) * morphTargetInfluences[i];
vertexID += 1.0;
#endif

#ifdef MORPHTARGETS_TANGENT
tangentUpdated.xyz += (readVector3FromRawSampler({X}, vertexID) - tangent.xyz) * morphTargetInfluences[{X}];
#ifdef MORPHTARGETS_UV
uvUpdated += (readVector3FromRawSampler(i, vertexID).xy - uv) * morphTargetInfluences[i];
vertexID += 1.0;
#endif

#ifdef MORPHTARGETS_TANGENT
tangentUpdated.xyz += (readVector3FromRawSampler(i, vertexID) - tangent.xyz) * morphTargetInfluences[i];
#endif
}
#endif
#else
positionUpdated += (position{X} - position) * morphTargetInfluences[{X}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@
#ifdef MORPHTARGETS_UV
attribute vec2 uv_{X};
#endif
#elif {X} == 0
uniform int morphTargetCount;
#endif
#endif
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
#ifdef MORPHTARGETS
#ifdef MORPHTARGETS_TEXTURE
vertexID = f32(vertexInputs.vertexIndex) * uniforms.morphTargetTextureInfo.x;
positionUpdated = positionUpdated + (readVector3FromRawSampler({X}, vertexID) - vertexInputs.position) * uniforms.morphTargetInfluences[{X}];
vertexID = vertexID + 1.0;

#ifdef MORPHTARGETS_NORMAL
normalUpdated = normalUpdated + (readVector3FromRawSampler({X}, vertexID) - vertexInputs.normal) * uniforms.morphTargetInfluences[{X}];
vertexID = vertexID + 1.0;
#endif
#ifdef MORPHTARGETS_TEXTURE
#if {X} == 0
for (var i = 0; i < $NUM_MORPH_INFLUENCERS$; i = i + 1) {
if (i >= uniforms.morphTargetCount) {
break;
}

#ifdef MORPHTARGETS_UV
uvUpdated = uvUpdated + (readVector3FromRawSampler({X}, vertexID).xy - vertexInputs.uv) * uniforms.morphTargetInfluences[{X}];
vertexID = vertexID + 1.0;
#endif
vertexID = f32(vertexInputs.vertexIndex) * uniforms.morphTargetTextureInfo.x;
positionUpdated = positionUpdated + (readVector3FromRawSampler({X}, vertexID) - vertexInputs.position) * uniforms.morphTargetInfluences[{X}];
vertexID = vertexID + 1.0;

#ifdef MORPHTARGETS_NORMAL
normalUpdated = normalUpdated + (readVector3FromRawSampler({X}, vertexID) - vertexInputs.normal) * uniforms.morphTargetInfluences[{X}];
vertexID = vertexID + 1.0;
#endif

#ifdef MORPHTARGETS_TANGENT
tangentUpdated.xyz = tangentUpdated.xyz + (readVector3FromRawSampler({X}, vertexID) - vertexInputs.tangent.xyz) * uniforms.morphTargetInfluences[{X}];
#ifdef MORPHTARGETS_UV
uvUpdated = uvUpdated + (readVector3FromRawSampler({X}, vertexID).xy - vertexInputs.uv) * uniforms.morphTargetInfluences[{X}];
vertexID = vertexID + 1.0;
#endif

#ifdef MORPHTARGETS_TANGENT
tangentUpdated.xyz = tangentUpdated.xyz + (readVector3FromRawSampler({X}, vertexID) - vertexInputs.tangent.xyz) * uniforms.morphTargetInfluences[{X}];
#endif
}
#endif
#else
positionUpdated = positionUpdated + (position{X} - vertexInputs.position) * uniforms.morphTargetInfluences[{X}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@
#ifdef MORPHTARGETS_UV
attribute uv_{X} : vec2<f32>;
#endif
#elif {X} == 0
uniform morphTargetCount: i32;
#endif
#endif