Skip to content

Commit

Permalink
Make position morph binding as optional in renderers + enable other a…
Browse files Browse the repository at this point in the history
…ttrib type morph (#16024)

* use MorphTargetManager._bind for support texture based morphing

* Unify formatting

* make position morph as optional in shaders + enable other attrib type morph

* fix uv morph enable condition

* apply request changes

* simplify preprocessor conditions

* apply request changes

* lint

* lint

* Update thinEffectLayer.ts
  • Loading branch information
noname0310 authored Dec 31, 2024
1 parent cc283aa commit 3aa6009
Show file tree
Hide file tree
Showing 17 changed files with 371 additions and 251 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export class ComputeShaderBoundingHelper implements IBoundingInfoHelperPlatform
this._processedMeshes.push(mesh);

const manager = (<Mesh>mesh).morphTargetManager;
if (manager) {
if (manager && manager.supportsPositions) {
maxNumInfluencers = Math.max(maxNumInfluencers, manager.numTargets);
}
}
Expand All @@ -165,10 +165,9 @@ export class ComputeShaderBoundingHelper implements IBoundingInfoHelperPlatform
this._uniqueComputeShaders.add(computeShaderWithoutMorph);

const manager = (<Mesh>mesh).morphTargetManager;
if (manager) {
if (manager && manager.supportsPositions) {
defines = defines.slice();
defines.push("#define MORPHTARGETS");
defines.push("#define MORPHTARGETS_POSITION");
defines.push("#define NUM_MORPH_INFLUENCERS " + maxNumInfluencers);

const computeShaderWithMorph = this._getComputeShader(defines, hasBones, true);
Expand Down Expand Up @@ -233,7 +232,7 @@ export class ComputeShaderBoundingHelper implements IBoundingInfoHelperPlatform
const [computeShaderWithoutMorph, computeShaderWithMorph] = this._computeShaders[i];

const manager = (<Mesh>mesh).morphTargetManager;
const hasMorphs = manager && manager.numInfluencers > 0;
const hasMorphs = manager && manager.numInfluencers > 0 && manager.supportsPositions;
const computeShader = hasMorphs ? computeShaderWithMorph : computeShaderWithoutMorph;

this._extractDataAndLink(computeShader, mesh as Mesh, VertexBuffer.PositionKind, 3, "positionBuffer", this._positionBuffers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import type { Engine } from "core/Engines/engine";
import { Constants } from "core/Engines/constants";
import type { Nullable } from "core/types";
import type { AbstractMesh } from "core/Meshes/abstractMesh";
import { BindBonesParameters, BindMorphTargetParameters, PrepareAttributesForBakedVertexAnimation } from "core/Materials/materialHelper.functions";
import {
BindBonesParameters,
BindMorphTargetParameters,
PrepareAttributesForBakedVertexAnimation,
PrepareDefinesAndAttributesForMorphTargets,
} from "core/Materials/materialHelper.functions";
import type { Mesh } from "core/Meshes/mesh";
import type { IBoundingInfoHelperPlatform } from "./IBoundingInfoHelperPlatform";
import { extractMinAndMax } from "core/Maths/math.functions";
Expand Down Expand Up @@ -61,11 +66,8 @@ export class TransformFeedbackBoundingHelper implements IBoundingInfoHelperPlatf

// Get correct effect
let computeEffect: Effect;
let numInfluencers = 0;
const defines: string[] = [];
let uniforms: string[] = [];
const attribs = [VertexBuffer.PositionKind];
const samplers: string[] = [];

// Bones
if (mesh && mesh.useBones && mesh.computeBonesUsingShaders && mesh.skeleton) {
Expand All @@ -75,87 +77,50 @@ export class TransformFeedbackBoundingHelper implements IBoundingInfoHelperPlatf
attribs.push(VertexBuffer.MatricesIndicesExtraKind);
attribs.push(VertexBuffer.MatricesWeightsExtraKind);
}

const skeleton = mesh.skeleton;

defines.push("#define NUM_BONE_INFLUENCERS " + mesh.numBoneInfluencers);

if (skeleton.isUsingTextureForMatrices) {
defines.push("#define BONETEXTURE");

if (uniforms.indexOf("boneTextureWidth") === -1) {
uniforms.push("boneTextureWidth");
}

if (samplers.indexOf("boneSampler") === -1) {
samplers.push("boneSampler");
}
} else {
defines.push("#define BonesPerMesh " + (skeleton.bones.length + 1));

if (uniforms.indexOf("mBones") === -1) {
uniforms.push("mBones");
}
}
defines.push("#define BONETEXTURE " + mesh.skeleton.isUsingTextureForMatrices);
defines.push("#define BonesPerMesh " + (mesh.skeleton.bones.length + 1));
} else {
defines.push("#define NUM_BONE_INFLUENCERS 0");
}

// Morph
const manager = mesh ? (<Mesh>mesh).morphTargetManager : null;
if (manager) {
numInfluencers = manager.numMaxInfluencers || manager.numInfluencers;
if (numInfluencers > 0) {
defines.push("#define MORPHTARGETS");
defines.push("#define MORPHTARGETS_POSITION");
}
if (manager.isUsingTextureForTargets) {
defines.push("#define MORPHTARGETS_TEXTURE");

if (uniforms.indexOf("morphTargetTextureIndices") === -1) {
uniforms.push("morphTargetTextureIndices");
}

if (samplers.indexOf("morphTargets") === -1) {
samplers.push("morphTargets");
}
}
defines.push("#define NUM_MORPH_INFLUENCERS " + numInfluencers);
for (let index = 0; index < numInfluencers; index++) {
attribs.push(VertexBuffer.PositionKind + index);
}
if (numInfluencers > 0) {
uniforms = uniforms.slice();
uniforms.push("morphTargetInfluences");
uniforms.push("morphTargetCount");
uniforms.push("morphTargetTextureInfo");
uniforms.push("morphTargetTextureIndices");
}
}
const numMorphInfluencers = mesh.morphTargetManager
? PrepareDefinesAndAttributesForMorphTargets(
mesh.morphTargetManager,
defines,
attribs,
mesh,
true, // usePositionMorph
false, // useNormalMorph
false, // useTangentMorph
false, // useUVMorph
false // useUV2Morph
)
: 0;

// Baked Vertex Animation
const bvaManager = (<Mesh>mesh).bakedVertexAnimationManager;

if (bvaManager && bvaManager.isEnabled) {
defines.push("#define BAKED_VERTEX_ANIMATION_TEXTURE");
if (uniforms.indexOf("bakedVertexAnimationSettings") === -1) {
uniforms.push("bakedVertexAnimationSettings");
}
if (uniforms.indexOf("bakedVertexAnimationTextureSizeInverted") === -1) {
uniforms.push("bakedVertexAnimationTextureSizeInverted");
}
if (uniforms.indexOf("bakedVertexAnimationTime") === -1) {
uniforms.push("bakedVertexAnimationTime");
}

if (samplers.indexOf("bakedVertexAnimationTexture") === -1) {
samplers.push("bakedVertexAnimationTexture");
}
PrepareAttributesForBakedVertexAnimation(attribs, mesh, defines);
}

const join = defines.join("\n");
if (!this._effects[join]) {
const uniforms = [
"boneTextureWidth",
"mBones",
"morphTargetInfluences",
"morphTargetCount",
"morphTargetTextureInfo",
"morphTargetTextureIndices",
"bakedVertexAnimationSettings",
"bakedVertexAnimationTextureSizeInverted",
"bakedVertexAnimationTime",
];
const samplers = ["boneSampler", "morphTargets", "bakedVertexAnimationTexture"];

const computeEffectOptions = {
attributes: attribs,
uniformsNames: uniforms,
Expand All @@ -165,7 +130,7 @@ export class TransformFeedbackBoundingHelper implements IBoundingInfoHelperPlatf
fallbacks: null,
onCompiled: null,
onError: null,
indexParameters: { maxSimultaneousMorphTargets: numInfluencers },
indexParameters: { maxSimultaneousMorphTargets: numMorphInfluencers },
maxSimultaneousLights: 0,
transformFeedbackVaryings: ["outPosition"],
};
Expand Down Expand Up @@ -204,9 +169,9 @@ export class TransformFeedbackBoundingHelper implements IBoundingInfoHelperPlatf
BindBonesParameters(mesh, effect);

// Morph targets
const manager = (<Mesh>mesh).morphTargetManager;
if (manager && manager.numInfluencers > 0) {
BindMorphTargetParameters(<Mesh>mesh, effect);
BindMorphTargetParameters(mesh, effect);
if (mesh.morphTargetManager && mesh.morphTargetManager.isUsingTextureForTargets) {
mesh.morphTargetManager._bind(effect);
}

// BVA
Expand Down
31 changes: 15 additions & 16 deletions packages/dev/core/src/Layers/thinEffectLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import type { DataBuffer } from "../Buffers/dataBuffer";
import { EffectFallbacks } from "../Materials/effectFallbacks";
import { DrawWrapper } from "../Materials/drawWrapper";
import { addClipPlaneUniforms, bindClipPlane, prepareStringDefinesForClipPlanes } from "../Materials/clipPlaneMaterialHelper";
import { BindMorphTargetParameters, PrepareAttributesForMorphTargetsInfluencers, PushAttributesForInstances } from "../Materials/materialHelper.functions";
import { BindMorphTargetParameters, PrepareDefinesAndAttributesForMorphTargets, PushAttributesForInstances } from "../Materials/materialHelper.functions";
import { ShaderLanguage } from "core/Materials/shaderLanguage";
import { ObjectRenderer } from "core/Rendering/objectRenderer";

Expand Down Expand Up @@ -541,20 +541,19 @@ export class ThinEffectLayer {
}

// Morph targets
const manager = (<Mesh>mesh).morphTargetManager;
let morphInfluencers = 0;
if (manager) {
morphInfluencers = manager.numMaxInfluencers || manager.numInfluencers;
if (morphInfluencers > 0) {
defines.push("#define MORPHTARGETS");
defines.push("#define MORPHTARGETS_POSITION");
defines.push("#define NUM_MORPH_INFLUENCERS " + morphInfluencers);
if (manager.isUsingTextureForTargets) {
defines.push("#define MORPHTARGETS_TEXTURE");
}
PrepareAttributesForMorphTargetsInfluencers(attribs, mesh, morphInfluencers);
}
}
const numMorphInfluencers = mesh.morphTargetManager
? PrepareDefinesAndAttributesForMorphTargets(
mesh.morphTargetManager,
defines,
attribs,
mesh,
true, // usePositionMorph
false, // useNormalMorph
false, // useTangentMorph
uv1, // useUVMorph
uv2 // useUV2Morph
)
: 0;

// Instances
if (useInstances) {
Expand Down Expand Up @@ -604,7 +603,7 @@ export class ThinEffectLayer {
fallbacks,
undefined,
undefined,
{ maxSimultaneousMorphTargets: morphInfluencers },
{ maxSimultaneousMorphTargets: numMorphInfluencers },
this._shaderLanguage,
this._shadersLoaded
? undefined
Expand Down
39 changes: 22 additions & 17 deletions packages/dev/core/src/Lights/Shadows/shadowGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import type { BaseTexture } from "../../Materials/Textures/baseTexture";
import {
BindMorphTargetParameters,
BindSceneUniformBuffer,
PrepareAttributesForMorphTargetsInfluencers,
PrepareDefinesAndAttributesForMorphTargets,
PushAttributesForInstances,
} from "../../Materials/materialHelper.functions";
import { ShaderLanguage } from "core/Materials/shaderLanguage";
Expand Down Expand Up @@ -1329,7 +1329,6 @@ export class ShadowGenerator implements IShadowGenerator {

// Morph targets
BindMorphTargetParameters(renderingMesh, effect);

if (renderingMesh.morphTargetManager && renderingMesh.morphTargetManager.isUsingTextureForTargets) {
renderingMesh.morphTargetManager._bind(effect);
}
Expand Down Expand Up @@ -1552,10 +1551,15 @@ export class ShadowGenerator implements IShadowGenerator {

const mesh = subMesh.getMesh();

let useNormal = false;
let uv1 = false;
let uv2 = false;

// Normal bias.
if (this.normalBias && mesh.isVerticesDataPresent(VertexBuffer.NormalKind)) {
attribs.push(VertexBuffer.NormalKind);
defines.push("#define NORMAL");
useNormal = true;
if (mesh.nonUniformScaling) {
defines.push("#define NONUNIFORMSCALING");
}
Expand Down Expand Up @@ -1584,11 +1588,13 @@ export class ShadowGenerator implements IShadowGenerator {
if (mesh.isVerticesDataPresent(VertexBuffer.UVKind)) {
attribs.push(VertexBuffer.UVKind);
defines.push("#define UV1");
uv1 = true;
}
if (mesh.isVerticesDataPresent(VertexBuffer.UV2Kind)) {
if (this._opacityTexture.coordinatesIndex === 1) {
attribs.push(VertexBuffer.UV2Kind);
defines.push("#define UV2");
uv2 = true;
}
}
}
Expand Down Expand Up @@ -1619,20 +1625,19 @@ export class ShadowGenerator implements IShadowGenerator {
}

// Morph targets
const manager = (<Mesh>mesh).morphTargetManager;
let morphInfluencers = 0;
if (manager) {
morphInfluencers = manager.numMaxInfluencers || manager.numInfluencers;
if (morphInfluencers > 0) {
defines.push("#define MORPHTARGETS");
defines.push("#define MORPHTARGETS_POSITION");
defines.push("#define NUM_MORPH_INFLUENCERS " + morphInfluencers);
if (manager.isUsingTextureForTargets) {
defines.push("#define MORPHTARGETS_TEXTURE");
}
PrepareAttributesForMorphTargetsInfluencers(attribs, mesh, morphInfluencers);
}
}
const numMorphInfluencers = mesh.morphTargetManager
? PrepareDefinesAndAttributesForMorphTargets(
mesh.morphTargetManager,
defines,
attribs,
mesh,
true, // usePositionMorph
useNormal, // useNormalMorph
false, // useTangentMorph
uv1, // useUVMorph
uv2 // useUV2Morph
)
: 0;

// ClipPlanes
prepareStringDefinesForClipPlanes(material, this._scene, defines);
Expand Down Expand Up @@ -1737,7 +1742,7 @@ export class ShadowGenerator implements IShadowGenerator {
fallbacks: fallbacks,
onCompiled: null,
onError: null,
indexParameters: { maxSimultaneousMorphTargets: morphInfluencers },
indexParameters: { maxSimultaneousMorphTargets: numMorphInfluencers },
shaderLanguage: this._shaderLanguage,
},
engine
Expand Down
Loading

0 comments on commit 3aa6009

Please sign in to comment.