import { describe, expect, it } from 'vitest' import * as THREE from 'three' import { applyGuideModelMaterialPolicy, GUIDE_MODEL_MATERIAL_POLICY } from '@/components/map/modelMaterialPolicy' const meshWith = (material: THREE.Material) => new THREE.Mesh( new THREE.BoxGeometry(1, 1, 1), material ) describe('guide GLB material policy', () => { it('raises the roughness floor and limits environment reflection for opaque non-metal PBR materials', () => { const root = new THREE.Group() const wall = new THREE.MeshStandardMaterial({ roughness: 0.12, metalness: 0.05, envMapIntensity: 1 }) root.add(meshWith(wall)) expect(applyGuideModelMaterialPolicy(root)).toEqual({ pbrMaterialCount: 1, nonMetalMaterialCount: 1, protectedMaterialCount: 0 }) expect(wall.roughness).toBe(GUIDE_MODEL_MATERIAL_POLICY.nonMetalRoughnessFloor) expect(wall.envMapIntensity).toBe(GUIDE_MODEL_MATERIAL_POLICY.envMapIntensity) }) it('also applies the roughness floor after a non-metal roughness texture is sampled', () => { const root = new THREE.Group() const floor = new THREE.MeshStandardMaterial({ roughness: 1, metalness: 0 }) floor.roughnessMap = new THREE.Texture() root.add(meshWith(floor)) applyGuideModelMaterialPolicy(root) const shader = { fragmentShader: '#include ' } floor.onBeforeCompile(shader as any, {} as any) expect(shader.fragmentShader).toContain('roughnessFactor = max(roughnessFactor, 0.48);') expect(floor.customProgramCacheKey()).toContain('guide-non-metal-roughness-floor') }) it('caps imported specular extensions on opaque non-metal physical materials', () => { const root = new THREE.Group() const wall = new THREE.MeshPhysicalMaterial({ roughness: 0.55, metalness: 0, specularIntensity: 1 }) root.add(meshWith(wall)) applyGuideModelMaterialPolicy(root) expect(wall.specularIntensity).toBe(GUIDE_MODEL_MATERIAL_POLICY.nonMetalSpecularIntensityCap) }) it('keeps authored roughness on metal, transparent and glass materials while limiting environment reflection', () => { const root = new THREE.Group() const metal = new THREE.MeshStandardMaterial({ roughness: 0.08, metalness: 0.9, envMapIntensity: 1 }) const transparent = new THREE.MeshStandardMaterial({ roughness: 0.08, transparent: true, opacity: 0.4, envMapIntensity: 1 }) const glass = new THREE.MeshPhysicalMaterial({ roughness: 0.08, transmission: 0.9, envMapIntensity: 1, specularIntensity: 1 }) root.add(meshWith(metal), meshWith(transparent), meshWith(glass)) expect(applyGuideModelMaterialPolicy(root)).toEqual({ pbrMaterialCount: 3, nonMetalMaterialCount: 0, protectedMaterialCount: 3 }) expect([metal.roughness, transparent.roughness, glass.roughness]).toEqual([0.08, 0.08, 0.08]) expect(glass.specularIntensity).toBe(1) expect([metal.envMapIntensity, transparent.envMapIntensity, glass.envMapIntensity]) .toEqual([0.42, 0.42, 0.42]) }) })