Skip to content

Commit

Permalink
feat(model): cap model vertex shader bone influences based on model s…
Browse files Browse the repository at this point in the history
…kin section details
  • Loading branch information
fallenoak committed Feb 11, 2024
1 parent f146d53 commit 6819fcd
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 18 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
],
"dependencies": {
"@tweenjs/tween.js": "^23.1.1",
"@wowserhq/format": "^0.24.0"
"@wowserhq/format": "^0.25.0"
},
"peerDependencies": {
"three": "^0.160.0"
Expand Down
2 changes: 2 additions & 0 deletions src/lib/model/ModelManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class ModelManager {
const textureWeightIndex = spec.textureWeightIndex;
const textureTransformIndices = spec.textureTransformIndices;
const materialColorIndex = spec.materialColorIndex;
const boneInfluences = spec.boneInfluences;
const uniforms = { ...this.#sceneLight.uniforms };

return new ModelMaterial(
Expand All @@ -182,6 +183,7 @@ class ModelManager {
textureTransformIndices,
materialColorIndex,
skinned,
boneInfluences,
uniforms,
spec.blend,
spec.flags,
Expand Down
2 changes: 2 additions & 0 deletions src/lib/model/ModelMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class ModelMaterial extends THREE.RawShaderMaterial {
textureTransformIndices: number[],
colorIndex: number,
skinned: boolean = false,
boneInfluences: number = 0,
uniforms: Record<string, THREE.IUniform> = {},
blend = DEFAULT_BLEND,
flags = DEFAULT_FLAGS,
Expand Down Expand Up @@ -72,6 +73,7 @@ class ModelMaterial extends THREE.RawShaderMaterial {

if (skinned) {
this.defines['USE_SKINNING'] = 1;
this.defines['BONE_INFLUENCES'] = boneInfluences;
}

if (this.#blend === M2_MATERIAL_BLEND.BLEND_ALPHA_KEY) {
Expand Down
1 change: 1 addition & 0 deletions src/lib/model/loader/ModelLoaderWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ class ModelLoaderWorker extends SceneWorker {
materialColorIndex: batch.colorIndex,
vertexShader: batch.vertexShader,
fragmentShader: batch.fragmentShader,
boneInfluences: batch.skinSection.boneInfluences,
};
}

Expand Down
1 change: 1 addition & 0 deletions src/lib/model/loader/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type MaterialSpec = {
vertexShader: M2_VERTEX_SHADER;
fragmentShader: M2_FRAGMENT_SHADER;
blend: M2_MATERIAL_BLEND;
boneInfluences: number;
};

type GroupSpec = {
Expand Down
51 changes: 38 additions & 13 deletions src/lib/model/shader/vertex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,18 @@ const VERTEX_SHADER_FUNCTIONS = [VERTEX_SHADER_SPHERE_MAP, VERTEX_SHADER_GET_BON

const VERTEX_SHADER_MAIN_SKINNING = `
#ifdef USE_SKINNING
mat4 boneMatX = getBoneMatrix(skinIndex.x);
mat4 boneMatY = getBoneMatrix(skinIndex.y);
mat4 boneMatZ = getBoneMatrix(skinIndex.z);
mat4 boneMatW = getBoneMatrix(skinIndex.w);
#if BONE_INFLUENCES > 0
mat4 boneMatX = getBoneMatrix(skinIndex.x);
#endif
#if BONE_INFLUENCES > 1
mat4 boneMatY = getBoneMatrix(skinIndex.y);
#endif
#if BONE_INFLUENCES > 2
mat4 boneMatZ = getBoneMatrix(skinIndex.z);
#endif
#if BONE_INFLUENCES > 3
mat4 boneMatW = getBoneMatrix(skinIndex.w);
#endif
#endif
`;

Expand All @@ -73,10 +81,19 @@ vec3 objectNormal = normal;
#ifdef USE_SKINNING
mat4 skinMatrix = mat4(0.0);
skinMatrix += skinWeight.x * boneMatX;
skinMatrix += skinWeight.y * boneMatY;
skinMatrix += skinWeight.z * boneMatZ;
skinMatrix += skinWeight.w * boneMatW;
#if BONE_INFLUENCES > 0
skinMatrix += skinWeight.x * boneMatX;
#endif
#if BONE_INFLUENCES > 1
skinMatrix += skinWeight.y * boneMatY;
#endif
#if BONE_INFLUENCES > 2
skinMatrix += skinWeight.z * boneMatZ;
#endif
#if BONE_INFLUENCES > 3
skinMatrix += skinWeight.w * boneMatW;
#endif
vec3 skinNormal = vec4(skinMatrix * vec4(objectNormal, 0.0)).xyz;
vViewNormal = normalize(skinNormal);
Expand All @@ -95,12 +112,20 @@ ${VARIABLE_FOG_FACTOR.name} = calculateFogFactor(${UNIFORM_FOG_PARAMS.name}, cam
const VERTEX_SHADER_MAIN_POSITION = `
#ifdef USE_SKINNING
vec4 skinVertex = vec4(position, 1.0);
vec4 skinned = vec4(0.0);
skinned += boneMatX * skinVertex * skinWeight.x;
skinned += boneMatY * skinVertex * skinWeight.y;
skinned += boneMatZ * skinVertex * skinWeight.z;
skinned += boneMatW * skinVertex * skinWeight.w;
#if BONE_INFLUENCES > 0
skinned += boneMatX * skinVertex * skinWeight.x;
#endif
#if BONE_INFLUENCES > 1
skinned += boneMatY * skinVertex * skinWeight.y;
#endif
#if BONE_INFLUENCES > 2
skinned += boneMatZ * skinVertex * skinWeight.z;
#endif
#if BONE_INFLUENCES > 3
skinned += boneMatW * skinVertex * skinWeight.w;
#endif
gl_Position = projectionMatrix * skinned;
#else
Expand Down

0 comments on commit 6819fcd

Please sign in to comment.