fix(viewer): harden WebGPU slab recovery (#518)
Co-authored-by: Connor Soohoo <connorsoohoo@users.noreply.github.com>
This commit is contained in:
co-authored by
Connor Soohoo
parent
a7734b8ffe
commit
87f3952e4d
@@ -0,0 +1,31 @@
|
|||||||
|
import { describe, expect, test } from 'bun:test'
|
||||||
|
import { SlabNode } from '@pascal-app/core'
|
||||||
|
import { Mesh } from 'three'
|
||||||
|
import { buildSlabGeometry } from '../geometry'
|
||||||
|
|
||||||
|
describe('buildSlabGeometry', () => {
|
||||||
|
test('copies the primary UVs into uv2 for every slab mesh', () => {
|
||||||
|
const slab = SlabNode.parse({
|
||||||
|
polygon: [
|
||||||
|
[0, 0],
|
||||||
|
[2, 0],
|
||||||
|
[2, 2],
|
||||||
|
[0, 2],
|
||||||
|
],
|
||||||
|
})
|
||||||
|
|
||||||
|
const group = buildSlabGeometry(slab, undefined, 'solid', false)
|
||||||
|
const meshes = group.children.filter((child): child is Mesh => child instanceof Mesh)
|
||||||
|
|
||||||
|
expect(meshes).toHaveLength(2)
|
||||||
|
for (const mesh of meshes) {
|
||||||
|
const uv = mesh.geometry.getAttribute('uv')
|
||||||
|
const uv2 = mesh.geometry.getAttribute('uv2')
|
||||||
|
|
||||||
|
expect(uv2).toBeDefined()
|
||||||
|
expect(uv2.itemSize).toBe(2)
|
||||||
|
expect(uv2.count).toBe(uv.count)
|
||||||
|
expect(Array.from(uv2.array)).toEqual(Array.from(uv.array))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -127,7 +127,10 @@ function splitSlabFacesByFacing(geometry: BufferGeometry): {
|
|||||||
const build = (data: { pos: number[]; uv: number[] }) => {
|
const build = (data: { pos: number[]; uv: number[] }) => {
|
||||||
const geo = new BufferGeometry()
|
const geo = new BufferGeometry()
|
||||||
geo.setAttribute('position', new Float32BufferAttribute(data.pos, 3))
|
geo.setAttribute('position', new Float32BufferAttribute(data.pos, 3))
|
||||||
if (data.uv.length > 0) geo.setAttribute('uv', new Float32BufferAttribute(data.uv, 2))
|
if (data.uv.length > 0) {
|
||||||
|
geo.setAttribute('uv', new Float32BufferAttribute(data.uv, 2))
|
||||||
|
geo.setAttribute('uv2', new Float32BufferAttribute(data.uv.slice(), 2))
|
||||||
|
}
|
||||||
geo.computeVertexNormals()
|
geo.computeVertexNormals()
|
||||||
return geo
|
return geo
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -755,6 +755,8 @@ const PostProcessingPasses = ({
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
hasPipelineErrorRef.current = true
|
hasPipelineErrorRef.current = true
|
||||||
|
// A failed MRT pass may leave its target bound; clear it before the fallback render.
|
||||||
|
;(renderer as any).setRenderTarget?.(null)
|
||||||
console.error('[viewer/post-processing] Render pass failed.', {
|
console.error('[viewer/post-processing] Render pass failed.', {
|
||||||
retryCount: retryCountRef.current,
|
retryCount: retryCountRef.current,
|
||||||
rendererCtor: (renderer as any).constructor?.name,
|
rendererCtor: (renderer as any).constructor?.name,
|
||||||
|
|||||||
Reference in New Issue
Block a user