Skip to content

Commit

Permalink
feat(model): add full shader selection logic to batches (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
fallenoak authored Jan 22, 2024
1 parent bef2702 commit 7725533
Show file tree
Hide file tree
Showing 8 changed files with 678 additions and 95 deletions.
Binary file added fixture/model/tank.m2
Binary file not shown.
Binary file added fixture/model/tank00.skin
Binary file not shown.
30 changes: 26 additions & 4 deletions src/lib/model/M2Batch.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,50 @@
import M2Material from './M2Material.js';
import M2SkinSection from './M2SkinSection.js';
import M2BatchTexture from './M2BatchTexture.js';
import M2Texture from './M2Texture.js';
import { M2_FRAGMENT_SHADER, M2_VERTEX_SHADER } from './const.js';

class M2Batch {
#flags: number;
#priorityPlane: number;
#skinSection: M2SkinSection;
#material: M2Material;
#textures: M2BatchTexture[];
#layer: number;
#textures: M2Texture[];
#vertexShader: M2_VERTEX_SHADER;
#fragmentShader: M2_FRAGMENT_SHADER;

constructor(
flags: number,
priorityPlane: number,
skinSection: M2SkinSection,
material: M2Material,
textures: M2BatchTexture[],
layer: number,
textures: M2Texture[],
vertexShader: M2_VERTEX_SHADER,
fragmentShader: M2_FRAGMENT_SHADER,
) {
this.#flags = flags;
this.#priorityPlane = priorityPlane;
this.#skinSection = skinSection;
this.#material = material;
this.#layer = layer;
this.#textures = textures;
this.#vertexShader = vertexShader;
this.#fragmentShader = fragmentShader;
}

get flags() {
return this.#flags;
}

get fragmentShader() {
return this.#fragmentShader;
}

get layer() {
return this.#layer;
}

get material() {
return this.#material;
}
Expand All @@ -42,7 +60,11 @@ class M2Batch {
get textures() {
return this.#textures;
}

get vertexShader() {
return this.#vertexShader;
}
}

export default M2Batch;
export { M2Batch };
export { M2Batch, M2_VERTEX_SHADER, M2_FRAGMENT_SHADER };
47 changes: 0 additions & 47 deletions src/lib/model/M2BatchTexture.ts

This file was deleted.

56 changes: 14 additions & 42 deletions src/lib/model/M2SkinProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import * as m2Io from './io/m2.js';
import M2Batch from './M2Batch.js';
import M2Model from './M2Model.js';
import M2SkinSection from './M2SkinSection.js';
import M2BatchTexture from './M2BatchTexture.js';
import { M2_MATERIAL_BLEND, M2_MODEL_FLAG, M2_TEXTURE_COMBINER } from './const.js';
import { M2_FRAGMENT_SHADER, M2_VERTEX_SHADER } from './const.js';
import { getBatchShaders, normalizeBatches } from './batch.js';

class M2SkinProfile {
#model: M2Model;
Expand Down Expand Up @@ -66,64 +66,36 @@ class M2SkinProfile {
}

#loadBatches(data: any) {
for (const batchData of data.batches) {
// TODO process batches above layer 0 - while batches above layer 0 are typically discarded
// at runtime, they occasionally contain information needed to identify
// specialized shading logic (eg. Combiners_Opaque_Mod2xNA_Alpha)
if (batchData.materialLayer > 0) {
for (const batchData of normalizeBatches(this.#model, data.batches)) {
const { vertexShader, fragmentShader } = getBatchShaders(this.#model, batchData);

if (
vertexShader === M2_VERTEX_SHADER.VERTEX_UNKNOWN ||
fragmentShader === M2_FRAGMENT_SHADER.FRAGMENT_UNKNOWN
) {
continue;
}

const skinSection = this.#skinSections[batchData.skinSectionIndex];
const material = this.#model.materials[batchData.materialIndex];
const useCombinerCombos = this.#model.flags & M2_MODEL_FLAG.USE_COMBINER_COMBOS;

const textures = [];
for (let i = 0; i < batchData.textureCount; i++) {
const textureIndex = this.#model.textureCombos[batchData.textureComboIndex + i];
const textureIndex = batchData.textureIndices[i];
const texture = this.#model.textures[textureIndex];

let textureCombiner = M2_TEXTURE_COMBINER.COMBINER_OPAQUE;
if (useCombinerCombos) {
if (i === 0 && material.blend === M2_MATERIAL_BLEND.BLEND_OPAQUE) {
textureCombiner = M2_TEXTURE_COMBINER.COMBINER_OPAQUE;
} else {
textureCombiner = this.#model.textureCombinerCombos[batchData.shaderId + i];
}
} else {
textureCombiner =
material.blend === M2_MATERIAL_BLEND.BLEND_OPAQUE
? M2_TEXTURE_COMBINER.COMBINER_OPAQUE
: M2_TEXTURE_COMBINER.COMBINER_MOD;
}

const textureCoord = this.#model.textureCoordCombos[batchData.textureCoordComboIndex + i];

const textureWeightIndex =
this.#model.textureWeightCombos[batchData.textureWeightComboIndex + i];
const textureWeight = this.#model.textureWeights[textureWeightIndex];

const textureTransformIndex =
this.#model.textureTransformCombos[batchData.textureTransformComboIndex + i];
const textureTransform = this.#model.textureTransforms[textureTransformIndex];

textures.push(
new M2BatchTexture(
texture,
textureCombiner,
textureCoord,
textureWeight,
textureTransform,
),
);
textures.push(texture);
}

const batch = new M2Batch(
batchData.flags,
batchData.priorityPlane,
skinSection,
material,
batchData.materialLayer,
textures,
vertexShader,
fragmentShader,
);

this.#batches.push(batch);
Expand Down
Loading

0 comments on commit 7725533

Please sign in to comment.