@meimu/mutracer 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/assets/bvh.worker.js +1 -1
  2. package/dist/mutracer.umd.js +3525 -3484
  3. package/docs/materials.md +27 -7
  4. package/docs/threejs.md +13 -2
  5. package/docs/viewer.md +53 -0
  6. package/lib/oidn.d.ts +1 -1
  7. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  8. package/lib/renderer/MaterialTable.d.ts +1 -0
  9. package/lib/renderer/MaterialTable.js +2 -1
  10. package/lib/renderer/MaterialTable.js.map +1 -1
  11. package/lib/renderer/WGPUBloomPass.js +18 -18
  12. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  13. package/lib/renderer/WGPUJNLMDenoiser.js +62 -62
  14. package/lib/renderer/WGPURayTraceOutput.js +14 -12
  15. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  16. package/lib/renderer/WGPURayTracePass.js +2 -2
  17. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  18. package/lib/renderer/WGPURenderingPipeline.js +20 -18
  19. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  20. package/lib/renderer/WebGLJNLMDenoiser.js +61 -61
  21. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  22. package/lib/renderer/WebGLRayTracePass.js +3 -1
  23. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  24. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -9
  25. package/lib/renderer/glsl/chunks/envMap.glsl.js +45 -45
  26. package/lib/renderer/glsl/chunks/intersect.glsl.js +262 -262
  27. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +111 -111
  28. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +436 -436
  29. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  30. package/lib/renderer/glsl/chunks/random.glsl.js +3 -3
  31. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +32 -32
  32. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +54 -54
  33. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +71 -71
  34. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
  35. package/lib/renderer/glsl/chunks/sampling.glsl.js +64 -64
  36. package/lib/renderer/glsl/chunks/sobol.glsl.js +49 -49
  37. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  38. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +5 -5
  39. package/lib/renderer/glsl/depthQuery.frag.js +2 -2
  40. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
  41. package/lib/renderer/glsl/rayTrace.frag.js +128 -128
  42. package/lib/renderer/glsl/shadowCatcher.frag.js +12 -12
  43. package/lib/renderer/glsl/webglPipeline.frag.js +49 -49
  44. package/lib/renderer/lightsUtil.js +1 -1
  45. package/lib/renderer/lightsUtil.js.map +1 -1
  46. package/lib/renderer/materialComparison.generated.js +5 -0
  47. package/lib/renderer/materialComparison.generated.js.map +1 -1
  48. package/lib/renderer/materialLayout.js +2 -1
  49. package/lib/renderer/materialLayout.js.map +1 -1
  50. package/lib/renderer/prepareMeshBVH.d.ts +4 -2
  51. package/lib/renderer/prepareMeshBVH.js +44 -20
  52. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  53. package/lib/renderer/scratchSampling.js +6 -6
  54. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  55. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +29 -29
  56. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +376 -379
  57. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  58. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +5 -5
  59. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +51 -51
  60. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +453 -453
  61. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
  62. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +122 -117
  63. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
  64. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  65. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +13 -13
  66. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +94 -94
  67. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +119 -119
  68. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +5 -5
  69. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +62 -62
  70. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +3 -3
  71. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +2 -2
  72. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -1
  73. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +53 -53
  74. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +5 -5
  75. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -2
  76. package/lib/renderer/wgsl/compose.frag.wgsl.js +120 -92
  77. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
  78. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  79. package/lib/renderer/wgsl/depthQuery.wgsl.js +3 -3
  80. package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
  81. package/lib/renderer/wgsl/rayTrace.compute.js +220 -211
  82. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  83. package/lib/scene/OpenPBRMaterial.d.ts +4 -2
  84. package/lib/scene/OpenPBRMaterial.js +4 -2
  85. package/lib/scene/OpenPBRMaterial.js.map +1 -1
  86. package/lib/scene/openPbrSchema.d.ts +7 -2
  87. package/lib/scene/openPbrSchema.js +2 -1
  88. package/lib/scene/openPbrSchema.js.map +1 -1
  89. package/lib/util/fromTHREE.d.ts +1 -0
  90. package/lib/util/fromTHREE.js +24 -6
  91. package/lib/util/fromTHREE.js.map +1 -1
  92. package/lib/version.d.ts +1 -1
  93. package/lib/version.js +1 -1
  94. package/lib/version.js.map +1 -1
  95. package/package.json +5 -4
@@ -1 +1 @@
1
- {"version":3,"file":"materialLayout.js","sourceRoot":"","sources":["../../src/renderer/materialLayout.ts"],"names":[],"mappings":"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","sourcesContent":["import type { vec2 } from '../math.js';\nimport type { BufferData } from './MaterialTable.js';\n\n// Internal GPU contract. Each row occupies one vec4 (16 bytes). Reserved fields\n// retain their legacy sources/zero bytes; reuse requires an intentional migration.\ntype FieldType = 'f32' | 'vec2f' | 'vec3f';\ntype Source<T extends FieldType> = {\n [K in keyof BufferData]: BufferData[K] extends (T extends 'f32' ? number[] :\n T extends 'vec2f' ? vec2.Vec2Array[] : [number, number, number][]) ? K : never\n}[keyof BufferData];\nexport interface MaterialLayoutField {\n name: string;\n source: keyof BufferData | null;\n type: FieldType;\n reserved: boolean;\n}\nfunction field<T extends FieldType>(name: string, source: Source<T> | null,\n type: T, reserved = false): MaterialLayoutField {\n return { name, source, type, reserved };\n}\n\nexport const MATERIAL_LAYOUT = [\n { name: 'COLOR', fields: [\n field('color', 'color', 'vec3f'),\n field('matType', 'type', 'f32')\n ] },\n { name: 'ROUGHNESS_NORMAL', fields: [\n field('roughness', 'roughness', 'f32'),\n field('normalMapIndex', 'normalMapIndex', 'f32'),\n field('normalMapScale', 'normalScale', 'vec2f')\n ] },\n { name: 'METALLIC_MAPS', fields: [\n field('metallic', 'metallic', 'f32'),\n field('anisotropy', 'anisotropy', 'f32'),\n field('diffuseMapIndex', 'diffuseMapIndex', 'f32'),\n field('mrtMapIndex', 'metallicRoughnessMapIndex', 'f32')\n ] },\n { name: 'EMISSION', fields: [\n field('emission', 'emission', 'vec3f'),\n field('emissiveMapIndex', 'emissiveMapIndex', 'f32')\n ] },\n { name: 'IOR_TRANSMISSION', fields: [\n field('ior', 'ior', 'f32'),\n field('transmission', 'transmission', 'f32'),\n field('mediumType', 'mediumType', 'f32', true),\n field('thin', 'thin', 'f32')\n ] },\n { name: 'MISC', fields: [\n field('bevel', 'bevelSize', 'f32'),\n field('dispersion', 'dispersion', 'f32'),\n field('thinFilmThickness', 'thinFilmThickness', 'f32'),\n field('mapAlphaUsage', 'mapAlphaUsage', 'f32')\n ] },\n { name: 'LAYER_MAPS', fields: [\n field('coatWeightMapIndex', 'coatWeightMapIndex', 'f32'),\n field('coatRoughnessMapIndex', 'coatRoughnessMapIndex', 'f32'),\n field('coatNormalMapIndex', 'coatNormalMapIndex', 'f32'),\n field('fuzzColorMapIndex', 'fuzzColorMapIndex', 'f32')\n ] },\n { name: 'UV', fields: [\n field('uvProjection', 'uvProjection', 'f32'),\n field('displacementMapIndex', 'displacementMapIndex', 'f32'),\n field('uvScale', 'uvScale', 'vec2f')\n ] },\n { name: 'DISPLACEMENT', fields: [\n field('displacementStepSize', 'displacementStepSize', 'f32'),\n field('_padding', null, 'f32', true),\n field('displacementUvProjection', 'displacementUvProjection', 'f32'),\n field('displacementUvProjectionScale', 'displacementUvProjectionScale', 'f32')\n ] },\n { name: 'ALPHA_FILM', fields: [\n field('alpha', 'alpha', 'f32'),\n field('thinFilmMapIndex', 'thinFilmMapIndex', 'f32'),\n field('thinFilmIor', 'thinFilmIor', 'f32'),\n field('transmissionMapIndex', 'transmissionMapIndex', 'f32')\n ] },\n { name: 'BASE_CONTROLS', fields: [\n field('baseWeight', 'baseWeight', 'f32'),\n field('baseDiffuseRoughness', 'baseDiffuseRoughness', 'f32'),\n field('specularWeight', 'specularWeight', 'f32'),\n field('subsurfaceWeight', 'subsurfaceWeight', 'f32')\n ] },\n { name: 'SPECULAR_FUZZ', fields: [\n field('specularColor', 'specularColor', 'vec3f'),\n field('fuzzWeight', 'fuzzWeight', 'f32')\n ] },\n { name: 'TRANSMISSION_COLOR', fields: [\n field('transmissionColor', 'transmissionColor', 'vec3f'),\n field('transmissionDepth', 'transmissionDepth', 'f32')\n ] },\n { name: 'TRANSMISSION_SCATTER', fields: [\n field('transmissionScatter', 'transmissionScatter', 'vec3f'),\n field('transmissionScatterAnisotropy', 'transmissionScatterAnisotropy', 'f32')\n ] },\n { name: 'SUBSURFACE', fields: [\n field('subsurfaceColor', 'subsurfaceColor', 'vec3f'),\n field('subsurfaceRadius', 'subsurfaceRadius', 'f32')\n ] },\n { name: 'FUZZ', fields: [\n field('fuzzColor', 'fuzzColor', 'vec3f'),\n field('fuzzRoughness', 'fuzzRoughness', 'f32')\n ] },\n { name: 'COAT', fields: [\n field('coatColor', 'coatColor', 'vec3f'),\n field('coatWeight', 'coatWeight', 'f32')\n ] },\n { name: 'COAT_CONTROLS', fields: [\n field('coatRoughness', 'coatRoughness', 'f32'),\n field('coatAnisotropy', 'coatAnisotropy', 'f32'),\n field('coatIor', 'coatIor', 'f32'),\n field('coatDarkening', 'coatDarkening', 'f32')\n ] },\n { name: 'FILM_DISPERSION', fields: [\n field('thinFilmWeight', 'thinFilmWeight', 'f32'),\n field('dispersionAbbeNumber', 'dispersionAbbeNumber', 'f32'),\n field('subsurfaceScatterAnisotropy', 'subsurfaceScatterAnisotropy', 'f32'),\n field('fuzzRoughnessMapIndex', 'fuzzRoughnessMapIndex', 'f32')\n ] },\n { name: 'SUBSURFACE_RADIUS', fields: [\n field('subsurfaceRadiusScale', 'subsurfaceRadiusScale', 'vec3f'),\n field('specularWeightMapIndex', 'specularWeightMapIndex', 'f32')\n ] },\n { name: 'MEDIUM_EXTINCTION', fields: [\n field('mediumExtinction', 'mediumExtinction', 'vec3f'),\n field('mediumAnisotropy', 'mediumAnisotropy', 'f32')\n ] },\n { name: 'MEDIUM_SCATTERING', fields: [\n field('mediumScattering', 'mediumScattering', 'vec3f'),\n field('specularColorMapIndex', 'specularColorMapIndex', 'f32')\n ] },\n { name: 'STANDALONE_MAPS', fields: [\n field('roughnessMapIndex', 'roughnessMapIndex', 'f32'),\n field('metalnessMapIndex', 'metalnessMapIndex', 'f32'),\n field('alphaMapIndex', 'alphaMapIndex', 'f32'),\n field('alphaCutoff', 'alphaCutoff', 'f32')\n ] },\n { name: 'ALPHA', fields: [\n field('_padding1', null, 'f32', true),\n field('_padding2', null, 'f32', true),\n field('doubleSided', 'doubleSided', 'f32'),\n field('alphaMode', 'alphaMode', 'f32')\n ] },\n // Reserve the approved direction/normal inputs for C1 steps two and three.\n { name: 'DIRECTION_NORMAL', fields: [\n field('anisotropyMapIndex', 'anisotropyMapIndex', 'f32'),\n field('specularAnisotropyRotation', 'specularAnisotropyRotation', 'f32'),\n field('coatNormalScale', 'coatNormalScale', 'vec2f')\n ] },\n { name: 'FILM_TEXTURE', fields: [\n field('coatAnisotropyRotation', 'coatAnisotropyRotation', 'f32'),\n field('specularAnisotropyModel', 'specularAnisotropyModel', 'f32'),\n field('thinFilmThicknessMinimum', 'thinFilmThicknessMinimum', 'f32'),\n field('thinFilmMapChannel', 'thinFilmMapChannel', 'f32')\n ] },\n] as const;\n\nexport const MATERIAL_ROW_COUNT = MATERIAL_LAYOUT.length;\nexport const MATERIAL_FLOAT_COUNT = MATERIAL_ROW_COUNT * 4;\nconst components = { f32: 1, vec2f: 2, vec3f: 3 } as const;\nexport function materialLayoutFields() {\n return MATERIAL_LAYOUT.flatMap((row, rowIndex) => {\n let component = 0;\n return row.fields.map(field => {\n const offset = rowIndex * 16 + component * 4;\n component += components[field.type];\n return { ...field, row: rowIndex, component: offset % 16 / 4, offset };\n });\n });\n}\n\nexport function packMaterialBuffer(data: BufferData): Float32Array {\n const fields = materialLayoutFields().map(field => ({\n ...field,\n // Flatten exactly as the legacy interleave did (including missing indices).\n values: field.source === null ? data.type.map(() => 0) : data[field.source]?.flat() ?? []\n }));\n const packed = new Float32Array(data.type.length * MATERIAL_FLOAT_COUNT);\n for (let material = 0; material < data.type.length; material++) {\n for (const field of fields) {\n const width = components[field.type];\n for (let c = 0; c < width; c++) {\n packed[material * MATERIAL_FLOAT_COUNT + field.offset / 4 + c] =\n Number(field.values[material * width + c] ?? -1);\n }\n }\n }\n return packed;\n}\n\nexport function materialBufferWgsl(): string {\n let end = 0;\n const declarations = materialLayoutFields().map(field => {\n const alignment = field.type === 'vec3f' ? 16 : components[field.type] * 4;\n const aligned = Math.ceil(end / alignment) * alignment;\n if (aligned !== field.offset) throw new Error(`Misaligned material field: ${field.name}`);\n end = aligned + components[field.type] * 4;\n return ` ${field.name}: ${field.type},`;\n });\n if (Math.ceil(end / 16) * 16 !== MATERIAL_ROW_COUNT * 16) {\n throw new Error('Invalid material buffer size');\n }\n return `struct MaterialBuffer {\\n${declarations.join('\\n')}\\n};`;\n}\n\nexport function materialRowsGlsl(): string {\n return [`const int MAT_DATA_SIZE = ${MATERIAL_ROW_COUNT};`,\n ...MATERIAL_LAYOUT.map((row, index) => `const int MAT_ROW_${row.name} = ${index};`)\n ].join('\\n');\n}\n"]}
1
+ {"version":3,"file":"materialLayout.js","sourceRoot":"","sources":["../../src/renderer/materialLayout.ts"],"names":[],"mappings":"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","sourcesContent":["import type { vec2 } from '../math.js';\nimport type { BufferData } from './MaterialTable.js';\n\n// Internal GPU contract. Each row occupies one vec4 (16 bytes). Reserved fields\n// retain their legacy sources/zero bytes; reuse requires an intentional migration.\ntype FieldType = 'f32' | 'vec2f' | 'vec3f';\ntype Source<T extends FieldType> = {\n [K in keyof BufferData]: BufferData[K] extends (T extends 'f32' ? number[] :\n T extends 'vec2f' ? vec2.Vec2Array[] : [number, number, number][]) ? K : never\n}[keyof BufferData];\nexport interface MaterialLayoutField {\n name: string;\n source: keyof BufferData | null;\n type: FieldType;\n reserved: boolean;\n}\nfunction field<T extends FieldType>(name: string, source: Source<T> | null,\n type: T, reserved = false): MaterialLayoutField {\n return { name, source, type, reserved };\n}\n\nexport const MATERIAL_LAYOUT = [\n { name: 'COLOR', fields: [\n field('color', 'color', 'vec3f'),\n field('matType', 'type', 'f32')\n ] },\n { name: 'ROUGHNESS_NORMAL', fields: [\n field('roughness', 'roughness', 'f32'),\n field('normalMapIndex', 'normalMapIndex', 'f32'),\n field('normalMapScale', 'normalScale', 'vec2f')\n ] },\n { name: 'METALLIC_MAPS', fields: [\n field('metallic', 'metallic', 'f32'),\n field('anisotropy', 'anisotropy', 'f32'),\n field('diffuseMapIndex', 'diffuseMapIndex', 'f32'),\n field('mrtMapIndex', 'metallicRoughnessMapIndex', 'f32')\n ] },\n { name: 'EMISSION', fields: [\n field('emission', 'emission', 'vec3f'),\n field('emissiveMapIndex', 'emissiveMapIndex', 'f32')\n ] },\n { name: 'IOR_TRANSMISSION', fields: [\n field('ior', 'ior', 'f32'),\n field('transmission', 'transmission', 'f32'),\n field('mediumType', 'mediumType', 'f32', true),\n field('thin', 'thin', 'f32')\n ] },\n { name: 'MISC', fields: [\n field('bevel', 'bevelSize', 'f32'),\n field('dispersion', 'dispersion', 'f32'),\n field('thinFilmThickness', 'thinFilmThickness', 'f32'),\n field('mapAlphaUsage', 'mapAlphaUsage', 'f32')\n ] },\n { name: 'LAYER_MAPS', fields: [\n field('coatWeightMapIndex', 'coatWeightMapIndex', 'f32'),\n field('coatRoughnessMapIndex', 'coatRoughnessMapIndex', 'f32'),\n field('coatNormalMapIndex', 'coatNormalMapIndex', 'f32'),\n field('fuzzColorMapIndex', 'fuzzColorMapIndex', 'f32')\n ] },\n { name: 'UV', fields: [\n field('uvProjection', 'uvProjection', 'f32'),\n field('displacementMapIndex', 'displacementMapIndex', 'f32'),\n field('uvScale', 'uvScale', 'vec2f')\n ] },\n { name: 'DISPLACEMENT', fields: [\n field('displacementStepSize', 'displacementStepSize', 'f32'),\n // Reuses zero padding: default bias preserves historical bytes and stride.\n field('displacementBias', 'displacementBias', 'f32'),\n field('displacementUvProjection', 'displacementUvProjection', 'f32'),\n field('displacementUvProjectionScale', 'displacementUvProjectionScale', 'f32')\n ] },\n { name: 'ALPHA_FILM', fields: [\n field('alpha', 'alpha', 'f32'),\n field('thinFilmMapIndex', 'thinFilmMapIndex', 'f32'),\n field('thinFilmIor', 'thinFilmIor', 'f32'),\n field('transmissionMapIndex', 'transmissionMapIndex', 'f32')\n ] },\n { name: 'BASE_CONTROLS', fields: [\n field('baseWeight', 'baseWeight', 'f32'),\n field('baseDiffuseRoughness', 'baseDiffuseRoughness', 'f32'),\n field('specularWeight', 'specularWeight', 'f32'),\n field('subsurfaceWeight', 'subsurfaceWeight', 'f32')\n ] },\n { name: 'SPECULAR_FUZZ', fields: [\n field('specularColor', 'specularColor', 'vec3f'),\n field('fuzzWeight', 'fuzzWeight', 'f32')\n ] },\n { name: 'TRANSMISSION_COLOR', fields: [\n field('transmissionColor', 'transmissionColor', 'vec3f'),\n field('transmissionDepth', 'transmissionDepth', 'f32')\n ] },\n { name: 'TRANSMISSION_SCATTER', fields: [\n field('transmissionScatter', 'transmissionScatter', 'vec3f'),\n field('transmissionScatterAnisotropy', 'transmissionScatterAnisotropy', 'f32')\n ] },\n { name: 'SUBSURFACE', fields: [\n field('subsurfaceColor', 'subsurfaceColor', 'vec3f'),\n field('subsurfaceRadius', 'subsurfaceRadius', 'f32')\n ] },\n { name: 'FUZZ', fields: [\n field('fuzzColor', 'fuzzColor', 'vec3f'),\n field('fuzzRoughness', 'fuzzRoughness', 'f32')\n ] },\n { name: 'COAT', fields: [\n field('coatColor', 'coatColor', 'vec3f'),\n field('coatWeight', 'coatWeight', 'f32')\n ] },\n { name: 'COAT_CONTROLS', fields: [\n field('coatRoughness', 'coatRoughness', 'f32'),\n field('coatAnisotropy', 'coatAnisotropy', 'f32'),\n field('coatIor', 'coatIor', 'f32'),\n field('coatDarkening', 'coatDarkening', 'f32')\n ] },\n { name: 'FILM_DISPERSION', fields: [\n field('thinFilmWeight', 'thinFilmWeight', 'f32'),\n field('dispersionAbbeNumber', 'dispersionAbbeNumber', 'f32'),\n field('subsurfaceScatterAnisotropy', 'subsurfaceScatterAnisotropy', 'f32'),\n field('fuzzRoughnessMapIndex', 'fuzzRoughnessMapIndex', 'f32')\n ] },\n { name: 'SUBSURFACE_RADIUS', fields: [\n field('subsurfaceRadiusScale', 'subsurfaceRadiusScale', 'vec3f'),\n field('specularWeightMapIndex', 'specularWeightMapIndex', 'f32')\n ] },\n { name: 'MEDIUM_EXTINCTION', fields: [\n field('mediumExtinction', 'mediumExtinction', 'vec3f'),\n field('mediumAnisotropy', 'mediumAnisotropy', 'f32')\n ] },\n { name: 'MEDIUM_SCATTERING', fields: [\n field('mediumScattering', 'mediumScattering', 'vec3f'),\n field('specularColorMapIndex', 'specularColorMapIndex', 'f32')\n ] },\n { name: 'STANDALONE_MAPS', fields: [\n field('roughnessMapIndex', 'roughnessMapIndex', 'f32'),\n field('metalnessMapIndex', 'metalnessMapIndex', 'f32'),\n field('alphaMapIndex', 'alphaMapIndex', 'f32'),\n field('alphaCutoff', 'alphaCutoff', 'f32')\n ] },\n { name: 'ALPHA', fields: [\n field('_padding1', null, 'f32', true),\n field('_padding2', null, 'f32', true),\n field('doubleSided', 'doubleSided', 'f32'),\n field('alphaMode', 'alphaMode', 'f32')\n ] },\n // Reserve the approved direction/normal inputs for C1 steps two and three.\n { name: 'DIRECTION_NORMAL', fields: [\n field('anisotropyMapIndex', 'anisotropyMapIndex', 'f32'),\n field('specularAnisotropyRotation', 'specularAnisotropyRotation', 'f32'),\n field('coatNormalScale', 'coatNormalScale', 'vec2f')\n ] },\n { name: 'FILM_TEXTURE', fields: [\n field('coatAnisotropyRotation', 'coatAnisotropyRotation', 'f32'),\n field('specularAnisotropyModel', 'specularAnisotropyModel', 'f32'),\n field('thinFilmThicknessMinimum', 'thinFilmThicknessMinimum', 'f32'),\n field('thinFilmMapChannel', 'thinFilmMapChannel', 'f32')\n ] },\n] as const;\n\nexport const MATERIAL_ROW_COUNT = MATERIAL_LAYOUT.length;\nexport const MATERIAL_FLOAT_COUNT = MATERIAL_ROW_COUNT * 4;\nconst components = { f32: 1, vec2f: 2, vec3f: 3 } as const;\nexport function materialLayoutFields() {\n return MATERIAL_LAYOUT.flatMap((row, rowIndex) => {\n let component = 0;\n return row.fields.map(field => {\n const offset = rowIndex * 16 + component * 4;\n component += components[field.type];\n return { ...field, row: rowIndex, component: offset % 16 / 4, offset };\n });\n });\n}\n\nexport function packMaterialBuffer(data: BufferData): Float32Array {\n const fields = materialLayoutFields().map(field => ({\n ...field,\n // Flatten exactly as the legacy interleave did (including missing indices).\n values: field.source === null ? data.type.map(() => 0) : data[field.source]?.flat() ?? []\n }));\n const packed = new Float32Array(data.type.length * MATERIAL_FLOAT_COUNT);\n for (let material = 0; material < data.type.length; material++) {\n for (const field of fields) {\n const width = components[field.type];\n for (let c = 0; c < width; c++) {\n packed[material * MATERIAL_FLOAT_COUNT + field.offset / 4 + c] =\n Number(field.values[material * width + c] ?? -1);\n }\n }\n }\n return packed;\n}\n\nexport function materialBufferWgsl(): string {\n let end = 0;\n const declarations = materialLayoutFields().map(field => {\n const alignment = field.type === 'vec3f' ? 16 : components[field.type] * 4;\n const aligned = Math.ceil(end / alignment) * alignment;\n if (aligned !== field.offset) throw new Error(`Misaligned material field: ${field.name}`);\n end = aligned + components[field.type] * 4;\n return ` ${field.name}: ${field.type},`;\n });\n if (Math.ceil(end / 16) * 16 !== MATERIAL_ROW_COUNT * 16) {\n throw new Error('Invalid material buffer size');\n }\n return `struct MaterialBuffer {\\n${declarations.join('\\n')}\\n};`;\n}\n\nexport function materialRowsGlsl(): string {\n return [`const int MAT_DATA_SIZE = ${MATERIAL_ROW_COUNT};`,\n ...MATERIAL_LAYOUT.map((row, index) => `const int MAT_ROW_${row.name} = ${index};`)\n ].join('\\n');\n}\n"]}
@@ -38,7 +38,7 @@ export declare function getMeshDisplacementMap(mesh: Mesh): Texture | undefined;
38
38
  export declare function getMeshDisplacementScale(mesh: Mesh): number;
39
39
  export declare function getDisplacementTextureDataCacheKey(texture: Texture): string;
40
40
  export declare function getPreparedMeshGeometryCacheKey(mesh: Mesh): string | undefined;
41
- export declare function getCachedPreparedMeshGeometry(mesh: Mesh): Geometry | undefined;
41
+ export declare function getCachedPreparedMeshGeometry(mesh: Mesh): Geometry;
42
42
  export declare function cachePreparedMeshGeometry(mesh: Mesh, generated: Geometry): Geometry;
43
43
  /** Returns cached prepared geometry, or the source while asynchronous preparation is pending. */
44
44
  export declare function getPreparedMeshGeometry(mesh: Mesh): Geometry;
@@ -68,7 +68,9 @@ export declare function captureMeshBlasSnapshot(mesh: Mesh, target: Geometry): {
68
68
  };
69
69
  /** Check that a result still belongs to the captured mesh inputs. */
70
70
  export declare function meshBlasSnapshotIsCurrent(mesh: Mesh, target: Geometry, snapshot: ReturnType<typeof captureMeshBlasSnapshot>): boolean;
71
- export declare function updateMeshInstances(meshes: Mesh[]): {
71
+ export declare function updateMeshInstances(meshes: Mesh[], options?: {
72
+ displacement?: boolean;
73
+ }): {
72
74
  geometry: Geometry;
73
75
  geometries: Geometry[];
74
76
  geometryRegions: Map<Geometry, {
@@ -168,8 +168,7 @@ export function getMeshDisplacementScale(mesh) {
168
168
  const preparedGeometryCache = new WeakMap();
169
169
  let displacementTextureId = 1;
170
170
  const displacementTextureIds = new WeakMap();
171
- function getDisplacementTextureId(texture) {
172
- const identity = texture.source ?? texture;
171
+ function getDisplacementResourceId(identity) {
173
172
  let id = displacementTextureIds.get(identity);
174
173
  if (id == null) {
175
174
  id = displacementTextureId++;
@@ -180,7 +179,8 @@ function getDisplacementTextureId(texture) {
180
179
  export function getDisplacementTextureDataCacheKey(texture) {
181
180
  const image = texture.image;
182
181
  return [
183
- getDisplacementTextureId(texture),
182
+ getDisplacementResourceId(texture.source ?? texture),
183
+ getDisplacementResourceId(image),
184
184
  texture.version,
185
185
  image.width,
186
186
  image.height
@@ -194,11 +194,14 @@ export function getPreparedMeshGeometryCacheKey(mesh) {
194
194
  const texture = material?.displacementMap;
195
195
  if (!material)
196
196
  return undefined;
197
- // Projective bounds depend on the material projection and height texture.
198
- if (material.displacementUvProjection !== 'none' && texture && Math.abs(material.displacementScale) > 1e-6) {
199
- return ['projectiveProjection', source.version, getDisplacementTextureDataCacheKey(texture),
200
- +texture.flipY, texture.uvScale.join(','), texture.uvOffset.join(','),
201
- material.displacementScale, material.displacementUvProjectionScale, material.displacementUvProjection].join('|');
197
+ // UV and procedural displacement both need height-aware BLAS bounds and
198
+ // packed triangle ranges. Never reuse the source's undisplaced tree, or a
199
+ // different material's height field, when a texture/scale changes.
200
+ const scale = getMeshDisplacementScale(mesh);
201
+ if (texture && (scale !== 0 || material.displacementBias !== 0)) {
202
+ return ['displacement', source.version, getDisplacementTextureDataCacheKey(texture),
203
+ +texture.flipY, texture.uvScale.join(','), texture.uvOffset.join(','), texture.uvChannel,
204
+ scale, material.displacementBias, material.displacementUvProjectionScale, material.displacementUvProjection].join('|');
202
205
  }
203
206
  return undefined;
204
207
  }
@@ -207,8 +210,11 @@ export function getCachedPreparedMeshGeometry(mesh) {
207
210
  if (key == null)
208
211
  return mesh.geometry;
209
212
  const cached = preparedGeometryCache.get(mesh.geometry)?.get(key);
210
- if (!cached && key.startsWith('projectiveProjection|')) {
211
- return cachePreparedMeshGeometry(mesh, new Geometry(mesh.geometry));
213
+ if (!cached) {
214
+ const geometry = new Geometry(mesh.geometry);
215
+ geometry.dynamic = mesh.geometry.dynamic;
216
+ geometry.version = mesh.geometry.version;
217
+ return cachePreparedMeshGeometry(mesh, geometry);
212
218
  }
213
219
  return cached;
214
220
  }
@@ -574,8 +580,8 @@ export function ensureMeshGeometryAttributes(meshes) {
574
580
  generateVertexTangents(geometry);
575
581
  }
576
582
  }
577
- function getMeshBlasGeometry(mesh) {
578
- const geometry = getPreparedMeshGeometry(mesh);
583
+ function getMeshBlasGeometry(mesh, displacement = true) {
584
+ const geometry = displacement ? getPreparedMeshGeometry(mesh) : mesh.geometry;
579
585
  if (!geometry.normal)
580
586
  computeGeometryNormals(geometry);
581
587
  if (!geometry.tangent && geometry.uv)
@@ -587,9 +593,27 @@ export function getMeshBlasInput(mesh) {
587
593
  const geometry = getMeshBlasGeometry(mesh);
588
594
  const heightMap = getMeshDisplacementMap(mesh);
589
595
  const displacementScale = heightMap ? getMeshDisplacementScale(mesh) : 0;
590
- const trianglesDisplacement = Math.abs(displacementScale) > 1e-6
596
+ const trianglesDisplacement = displacementScale !== 0
591
597
  ? getTrianglesDisplacementRange(geometry, heightMap, getMeshDisplacementMaterial(mesh))
592
598
  : undefined;
599
+ // Build bounds around a normal-offset base while retaining original vertex
600
+ // attributes for texture coordinates and shading. This same input works for
601
+ // built-in, TinyBVH and Worker builds; the shader offsets its base identically.
602
+ const bias = heightMap ? getMeshDisplacementMaterial(mesh).displacementBias : 0;
603
+ if (bias !== 0) {
604
+ const positions = geometry.position.array.slice();
605
+ const normals = geometry.normal.array;
606
+ for (let vertex = 0; vertex < geometry.vertexCount; vertex++) {
607
+ const p = vertex * geometry.position.itemSize, n = vertex * geometry.normal.itemSize;
608
+ const length = Math.hypot(normals[n], normals[n + 1], normals[n + 2]);
609
+ if (length > 0) {
610
+ for (let axis = 0; axis < 3; axis++)
611
+ positions[p + axis] += normals[n + axis] / length * bias;
612
+ }
613
+ }
614
+ return { geometry: new Geometry({ ...geometry, position: new Attribute(positions, geometry.position.itemSize) }),
615
+ displacementScale, trianglesDisplacement };
616
+ }
593
617
  return { geometry, displacementScale, trianglesDisplacement };
594
618
  }
595
619
  /** Whether a static mesh still needs a BLAS before it can be rendered. */
@@ -620,18 +644,18 @@ export function meshBlasSnapshotIsCurrent(mesh, target, snapshot) {
620
644
  (!snapshot.displacementMap || getDisplacementTextureDataCacheKey(snapshot.displacementMap) ===
621
645
  snapshot.displacementTextureKey);
622
646
  }
623
- function prepareMeshGeometryBvh(mesh) {
624
- const geometry = getMeshBlasGeometry(mesh);
625
- const displacementScale = getMeshDisplacementMap(mesh) ? getMeshDisplacementScale(mesh) : 0;
647
+ function prepareMeshGeometryBvh(mesh, displacement = true) {
648
+ const geometry = getMeshBlasGeometry(mesh, displacement);
649
+ const displacementScale = displacement && getMeshDisplacementMap(mesh) ? getMeshDisplacementScale(mesh) : 0;
626
650
  if (geometry.dynamic && getGeometryBvh(geometry)?.builder !== 'builtin')
627
651
  setGeometryBvh(geometry, undefined);
628
652
  if (!getGeometryBvh(geometry)) {
629
- const { trianglesDisplacement } = getMeshBlasInput(mesh);
630
- setGeometryBvh(geometry, buildBLAS(geometry, displacementScale, trianglesDisplacement));
653
+ const input = displacement ? getMeshBlasInput(mesh) : { geometry, displacementScale, trianglesDisplacement: undefined };
654
+ setGeometryBvh(geometry, buildBLAS(input.geometry, input.displacementScale, input.trianglesDisplacement));
631
655
  }
632
656
  return { geometry, displacementScale };
633
657
  }
634
- export function updateMeshInstances(meshes) {
658
+ export function updateMeshInstances(meshes, options = {}) {
635
659
  const materialIndexMap = new Map();
636
660
  const geometryIndexMap = new Map();
637
661
  const geometries = [];
@@ -642,7 +666,7 @@ export function updateMeshInstances(meshes) {
642
666
  const instances = meshes
643
667
  .filter((mesh) => mesh.geometry.position?.array.length > 0)
644
668
  .map((mesh) => {
645
- let { geometry, displacementScale } = prepareMeshGeometryBvh(mesh);
669
+ let { geometry, displacementScale } = prepareMeshGeometryBvh(mesh, options.displacement !== false);
646
670
  const bvhBounds = getBvhBounds(geometry);
647
671
  const bounds = computeBounds(geometry, mesh.transform, bvhBounds);
648
672
  let geoIdx = geometryIndexMap.get(geometry);