Skip to content

Fix mesh uploading.#40

Merged
papiguy merged 3 commits into
Stem-Studio:mainfrom
querielo:kirill/splat-skin
Jun 5, 2026
Merged

Fix mesh uploading.#40
papiguy merged 3 commits into
Stem-Studio:mainfrom
querielo:kirill/splat-skin

Conversation

@querielo

@querielo querielo commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Screen.Recording.2026-06-05.at.14.37.44.mp4

This fixes the skinned-mesh interop path inside the Spark composite bridge when the scene uses both WebGPU and the temporary WebGL depth pass.

Why this fixes it

WebGL and WebGPU were sharing mutable skinning state across the bridge:

  • WebGL was allowed to reinterpret or expand skinning data for its own shader path
  • WebGPU then inherited that mutated state and tried to use it with its compact buffer path

This change makes the WebGL pass explicitly transactional:

  • swap into WebGL-compatible skin data before render
  • restore WebGPU-compatible skin data immediately after render

Copilot AI review requested due to automatic review settings June 5, 2026 12:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds/adjusts Spark rendering integrations to improve Gaussian splat lighting, skinned-mesh depth handling, and worker-based model preview loading.

Changes:

  • Introduces SparkSceneLightingBridge and wires it into EffectRenderer for dynamic lighting edits.
  • Patches Spark composite rendering to render skinned-mesh depth via a WebGL pre-pass and cleans up related resources.
  • Refactors the model-preview worker to lazy-load heavy modules and expand DOM/event polyfills; adds a Bun patched dependency for @querielo/spark.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
vite.config.ts Restricts React refresh processing via include/exclude.
patches/@querielo%2Fspark@2.0.0.patch Patches Spark’s renderable-object detection to avoid instanceof.
package.json Registers Bun patchedDependencies for @querielo/spark.
bun.lock Locks patched dependency mapping.
client/packages/editor-oss/src/render/SparkLightingBridge.ts New dynamic lighting bridge that converts Three lights to Spark SDF edits.
client/packages/editor-oss/src/render/SparkCompositeBridge.ts Adds skinned-mesh depth workaround using WebGLRenderer and manages temporary state.
client/packages/editor-oss/src/render/EffectRenderer.js Creates/updates/disposes the scene lighting bridge during render lifecycle.
client/packages/editor-oss/src/helper/light/VolumePointLightHelper.js Reimplements helper as LineSegments with explicit dispose/update.
client/packages/editor-oss/src/editor/assets/v2/.../render.worker.ts Improves worker polyfills and lazy-loads GLTFLoader/ModelPreviewRenderer.
client/packages/editor-oss/src/editor/assets/v2/.../ModelPreviewRenderer.ts Tunes preview lighting and only enables Spark composite for Gaussian splats.
client/packages/editor-oss/src/editor/Editor.ts Improves selection boundary logic for skinned meshes.
client/packages/editor-oss/src/assets/js/loaders/SparkGaussianSplatLoader.ts Enables editable: true for loaded splat meshes.
client/packages/editor-oss/src/assets/js/animations/poseFit.ts Removes computeBoneTexture call after pose application.
client/packages/editor-oss/src/EngineRuntime.ts Changes WebGPU/WebGL forcing logic (currently hard-coded).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


private createWebGPURenderer(overrideForceWebGL?: boolean): WebGPURenderer {
const forceWebGL = overrideForceWebGL ?? (this.editor?.scene?.userData?.rendering?.forceWebGL || false);
const forceWebGL = !true;
Comment on lines +422 to +427
private syncSdfColor(sdf: SplatEditSdf, light: Light, overrides: SparkLightOverrides, strength: number): void {
sdf.opacity = isFiniteNumber(overrides.opacity) ? Math.min(1, Math.max(0, overrides.opacity)) : 0;
sdf.color
.copy(getLightColor(light, overrides, this.lightColor))
.multiplyScalar(strength);
}
Comment on lines +126 to +162
async function updateModelPayload(payload: ArrayBuffer) {
if (!renderer) return;

const { GLTFLoader } = await import('three/examples/jsm/loaders/GLTFLoader.js');
const loader = new GLTFLoader();

let renderer: ModelPreviewRenderer | undefined;
try {
loader.parse(
payload,
'',
(gltf) => {
renderer?.updateModel(gltf.scene);
},
(error) => {
const payloadType = payload ? payload.constructor?.name ?? typeof payload : typeof payload;
const sizeInfo =
payload instanceof ArrayBuffer
? `, byteLength=${payload.byteLength}`
: '';
console.error(
`Worker: Failed to parse GLB (payloadType=${payloadType}${sizeInfo})`,
error,
);
},
);
} catch (err) {
const payloadType = payload ? payload.constructor?.name ?? typeof payload : typeof payload;
const sizeInfo =
payload instanceof ArrayBuffer
? `, byteLength=${payload.byteLength}`
: '';
console.error(
`Worker: Failed to parse model (payloadType=${payloadType}${sizeInfo})`,
err,
);
}
}
Comment on lines +124 to +152
const restoreSkeletons = (snapshots: Map<Skeleton, SkeletonState>) => {
for (const [skeleton, snapshot] of snapshots) {
const compactLength = skeleton.bones.length * 16;
const currentBoneTexture = skeleton.boneTexture;

skeleton.boneMatrices = compactSkeletonMatrices(
skeleton.boneMatrices,
snapshot.boneMatrices,
compactLength,
);
skeleton.previousBoneMatrices = compactSkeletonMatrices(
skeleton.previousBoneMatrices,
snapshot.previousBoneMatrices,
compactLength,
);

if (currentBoneTexture && currentBoneTexture !== snapshot.boneTexture) {
currentBoneTexture.dispose();
}

if (snapshot.boneTexture) {
snapshot.boneTexture.dispose();
}

// WebGLRenderer creates a padded boneTexture/boneMatrices pair. The
// surrounding WebGPU renderer expects compact bone matrix buffers.
skeleton.boneTexture = null;
}
};
@papiguy papiguy merged commit 644b922 into Stem-Studio:main Jun 5, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants