70 lines
3.0 KiB
TypeScript
70 lines
3.0 KiB
TypeScript
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 <roughnessmap_fragment>' }
|
|
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])
|
|
})
|
|
})
|