Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make position morph binding as optional in renderers + enable other attrib type morph #16024

Merged
merged 11 commits into from
Dec 31, 2024
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) {
Popov72 marked this conversation as resolved.
Show resolved Hide resolved
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