@woosh/meep-engine 2.138.17 → 2.138.19
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.
- package/README.md +2 -2
- package/build/bundle-worker-image-decoder.js +1 -1
- package/editor/actions/concrete/ActionUpdateTexture.d.ts +12 -0
- package/editor/actions/concrete/ActionUpdateTexture.d.ts.map +1 -0
- package/editor/actions/concrete/ArrayCopyAction.d.ts +20 -0
- package/editor/actions/concrete/ArrayCopyAction.d.ts.map +1 -0
- package/editor/actions/concrete/ComponentRemoveAction.d.ts +11 -0
- package/editor/actions/concrete/ComponentRemoveAction.d.ts.map +1 -0
- package/editor/actions/concrete/ModifyPatchSampler2DAction.d.ts +47 -0
- package/editor/actions/concrete/ModifyPatchSampler2DAction.d.ts.map +1 -0
- package/editor/actions/concrete/ModifyPatchTextureArray2DAction.d.ts +38 -0
- package/editor/actions/concrete/ModifyPatchTextureArray2DAction.d.ts.map +1 -0
- package/editor/actions/concrete/PaintTerrainOverlayAction.d.ts +23 -0
- package/editor/actions/concrete/PaintTerrainOverlayAction.d.ts.map +1 -0
- package/editor/actions/concrete/PatchTerrainHeightAction.d.ts +19 -0
- package/editor/actions/concrete/PatchTerrainHeightAction.d.ts.map +1 -0
- package/editor/actions/concrete/SelectionRemoveAction.d.ts +10 -0
- package/editor/actions/concrete/SelectionRemoveAction.d.ts.map +1 -0
- package/editor/actions/concrete/WriteGridValueAction.d.ts +15 -0
- package/editor/actions/concrete/WriteGridValueAction.d.ts.map +1 -0
- package/editor/ecs/component/FieldDescriptor.d.ts +27 -0
- package/editor/ecs/component/FieldDescriptor.d.ts.map +1 -0
- package/editor/ecs/component/FieldValueAdapter.d.ts +7 -0
- package/editor/ecs/component/FieldValueAdapter.d.ts.map +1 -0
- package/editor/ecs/component/createFieldEditor.d.ts +9 -0
- package/editor/ecs/component/createFieldEditor.d.ts.map +1 -0
- package/editor/ecs/component/createObjectEditor.d.ts +14 -0
- package/editor/ecs/component/createObjectEditor.d.ts.map +1 -0
- package/editor/ecs/component/editors/geom/QuaternionEditor.d.ts.map +1 -1
- package/editor/ecs/component/findNearestRegisteredType.d.ts +8 -0
- package/editor/ecs/component/findNearestRegisteredType.d.ts.map +1 -0
- package/editor/process/ObstacleGridDisplayProcess.d.ts.map +1 -1
- package/editor/process/symbolic/makeGridPositionSymbolDisplay.d.ts.map +1 -1
- package/editor/tools/GridPaintTool.d.ts +17 -0
- package/editor/tools/GridPaintTool.d.ts.map +1 -0
- package/editor/tools/SelectionTool.d.ts +27 -0
- package/editor/tools/SelectionTool.d.ts.map +1 -0
- package/editor/tools/TopDownCameraControlTool.d.ts +13 -0
- package/editor/tools/TopDownCameraControlTool.d.ts.map +1 -0
- package/editor/view/ecs/ComponentControlFactory.d.ts.map +1 -0
- package/editor/view/ecs/ComponentControlView.d.ts.map +1 -1
- package/editor/view/ecs/EntityEditor.d.ts.map +1 -0
- package/editor/view/ecs/EntityList.d.ts.map +1 -0
- package/editor/view/ecs/HierarchicalEntityListView.d.ts.map +1 -0
- package/editor/view/node-graph/NodeGraphEditorView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeView.d.ts.map +1 -1
- package/editor/view/node-graph/PortView.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.d.ts +1 -1
- package/src/core/binary/BinaryBuffer.js +1 -1
- package/src/core/binary/BitSet.d.ts +1 -1
- package/src/core/binary/BitSet.js +1 -1
- package/src/core/cache/Cache.js +1 -1
- package/src/core/cache/LoadingCache.js +1 -1
- package/src/core/collection/list/List.js +1 -1
- package/src/core/collection/map/HashMap.js +1 -1
- package/src/core/collection/table/RowFirstTable.d.ts +1 -1
- package/src/core/collection/table/RowFirstTable.js +1 -1
- package/src/core/collection/table/RowFirstTableSpec.d.ts +1 -1
- package/src/core/collection/table/RowFirstTableSpec.js +1 -1
- package/src/core/color/oklab/compute_max_saturation.d.ts +1 -1
- package/src/core/color/oklab/compute_max_saturation.js +1 -1
- package/src/core/color/oklab/find_cusp.d.ts +1 -1
- package/src/core/color/oklab/find_cusp.js +1 -1
- package/src/core/color/oklab/find_gamut_intersection.d.ts +1 -1
- package/src/core/color/oklab/find_gamut_intersection.js +1 -1
- package/src/core/color/oklab/okhsv_to_linear_srgb.d.ts +1 -1
- package/src/core/color/oklab/okhsv_to_linear_srgb.js +1 -1
- package/src/core/color/oklab/oklab_to_linear_srgb.d.ts +1 -1
- package/src/core/color/oklab/oklab_to_linear_srgb.js +1 -1
- package/src/core/color/oklab/oklab_to_xyz.d.ts +1 -1
- package/src/core/color/oklab/oklab_to_xyz.js +1 -1
- package/src/core/color/oklab/xyz_to_oklab.d.ts +1 -1
- package/src/core/color/oklab/xyz_to_oklab.js +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.d.ts +1 -1
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +1 -1
- package/src/core/geom/3d/aabb/aabb3_nearest_point_on_surface.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/aabb3_nearest_point_on_surface.js +57 -65
- package/src/core/geom/3d/octahedra/octahedral_uv_wrap.d.ts +1 -1
- package/src/core/geom/3d/octahedra/octahedral_uv_wrap.js +1 -1
- package/src/core/geom/3d/quaternion/quat_decode_from_uint32.d.ts +1 -1
- package/src/core/geom/3d/quaternion/quat_decode_from_uint32.js +1 -1
- package/src/core/geom/3d/quaternion/quat_encode_to_uint32.d.ts +1 -1
- package/src/core/geom/3d/quaternion/quat_encode_to_uint32.js +1 -1
- package/src/core/geom/3d/shape/AbstractShape3D.d.ts +74 -3
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts +37 -0
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/CapsuleShape3D.js +210 -0
- package/src/core/geom/3d/shape/PointShape3D.d.ts +5 -0
- package/src/core/geom/3d/shape/PointShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/PointShape3D.js +52 -14
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts +75 -12
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/TransformedShape3D.js +12 -3
- package/src/core/geom/3d/shape/UnionShape3D.d.ts +47 -5
- package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts +12 -5
- package/src/core/geom/3d/shape/UnitCubeShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts +17 -5
- package/src/core/geom/3d/shape/UnitSphereShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/shape_to_type.js +4 -1
- package/src/core/geom/3d/shape/json/type_adapters.d.ts +17 -2
- package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/type_adapters.js +18 -2
- package/src/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.d.ts.map +1 -1
- package/src/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +51 -48
- package/src/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.d.ts +1 -1
- package/src/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.js +1 -1
- package/src/core/geom/ConicRay.d.ts +1 -1
- package/src/core/geom/ConicRay.js +1 -1
- package/src/core/geom/Quaternion.d.ts +2 -2
- package/src/core/geom/Quaternion.js +2 -2
- package/src/core/geom/Vector1.d.ts +1 -1
- package/src/core/geom/Vector1.js +1 -1
- package/src/core/geom/Vector2.d.ts +1 -1
- package/src/core/geom/Vector2.js +1 -1
- package/src/core/geom/Vector3.d.ts +1 -1
- package/src/core/geom/Vector3.js +1 -1
- package/src/core/geom/packing/miniball/Miniball.d.ts +1 -1
- package/src/core/geom/packing/miniball/Miniball.js +1 -1
- package/src/core/geom/vec3/serialization/v3_binary_equality_decode.d.ts +1 -1
- package/src/core/geom/vec3/serialization/v3_binary_equality_decode.js +1 -1
- package/src/core/geom/vec3/serialization/v3_binary_equality_encode.d.ts +1 -1
- package/src/core/geom/vec3/serialization/v3_binary_equality_encode.js +1 -1
- package/src/core/math/spline/spline3_hermite.d.ts +1 -1
- package/src/core/math/spline/spline3_hermite.js +1 -1
- package/src/core/math/spline/spline3_hermite_bounds.d.ts +1 -1
- package/src/core/math/spline/spline3_hermite_bounds.js +1 -1
- package/src/core/math/spline/spline3_hermite_bounds_t.d.ts +1 -1
- package/src/core/math/spline/spline3_hermite_bounds_t.js +1 -1
- package/src/core/math/spline/spline3_hermite_to_monomial.d.ts +1 -1
- package/src/core/math/spline/spline3_hermite_to_monomial.js +1 -1
- package/src/core/model/ObservedBoolean.d.ts +1 -1
- package/src/core/model/ObservedBoolean.js +1 -1
- package/src/core/model/ObservedString.d.ts +1 -1
- package/src/core/model/ObservedString.js +1 -1
- package/src/core/process/undo/Action.js +1 -1
- package/src/core/process/undo/ActionProcessor.js +1 -1
- package/src/engine/animation/curve/AnimationCurve.d.ts +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +1 -1
- package/src/engine/animation/curve/Keyframe.d.ts +1 -1
- package/src/engine/animation/curve/Keyframe.js +1 -1
- package/src/engine/animation/curve/animation_curve_compute_aabb.d.ts +1 -1
- package/src/engine/animation/curve/animation_curve_compute_aabb.js +1 -1
- package/src/engine/animation/curve/animation_curve_optimize.d.ts +1 -1
- package/src/engine/animation/curve/animation_curve_optimize.js +2 -2
- package/src/engine/asset/loaders/image/jpeg/JpegImage.js +1 -1
- package/src/engine/asset/loaders/image/png/PNGReader.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/png/PNGReader.js +27 -7
- package/src/engine/asset/loaders/image/png/crc32.d.ts +1 -1
- package/src/engine/asset/loaders/image/png/crc32.js +1 -1
- package/src/engine/control/first-person/DESIGN.md +616 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +229 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.js +176 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +251 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +205 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +151 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +799 -0
- package/src/engine/control/first-person/math/computeJumpFromApex.d.ts +23 -0
- package/src/engine/control/first-person/math/computeJumpFromApex.d.ts.map +1 -0
- package/src/engine/control/first-person/math/computeJumpFromApex.js +23 -0
- package/src/engine/control/first-person/math/criticallyDampedSpring.d.ts +23 -0
- package/src/engine/control/first-person/math/criticallyDampedSpring.d.ts.map +1 -0
- package/src/engine/control/first-person/math/criticallyDampedSpring.js +34 -0
- package/src/engine/control/first-person/math/dampedSpringStep.d.ts +23 -0
- package/src/engine/control/first-person/math/dampedSpringStep.d.ts.map +1 -0
- package/src/engine/control/first-person/math/dampedSpringStep.js +72 -0
- package/src/engine/control/first-person/math/stepTowards.d.ts +12 -0
- package/src/engine/control/first-person/math/stepTowards.d.ts.map +1 -0
- package/src/engine/control/first-person/math/stepTowards.js +20 -0
- package/src/engine/control/first-person/pose/FirstPersonPose.d.ts +69 -0
- package/src/engine/control/first-person/pose/FirstPersonPose.d.ts.map +1 -0
- package/src/engine/control/first-person/pose/FirstPersonPose.js +91 -0
- package/src/engine/control/first-person/prototype_first_person_controller.d.ts +2 -0
- package/src/engine/control/first-person/prototype_first_person_controller.d.ts.map +1 -0
- package/src/engine/control/first-person/prototype_first_person_controller.js +314 -0
- package/src/engine/ecs/Entity.js +1 -1
- package/src/engine/ecs/EntityComponentDataset.js +1 -1
- package/src/engine/ecs/EntityManager.d.ts +1 -1
- package/src/engine/ecs/EntityManager.js +1 -1
- package/src/engine/ecs/EntityObserver.js +1 -1
- package/src/engine/ecs/EntityReference.d.ts +1 -1
- package/src/engine/ecs/EntityReference.js +1 -1
- package/src/engine/ecs/System.js +1 -1
- package/src/engine/ecs/attachment/AttachmentSystem.d.ts +2 -2
- package/src/engine/ecs/attachment/AttachmentSystem.d.ts.map +1 -1
- package/src/engine/ecs/grid/HeightMap2AOMap.d.ts.map +1 -1
- package/src/engine/ecs/grid/HeightMap2AOMap.js +3 -2
- package/src/engine/ecs/guid/UUID.d.ts +1 -1
- package/src/engine/ecs/guid/UUID.js +1 -1
- package/src/engine/ecs/name/Name.d.ts +1 -1
- package/src/engine/ecs/name/Name.js +1 -1
- package/src/engine/ecs/parent/ParentEntity.js +1 -1
- package/src/engine/ecs/storage/BinaryBufferDeSerializer.d.ts +1 -1
- package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +1 -1
- package/src/engine/ecs/storage/BinaryBufferSerializer.d.ts +1 -1
- package/src/engine/ecs/storage/BinaryBufferSerializer.js +1 -1
- package/src/engine/ecs/storage/binary/BinaryClassSerializationAdapter.js +1 -1
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts +1 -1
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +1 -1
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.d.ts +1 -1
- package/src/engine/ecs/storage/binary/collection/BinaryCollectionDeSerializer.js +1 -1
- package/src/engine/ecs/transform/Transform.d.ts +1 -1
- package/src/engine/ecs/transform/Transform.js +1 -1
- package/src/engine/graphics/ecs/path/PathDisplaySystem.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/ImpostorBaker.d.ts.map +1 -1
- package/src/engine/graphics/impostors/octahedral/ImpostorBaker.js +10 -1
- package/src/engine/graphics/impostors/voxel/README.md +149 -0
- package/src/engine/graphics/impostors/voxel/VoxelImpostorBaker.d.ts +91 -0
- package/src/engine/graphics/impostors/voxel/VoxelImpostorBaker.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/VoxelImpostorBaker.js +376 -0
- package/src/engine/graphics/impostors/voxel/VoxelImpostorDescription.d.ts +128 -0
- package/src/engine/graphics/impostors/voxel/VoxelImpostorDescription.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/VoxelImpostorDescription.js +141 -0
- package/src/engine/graphics/impostors/voxel/bake/read_atlas_to_samples.d.ts +38 -0
- package/src/engine/graphics/impostors/voxel/bake/read_atlas_to_samples.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/bake/read_atlas_to_samples.js +338 -0
- package/src/engine/graphics/impostors/voxel/bake/voxelize_samples.d.ts +43 -0
- package/src/engine/graphics/impostors/voxel/bake/voxelize_samples.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/bake/voxelize_samples.js +192 -0
- package/src/engine/graphics/impostors/voxel/prototype_voxel_impostors.d.ts +2 -0
- package/src/engine/graphics/impostors/voxel/prototype_voxel_impostors.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/prototype_voxel_impostors.js +343 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderDepthV0.d.ts +13 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderDepthV0.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderDepthV0.js +99 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderLitV0.d.ts +19 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderLitV0.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderLitV0.js +231 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderNormalsV0.d.ts +5 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderNormalsV0.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderNormalsV0.js +70 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderV0.d.ts +13 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderV0.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderV0.js +127 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderViewportDepthV0.d.ts +5 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderViewportDepthV0.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/shader/VoxelImpostorShaderViewportDepthV0.js +68 -0
- package/src/engine/graphics/impostors/voxel/util/make_voxel_impostor_geometry.d.ts +27 -0
- package/src/engine/graphics/impostors/voxel/util/make_voxel_impostor_geometry.d.ts.map +1 -0
- package/src/engine/graphics/impostors/voxel/util/make_voxel_impostor_geometry.js +96 -0
- package/src/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.d.ts +113 -29
- package/src/engine/graphics/render/forward_plus/SPECIFICATION.md +1 -1
- package/src/engine/graphics/shaders/AmbientOcclusionShader.d.ts.map +1 -1
- package/src/engine/graphics/shaders/AmbientOcclusionShader.js +20 -5
- package/src/engine/graphics/texture/sampler/Sampler2D.d.ts +1 -1
- package/src/engine/graphics/texture/sampler/Sampler2D.js +1 -1
- package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_NaiveFlood.d.ts +1 -1
- package/src/engine/graphics/texture/sampler/distance/computeSignedDistanceField_NaiveFlood.js +1 -1
- package/src/engine/graphics/util/build_max_height_pyramid.d.ts +21 -14
- package/src/engine/graphics/util/build_max_height_pyramid.d.ts.map +1 -1
- package/src/engine/graphics/util/build_max_height_pyramid.js +107 -70
- package/src/engine/input/devices/InputDeviceSwitch.js +1 -1
- package/src/engine/input/devices/KeyboardDevice.js +1 -1
- package/src/engine/input/devices/PointerDevice.js +1 -1
- package/src/engine/intelligence/behavior/Behavior.js +1 -1
- package/src/engine/intelligence/behavior/SelectorBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/SelectorBehavior.js +1 -1
- package/src/engine/intelligence/behavior/behavior_to_dot.d.ts +1 -1
- package/src/engine/intelligence/behavior/behavior_to_dot.js +1 -1
- package/src/engine/intelligence/behavior/composite/CompositeBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/composite/CompositeBehavior.js +1 -1
- package/src/engine/intelligence/behavior/composite/ParallelBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/composite/ParallelBehavior.js +1 -1
- package/src/engine/intelligence/behavior/composite/SequenceBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/composite/SequenceBehavior.js +1 -1
- package/src/engine/intelligence/behavior/decorator/AbstractDecoratorBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/decorator/AbstractDecoratorBehavior.js +1 -1
- package/src/engine/intelligence/behavior/decorator/IgnoreFailureBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/decorator/IgnoreFailureBehavior.js +1 -1
- package/src/engine/intelligence/behavior/decorator/InvertStatusBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/decorator/InvertStatusBehavior.js +1 -1
- package/src/engine/intelligence/behavior/decorator/RepeatBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/decorator/RepeatBehavior.js +1 -1
- package/src/engine/intelligence/behavior/decorator/RepeatUntilSuccessBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/decorator/RepeatUntilSuccessBehavior.js +1 -1
- package/src/engine/intelligence/behavior/ecs/BehaviorComponent.d.ts +1 -1
- package/src/engine/intelligence/behavior/ecs/BehaviorComponent.js +1 -1
- package/src/engine/intelligence/behavior/ecs/BehaviorSystem.d.ts +1 -1
- package/src/engine/intelligence/behavior/ecs/BehaviorSystem.js +1 -1
- package/src/engine/intelligence/behavior/ecs/DieBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/ecs/DieBehavior.js +1 -1
- package/src/engine/intelligence/behavior/ecs/EntityBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/ecs/EntityBehavior.js +1 -1
- package/src/engine/intelligence/behavior/ecs/KillBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/ecs/KillBehavior.js +1 -1
- package/src/engine/intelligence/behavior/ecs/SendEventBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/ecs/SendEventBehavior.js +1 -1
- package/src/engine/intelligence/behavior/ecs/WaitForEventBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/ecs/WaitForEventBehavior.js +1 -1
- package/src/engine/intelligence/behavior/primitive/ActionBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/primitive/ActionBehavior.js +1 -1
- package/src/engine/intelligence/behavior/primitive/FailingBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/primitive/FailingBehavior.js +1 -1
- package/src/engine/intelligence/behavior/primitive/PromiseBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/primitive/PromiseBehavior.js +1 -1
- package/src/engine/intelligence/behavior/primitive/SucceedingBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/primitive/SucceedingBehavior.js +1 -1
- package/src/engine/intelligence/behavior/selector/WeightedElement.d.ts +1 -1
- package/src/engine/intelligence/behavior/selector/WeightedElement.js +1 -1
- package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.js +1 -1
- package/src/engine/intelligence/behavior/util/BranchBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/util/BranchBehavior.js +1 -1
- package/src/engine/intelligence/behavior/util/DelayBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/util/DelayBehavior.js +1 -1
- package/src/engine/intelligence/behavior/util/LogMessageBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/util/LogMessageBehavior.js +1 -1
- package/src/engine/intelligence/behavior/util/RandomDelayBehavior.d.ts +1 -1
- package/src/engine/intelligence/behavior/util/RandomDelayBehavior.js +1 -1
- package/src/engine/intelligence/blackboard/Blackboard.js +1 -1
- package/src/engine/intelligence/mcts/MonteCarlo.d.ts +1 -1
- package/src/engine/intelligence/mcts/MonteCarlo.js +1 -1
- package/src/engine/intelligence/mcts/MoveEdge.d.ts +1 -1
- package/src/engine/intelligence/mcts/MoveEdge.js +1 -1
- package/src/engine/intelligence/mcts/StateNode.d.ts +1 -1
- package/src/engine/intelligence/mcts/StateNode.js +1 -1
- package/src/engine/intelligence/resource/ActionSequence.d.ts +1 -1
- package/src/engine/intelligence/resource/ActionSequence.js +1 -1
- package/src/engine/intelligence/resource/Resource.d.ts +1 -1
- package/src/engine/intelligence/resource/Resource.js +1 -1
- package/src/engine/intelligence/resource/ResourceAllocation.d.ts +1 -1
- package/src/engine/intelligence/resource/ResourceAllocation.js +1 -1
- package/src/engine/intelligence/resource/ResourceAllocationBid.d.ts +1 -1
- package/src/engine/intelligence/resource/ResourceAllocationBid.js +1 -1
- package/src/engine/intelligence/resource/ResourceAllocationSolver.d.ts +1 -1
- package/src/engine/intelligence/resource/ResourceAllocationSolver.js +1 -1
- package/src/engine/intelligence/resource/StrategicResourceAllocator.d.ts +1 -1
- package/src/engine/intelligence/resource/StrategicResourceAllocator.js +1 -1
- package/src/engine/intelligence/resource/TacticalModule.d.ts +1 -1
- package/src/engine/intelligence/resource/TacticalModule.js +1 -1
- package/src/engine/network/NetworkSession.d.ts +1 -1
- package/src/engine/network/NetworkSession.js +1 -1
- package/src/engine/network/adapters/QuaternionInterpolationAdapter.d.ts +1 -1
- package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +1 -1
- package/src/engine/network/adapters/TransformInterpolationAdapter.d.ts +1 -1
- package/src/engine/network/adapters/TransformInterpolationAdapter.js +1 -1
- package/src/engine/network/adapters/TransformReplicationAdapter.d.ts +1 -1
- package/src/engine/network/adapters/TransformReplicationAdapter.js +1 -1
- package/src/engine/network/adapters/Vector3InterpolationAdapter.d.ts +1 -1
- package/src/engine/network/adapters/Vector3InterpolationAdapter.js +1 -1
- package/src/engine/network/core/quantize/quantize_float.d.ts +1 -1
- package/src/engine/network/core/quantize/quantize_float.js +1 -1
- package/src/engine/network/core/quantize/quantize_position.d.ts +1 -1
- package/src/engine/network/core/quantize/quantize_position.js +1 -1
- package/src/engine/network/core/sequence/ack_bitfield.d.ts +1 -1
- package/src/engine/network/core/sequence/ack_bitfield.js +1 -1
- package/src/engine/network/core/sequence/seq16.d.ts +1 -1
- package/src/engine/network/core/sequence/seq16.js +1 -1
- package/src/engine/network/core/sequence/seq32.d.ts +1 -1
- package/src/engine/network/core/sequence/seq32.js +1 -1
- package/src/engine/network/diagnostics/BandwidthMeter.d.ts +1 -1
- package/src/engine/network/diagnostics/BandwidthMeter.js +1 -1
- package/src/engine/network/diagnostics/ReplayLog.d.ts +1 -1
- package/src/engine/network/diagnostics/ReplayLog.js +1 -1
- package/src/engine/network/diagnostics/SyncTest.d.ts +1 -1
- package/src/engine/network/diagnostics/SyncTest.js +1 -1
- package/src/engine/network/ecs/NetworkSystem.d.ts +1 -1
- package/src/engine/network/ecs/NetworkSystem.js +1 -1
- package/src/engine/network/ecs/components/NetworkIdentity.d.ts +1 -1
- package/src/engine/network/ecs/components/NetworkIdentity.js +1 -1
- package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.d.ts +1 -1
- package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.js +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.d.ts +1 -1
- package/src/engine/network/orchestrator/NetworkPeer.js +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.d.ts +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeClient.js +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.d.ts +1 -1
- package/src/engine/network/orchestrator/ServerAuthoritativeServer.js +1 -1
- package/src/engine/network/replication/Replicator.d.ts +1 -1
- package/src/engine/network/replication/Replicator.js +1 -1
- package/src/engine/network/replication/ScopeFilter.d.ts +2 -2
- package/src/engine/network/replication/ScopeFilter.js +2 -2
- package/src/engine/network/sim/ActionLog.d.ts +1 -1
- package/src/engine/network/sim/ActionLog.js +1 -1
- package/src/engine/network/sim/BinaryInterpolationAdapter.d.ts +1 -1
- package/src/engine/network/sim/BinaryInterpolationAdapter.js +1 -1
- package/src/engine/network/sim/InterpolationLog.d.ts +1 -1
- package/src/engine/network/sim/InterpolationLog.js +1 -1
- package/src/engine/network/sim/ReplicatedComponentRegistry.d.ts +1 -1
- package/src/engine/network/sim/ReplicatedComponentRegistry.js +1 -1
- package/src/engine/network/sim/RewindEngine.d.ts +1 -1
- package/src/engine/network/sim/RewindEngine.js +1 -1
- package/src/engine/network/sim/SimAction.d.ts +1 -1
- package/src/engine/network/sim/SimAction.js +1 -1
- package/src/engine/network/sim/SimActionExecutor.d.ts +1 -1
- package/src/engine/network/sim/SimActionExecutor.js +1 -1
- package/src/engine/network/sim/SimActionRegistry.d.ts +1 -1
- package/src/engine/network/sim/SimActionRegistry.js +1 -1
- package/src/engine/network/sim/SmoothingState.js +1 -1
- package/src/engine/network/sim/Snapshotter.d.ts +1 -1
- package/src/engine/network/sim/Snapshotter.js +1 -1
- package/src/engine/network/sim/SpeculationLog.d.ts +1 -1
- package/src/engine/network/sim/SpeculationLog.js +1 -1
- package/src/engine/network/state/Baseline.d.ts +1 -1
- package/src/engine/network/state/Baseline.js +1 -1
- package/src/engine/network/state/ChangedEntitySet.d.ts +1 -1
- package/src/engine/network/state/ChangedEntitySet.js +1 -1
- package/src/engine/network/state/InputRing.d.ts +1 -1
- package/src/engine/network/state/InputRing.js +1 -1
- package/src/engine/network/state/MutationLedger.d.ts +1 -1
- package/src/engine/network/state/MutationLedger.js +1 -1
- package/src/engine/network/state/PriorityAccumulator.d.ts +1 -1
- package/src/engine/network/state/PriorityAccumulator.js +1 -1
- package/src/engine/network/state/ReplicationSlotTable.d.ts +1 -1
- package/src/engine/network/state/ReplicationSlotTable.js +1 -1
- package/src/engine/network/time/AdaptiveRenderDelay.d.ts +1 -1
- package/src/engine/network/time/AdaptiveRenderDelay.js +1 -1
- package/src/engine/network/time/JitterBuffer.d.ts +1 -1
- package/src/engine/network/time/JitterBuffer.js +1 -1
- package/src/engine/network/time/TimeDilation.d.ts +1 -1
- package/src/engine/network/time/TimeDilation.js +1 -1
- package/src/engine/network/time/TimeSync.d.ts +1 -1
- package/src/engine/network/time/TimeSync.js +1 -1
- package/src/engine/network/transport/Channel.d.ts.map +1 -1
- package/src/engine/network/transport/Channel.js +3 -6
- package/src/engine/network/transport/LoopbackTransport.d.ts +1 -1
- package/src/engine/network/transport/LoopbackTransport.js +1 -1
- package/src/engine/network/transport/ReliableCommandPipeline.d.ts +1 -1
- package/src/engine/network/transport/ReliableCommandPipeline.js +1 -1
- package/src/engine/network/transport/Transport.d.ts +1 -1
- package/src/engine/network/transport/Transport.js +1 -1
- package/src/engine/network/transport/adapters/NodeUDPTransport.d.ts +1 -1
- package/src/engine/network/transport/adapters/NodeUDPTransport.js +2 -2
- package/src/engine/network/transport/adapters/SimulatedTransport.d.ts +1 -1
- package/src/engine/network/transport/adapters/SimulatedTransport.js +1 -1
- package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.d.ts +1 -1
- package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +1 -1
- package/src/engine/network/transport/adapters/WebSocketTransport.d.ts +1 -1
- package/src/engine/network/transport/adapters/WebSocketTransport.js +1 -1
- package/src/engine/network/transport/adapters/WebTransportTransport.d.ts +1 -1
- package/src/engine/network/transport/adapters/WebTransportTransport.js +1 -1
- package/src/engine/network/transport/fragments/FragmentAssembler.d.ts +1 -1
- package/src/engine/network/transport/fragments/FragmentAssembler.js +1 -1
- package/src/engine/network/transport/fragments/FragmentRetention.d.ts +1 -1
- package/src/engine/network/transport/fragments/FragmentRetention.js +1 -1
- package/src/engine/network/transport/fragments/packet_size.d.ts +1 -1
- package/src/engine/network/transport/fragments/packet_size.js +1 -1
- package/src/engine/simulation/Ticker.d.ts +1 -1
- package/src/engine/simulation/Ticker.js +1 -1
- package/src/engine/sound/SoundEngine.js +1 -1
- package/src/engine/ui/DraggableAspect.d.ts +1 -1
- package/src/engine/ui/DraggableAspect.js +1 -1
- package/src/view/View.js +1 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Voxel Impostor system
|
|
2
|
+
|
|
3
|
+
Point-based ("voxel" / surfel) impostor inspired by the **Nanite Voxels**
|
|
4
|
+
representation Epic and CD Projekt RED showed in the Witcher 4 / Unreal
|
|
5
|
+
Engine 5 tech demo (Unreal Fest Stockholm 2025). At distance, dense
|
|
6
|
+
alpha-tested foliage cards stop scaling cleanly — the new technique
|
|
7
|
+
replaces them with a cloud of near-pixel-sized splats, each carrying a
|
|
8
|
+
full G-buffer slice, so the LOD never has to fall back to a flat card.
|
|
9
|
+
|
|
10
|
+
This implementation is much simpler than UE's production system (we
|
|
11
|
+
don't do streaming, meshlet hierarchy, or front-to-back depth binning),
|
|
12
|
+
but the data model and rendering approach are the same:
|
|
13
|
+
|
|
14
|
+
- Each "voxel" is a single splat with the same world-space size.
|
|
15
|
+
- Per-splat attributes: position, normal, albedo, ORM (occlusion,
|
|
16
|
+
roughness, metalness). **No alpha.**
|
|
17
|
+
- Render as a camera-facing instanced quad; the splat's normal drives
|
|
18
|
+
the lighting equations, not the quad's geometry.
|
|
19
|
+
|
|
20
|
+
Conceptually the system mirrors the octahedral impostor's two phases:
|
|
21
|
+
|
|
22
|
+
1. **Baking** (CPU-heavy, offline) — produce a point cloud from a
|
|
23
|
+
source mesh.
|
|
24
|
+
2. **Drawing** (GPU, every frame) — render the points with a small set
|
|
25
|
+
of shaders (unlit / lit / debug / depth caster).
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Baking
|
|
30
|
+
|
|
31
|
+
Implemented in [`VoxelImpostorBaker`](./VoxelImpostorBaker.js). Strategy:
|
|
32
|
+
|
|
33
|
+
1. Reuse the existing octahedral baker — it already renders the mesh
|
|
34
|
+
from many directions into a 3-channel MRT atlas (albedo+alpha,
|
|
35
|
+
normal+depth, ORM) with supersampling, anisotropic filtering, vertex
|
|
36
|
+
colours, and normal-map evaluation. We don't reimplement any of that.
|
|
37
|
+
|
|
38
|
+
2. Read the atlas back to CPU. Every opaque pixel becomes one
|
|
39
|
+
object-space sample:
|
|
40
|
+
- position is reconstructed from `(D_frame, frame_local_uv, depth)`
|
|
41
|
+
- normal is decoded from the atlas's view-space-encoded bytes through
|
|
42
|
+
the bake camera's basis
|
|
43
|
+
- albedo / ORM are taken directly from the atlas
|
|
44
|
+
|
|
45
|
+
3. Bin samples into a sparse axis-aligned voxel grid. Each cell
|
|
46
|
+
averages position, sums-and-normalises normal, averages albedo and
|
|
47
|
+
ORM. Empty cells are dropped — the surviving set IS the output point
|
|
48
|
+
cloud.
|
|
49
|
+
|
|
50
|
+
4. The grid resolution is chosen iteratively to stay under a
|
|
51
|
+
user-specified `point_budget`. Geometric shrink (halving) converges in
|
|
52
|
+
`O(log resolution)` even on pathological inputs.
|
|
53
|
+
|
|
54
|
+
### Why CPU-side voxelisation
|
|
55
|
+
|
|
56
|
+
The mesh is fixed, the bake is offline, and the whole voxelisation
|
|
57
|
+
runs in a few hundred ms on a million samples. Doing it on CPU keeps the
|
|
58
|
+
code path one-shot deterministic and lets the engine's CPU path tracer
|
|
59
|
+
be layered in later (for high-quality baked AO replacing the O channel,
|
|
60
|
+
or for indirect-lighting hints in albedo) without changing anything on
|
|
61
|
+
the runtime rendering side.
|
|
62
|
+
|
|
63
|
+
### Why multi-view atlas sampling and not direct triangle sampling
|
|
64
|
+
|
|
65
|
+
A triangle area-weighted sampler would be cleaner in principle, but
|
|
66
|
+
would also re-implement everything `BakeShaderStandard` does — texture
|
|
67
|
+
filtering, supersampling, normal-map TBN, vertex-colour multiply,
|
|
68
|
+
material colour multiply, anisotropic filtering. The multi-view path
|
|
69
|
+
gets all of that for free, AND naturally weighs surfaces by visibility:
|
|
70
|
+
a surface visible from many angles gets many votes per voxel, which is
|
|
71
|
+
exactly what the impostor's job depends on.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Drawing
|
|
76
|
+
|
|
77
|
+
One `InstancedBufferGeometry`, one instance per point, with the point
|
|
78
|
+
buffer wrapped directly as an `InstancedInterleavedBuffer` (zero copy
|
|
79
|
+
between baker and GPU). Each shader takes the per-instance attributes
|
|
80
|
+
and:
|
|
81
|
+
|
|
82
|
+
- expands a unit quad in view-space XY, scaled by
|
|
83
|
+
`VoxelImpostorDescription.point_radius`, to keep it camera-facing;
|
|
84
|
+
- uses the per-instance normal (not the quad's geometry normal) for
|
|
85
|
+
shading.
|
|
86
|
+
|
|
87
|
+
Shader set:
|
|
88
|
+
|
|
89
|
+
| File | Purpose |
|
|
90
|
+
|------|---------|
|
|
91
|
+
| `VoxelImpostorShaderV0` | Unlit. Writes baked albedo. Fast sanity check. |
|
|
92
|
+
| `VoxelImpostorShaderLitV0` | PBR-lit. Integrates three.js's standard pipeline; casts & receives shadows. |
|
|
93
|
+
| `VoxelImpostorShaderDepthV0` | Shadow-cast depth pass paired with the lit shader. |
|
|
94
|
+
| `VoxelImpostorShaderNormalsV0` | Debug — per-splat object-space normal as RGB. |
|
|
95
|
+
| `VoxelImpostorShaderViewportDepthV0` | Debug — viewport depth as grayscale. |
|
|
96
|
+
|
|
97
|
+
A `uDiscMask` uniform toggles between square and circular splats; the
|
|
98
|
+
prototype harness uses square for slot 0 (matches the Witcher 4 "voxel"
|
|
99
|
+
look) and disc for slot 1 (clearer view of the point distribution).
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Limitations
|
|
104
|
+
|
|
105
|
+
Same trade-offs as any pre-baked impostor:
|
|
106
|
+
|
|
107
|
+
- **No animation.** Position / normal / colour are frozen at bake time.
|
|
108
|
+
- **Static materials.** Roughness, metalness, AO, albedo are baked
|
|
109
|
+
averages, not procedural.
|
|
110
|
+
- **View-bias.** Surfaces never visible from the bake's sphere of
|
|
111
|
+
directions (eg the inside of a sealed cavity) don't get sampled.
|
|
112
|
+
Increase `frames` to capture more directions, but there's a hard limit:
|
|
113
|
+
if the original mesh's surface can't be hit by an external ray, the
|
|
114
|
+
impostor won't show it.
|
|
115
|
+
- **Splat overlap at close range.** Camera-facing quads with radius
|
|
116
|
+
≈ voxel size will overlap noticeably at the edge of the visible range
|
|
117
|
+
before the impostor would normally be used. Use as a distant LOD, not
|
|
118
|
+
as a close-up replacement.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Parameter recommendations
|
|
123
|
+
|
|
124
|
+
| Asset type | `point_budget` | `frames` | `resolution` |
|
|
125
|
+
|------------|---------------:|---------:|-------------:|
|
|
126
|
+
| Small prop (barrel, crate) | 2 048 | 12 | 512 |
|
|
127
|
+
| Building / house | 16 384 | 16 | 1024 |
|
|
128
|
+
| Vegetation (tree, large) | 32 768 | 24 | 2048 |
|
|
129
|
+
| Hero / detailed mesh | 65 536 | 32 | 2048 |
|
|
130
|
+
|
|
131
|
+
The budget is the **maximum** output; the baker may produce fewer
|
|
132
|
+
points if the bounding box is small or the surface area limited. Bump
|
|
133
|
+
`frames` if you see gaps in deep concavities; bump `resolution` if
|
|
134
|
+
per-voxel colour looks noisy (more samples per voxel → cleaner average).
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## References
|
|
139
|
+
|
|
140
|
+
- [2025] [Large Scale Animated Foliage in The Witcher 4 UE5 Tech Demo —
|
|
141
|
+
Unreal Fest Stockholm 2025](https://www.youtube.com/watch?v=EdNkm0ezP0o)
|
|
142
|
+
- [2025] [Nanite Foliage — Unreal Engine 5.7 docs](https://dev.epicgames.com/documentation/unreal-engine/nanite-foliage)
|
|
143
|
+
- [2025] [Get a glimpse of Nanite Foliage with voxel representation in
|
|
144
|
+
UE 5.7 — 80.lv](https://80.lv/articles/get-a-glimpse-of-nanite-foliage-with-voxel-representation-in-ue5-7)
|
|
145
|
+
- Surface-splatting fundamentals: Pfister et al, "Surfels: Surface
|
|
146
|
+
Elements as Rendering Primitives" (SIGGRAPH 2000)
|
|
147
|
+
- Octahedral encoding (used in atlas sampling): Cigolle et al, "A
|
|
148
|
+
Survey of Efficient Representations for Independent Unit Vectors"
|
|
149
|
+
(JCGT 2014)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Voxel ("Nanite voxel") impostor baker.
|
|
3
|
+
*
|
|
4
|
+
* Inspiration: the Witcher 4 / UE5.6+ "Nanite Foliage" tech demo, which
|
|
5
|
+
* swaps alpha-tested cards for a near-pixel-sized voxel representation
|
|
6
|
+
* at distance. Each "voxel" is a point with a world-space size, carrying
|
|
7
|
+
* a baked G-buffer (position, normal, albedo, ORM) — no alpha. Targeted
|
|
8
|
+
* at very low point counts (128–2048), where each voxel projects to
|
|
9
|
+
* around one screen pixel at the impostor's design viewing distance.
|
|
10
|
+
*
|
|
11
|
+
* Bake strategy: control the point count by **atlas resolution**, not
|
|
12
|
+
* by varying the voxel grid resolution at a fixed atlas. Reason: varying
|
|
13
|
+
* the voxel grid at fixed atlas biases each cell's centroid toward
|
|
14
|
+
* whichever views happened to land more atlas pixels in that cell — a
|
|
15
|
+
* systematic directional bias that grows with coarser grids. Re-baking
|
|
16
|
+
* the atlas at the right resolution avoids that, because each bake
|
|
17
|
+
* produces fresh, evenly-distributed samples in the target frequency
|
|
18
|
+
* range.
|
|
19
|
+
*
|
|
20
|
+
* Search algorithm:
|
|
21
|
+
*
|
|
22
|
+
* PHASE 1 — coarse halving. Start at `resolution`, halve atlas
|
|
23
|
+
* resolution each iteration until the point count fits budget.
|
|
24
|
+
* O(log) iterations, each a full GPU bake.
|
|
25
|
+
*
|
|
26
|
+
* PHASE 2 — binary-search refinement. Between the last over-budget
|
|
27
|
+
* resolution and the first under-budget one, binary-search in
|
|
28
|
+
* steps of `frames` (the smallest atlas-resolution granularity
|
|
29
|
+
* that keeps each per-frame tile integer-sized). Pick the
|
|
30
|
+
* largest atlas resolution that still fits — that gives the most
|
|
31
|
+
* points up to budget = best detail.
|
|
32
|
+
*
|
|
33
|
+
* Each iteration:
|
|
34
|
+
* 1. Re-bake atlas at candidate resolution via {@link ImpostorBaker}.
|
|
35
|
+
* 2. Read back samples on CPU.
|
|
36
|
+
* 3. Voxelise at grid_res = atlas_res / frames (matched 1:1 so each
|
|
37
|
+
* atlas pixel maps to roughly one voxel cell).
|
|
38
|
+
* 4. Count, compare to budget, advance search.
|
|
39
|
+
*
|
|
40
|
+
* Re-baking costs a GPU pass per iteration (~250 draws for 16² frames),
|
|
41
|
+
* so a full search is ~10 bakes ≈ a couple seconds on modern hardware.
|
|
42
|
+
* Acceptable for one-shot offline impostor prep where quality
|
|
43
|
+
* dominates.
|
|
44
|
+
*/
|
|
45
|
+
export class VoxelImpostorBaker {
|
|
46
|
+
/**
|
|
47
|
+
* @type {THREE.WebGLRenderer|null}
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
private _renderer;
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* @param {THREE.WebGLRenderer} v
|
|
54
|
+
*/
|
|
55
|
+
set renderer(arg: import("three").WebGLRenderer);
|
|
56
|
+
/**
|
|
57
|
+
* @param {object} params
|
|
58
|
+
* @param {{mesh:ShadedGeometry, transform:mat4}[]} params.objects
|
|
59
|
+
* @param {number} [params.point_budget] target maximum point count.
|
|
60
|
+
* The baker may produce fewer if the input is too small for the
|
|
61
|
+
* target, but never more.
|
|
62
|
+
* @param {ImpostorCaptureType} [params.capture_type]
|
|
63
|
+
* @param {number} [params.frames] atlas frame count per axis
|
|
64
|
+
* (total sampled views = frames²). Also the granularity of the
|
|
65
|
+
* atlas-resolution binary search: candidates must be multiples
|
|
66
|
+
* of `frames` so each per-frame tile stays integer-sized.
|
|
67
|
+
* Default 16.
|
|
68
|
+
* @param {number} [params.resolution] maximum atlas resolution.
|
|
69
|
+
* Upper bound of the search; the baker may pick a smaller value
|
|
70
|
+
* to fit the budget. Default 1024.
|
|
71
|
+
* @returns {VoxelImpostorDescription}
|
|
72
|
+
*/
|
|
73
|
+
bake({ objects, point_budget, capture_type, frames, resolution }: {
|
|
74
|
+
objects: {
|
|
75
|
+
mesh: ShadedGeometry;
|
|
76
|
+
transform: mat4;
|
|
77
|
+
}[];
|
|
78
|
+
point_budget?: number;
|
|
79
|
+
capture_type?: ImpostorCaptureType;
|
|
80
|
+
frames?: number;
|
|
81
|
+
resolution?: number;
|
|
82
|
+
}): VoxelImpostorDescription;
|
|
83
|
+
/**
|
|
84
|
+
* Pack the search result into a final VoxelImpostorDescription.
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
private _compose_result;
|
|
88
|
+
}
|
|
89
|
+
import { ImpostorCaptureType } from "../octahedral/ImpostorCaptureType.js";
|
|
90
|
+
import { VoxelImpostorDescription } from "./VoxelImpostorDescription.js";
|
|
91
|
+
//# sourceMappingURL=VoxelImpostorBaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoxelImpostorBaker.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/impostors/voxel/VoxelImpostorBaker.js"],"names":[],"mappings":"AAsDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH;IAEI;;;OAGG;IACH,kBAAiB;IAEjB;;;OAGG;IACH,iDAEC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH;QAf2D,OAAO,EAAvD;YAAC,IAAI,iBAAgB;YAAC,SAAS,OAAK;SAAC,EAAE;QACvB,YAAY,GAA5B,MAAM;QAGuB,YAAY,GAAzC,mBAAmB;QACH,MAAM,GAAtB,MAAM;QAKU,UAAU,GAA1B,MAAM;QAGJ,wBAAwB,CA4MpC;IAGD;;;OAGG;IACH,wBAkCC;CACJ;oCApXmC,sCAAsC;yCAGjC,+BAA+B"}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import { vec3 } from "gl-matrix";
|
|
2
|
+
import { assert } from "../../../../core/assert.js";
|
|
3
|
+
import { ImpostorBaker } from "../octahedral/ImpostorBaker.js";
|
|
4
|
+
import { ImpostorCaptureType } from "../octahedral/ImpostorCaptureType.js";
|
|
5
|
+
import { read_atlas_to_samples } from "./bake/read_atlas_to_samples.js";
|
|
6
|
+
import { voxelize_samples } from "./bake/voxelize_samples.js";
|
|
7
|
+
import { VoxelImpostorDescription } from "./VoxelImpostorDescription.js";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Compute an axis-aligned bounding box over every input mesh's positions
|
|
12
|
+
* after applying its world transform. We need this in addition to the
|
|
13
|
+
* bounding sphere (which the underlying ImpostorBaker already computes)
|
|
14
|
+
* because the voxel grid is axis-aligned, not spherical — a sphere bound
|
|
15
|
+
* would waste cells in the corners.
|
|
16
|
+
*
|
|
17
|
+
* @param {{mesh:ShadedGeometry, transform:mat4}[]} objects
|
|
18
|
+
* @returns {{min:number[], max:number[]}}
|
|
19
|
+
*/
|
|
20
|
+
function compute_bounding_box(objects) {
|
|
21
|
+
const min = [Infinity, Infinity, Infinity];
|
|
22
|
+
const max = [-Infinity, -Infinity, -Infinity];
|
|
23
|
+
|
|
24
|
+
for (let k = 0; k < objects.length; k++) {
|
|
25
|
+
const object = objects[k];
|
|
26
|
+
|
|
27
|
+
const positions = object.mesh.geometry.getAttribute('position');
|
|
28
|
+
const arr = positions.array;
|
|
29
|
+
const m = object.transform;
|
|
30
|
+
|
|
31
|
+
for (let i = 0; i < positions.count; i++) {
|
|
32
|
+
const ix = i * positions.itemSize;
|
|
33
|
+
const x = arr[ix];
|
|
34
|
+
const y = arr[ix + 1];
|
|
35
|
+
const z = arr[ix + 2];
|
|
36
|
+
|
|
37
|
+
// Manual mat4 * vec3 (point) — Float32Array-friendly.
|
|
38
|
+
const wx = m[0] * x + m[4] * y + m[8] * z + m[12];
|
|
39
|
+
const wy = m[1] * x + m[5] * y + m[9] * z + m[13];
|
|
40
|
+
const wz = m[2] * x + m[6] * y + m[10] * z + m[14];
|
|
41
|
+
|
|
42
|
+
if (wx < min[0]) min[0] = wx;
|
|
43
|
+
if (wy < min[1]) min[1] = wy;
|
|
44
|
+
if (wz < min[2]) min[2] = wz;
|
|
45
|
+
if (wx > max[0]) max[0] = wx;
|
|
46
|
+
if (wy > max[1]) max[1] = wy;
|
|
47
|
+
if (wz > max[2]) max[2] = wz;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { min, max };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Voxel ("Nanite voxel") impostor baker.
|
|
57
|
+
*
|
|
58
|
+
* Inspiration: the Witcher 4 / UE5.6+ "Nanite Foliage" tech demo, which
|
|
59
|
+
* swaps alpha-tested cards for a near-pixel-sized voxel representation
|
|
60
|
+
* at distance. Each "voxel" is a point with a world-space size, carrying
|
|
61
|
+
* a baked G-buffer (position, normal, albedo, ORM) — no alpha. Targeted
|
|
62
|
+
* at very low point counts (128–2048), where each voxel projects to
|
|
63
|
+
* around one screen pixel at the impostor's design viewing distance.
|
|
64
|
+
*
|
|
65
|
+
* Bake strategy: control the point count by **atlas resolution**, not
|
|
66
|
+
* by varying the voxel grid resolution at a fixed atlas. Reason: varying
|
|
67
|
+
* the voxel grid at fixed atlas biases each cell's centroid toward
|
|
68
|
+
* whichever views happened to land more atlas pixels in that cell — a
|
|
69
|
+
* systematic directional bias that grows with coarser grids. Re-baking
|
|
70
|
+
* the atlas at the right resolution avoids that, because each bake
|
|
71
|
+
* produces fresh, evenly-distributed samples in the target frequency
|
|
72
|
+
* range.
|
|
73
|
+
*
|
|
74
|
+
* Search algorithm:
|
|
75
|
+
*
|
|
76
|
+
* PHASE 1 — coarse halving. Start at `resolution`, halve atlas
|
|
77
|
+
* resolution each iteration until the point count fits budget.
|
|
78
|
+
* O(log) iterations, each a full GPU bake.
|
|
79
|
+
*
|
|
80
|
+
* PHASE 2 — binary-search refinement. Between the last over-budget
|
|
81
|
+
* resolution and the first under-budget one, binary-search in
|
|
82
|
+
* steps of `frames` (the smallest atlas-resolution granularity
|
|
83
|
+
* that keeps each per-frame tile integer-sized). Pick the
|
|
84
|
+
* largest atlas resolution that still fits — that gives the most
|
|
85
|
+
* points up to budget = best detail.
|
|
86
|
+
*
|
|
87
|
+
* Each iteration:
|
|
88
|
+
* 1. Re-bake atlas at candidate resolution via {@link ImpostorBaker}.
|
|
89
|
+
* 2. Read back samples on CPU.
|
|
90
|
+
* 3. Voxelise at grid_res = atlas_res / frames (matched 1:1 so each
|
|
91
|
+
* atlas pixel maps to roughly one voxel cell).
|
|
92
|
+
* 4. Count, compare to budget, advance search.
|
|
93
|
+
*
|
|
94
|
+
* Re-baking costs a GPU pass per iteration (~250 draws for 16² frames),
|
|
95
|
+
* so a full search is ~10 bakes ≈ a couple seconds on modern hardware.
|
|
96
|
+
* Acceptable for one-shot offline impostor prep where quality
|
|
97
|
+
* dominates.
|
|
98
|
+
*/
|
|
99
|
+
export class VoxelImpostorBaker {
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @type {THREE.WebGLRenderer|null}
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
_renderer = null;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* @param {THREE.WebGLRenderer} v
|
|
110
|
+
*/
|
|
111
|
+
set renderer(v) {
|
|
112
|
+
this._renderer = v;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param {object} params
|
|
117
|
+
* @param {{mesh:ShadedGeometry, transform:mat4}[]} params.objects
|
|
118
|
+
* @param {number} [params.point_budget] target maximum point count.
|
|
119
|
+
* The baker may produce fewer if the input is too small for the
|
|
120
|
+
* target, but never more.
|
|
121
|
+
* @param {ImpostorCaptureType} [params.capture_type]
|
|
122
|
+
* @param {number} [params.frames] atlas frame count per axis
|
|
123
|
+
* (total sampled views = frames²). Also the granularity of the
|
|
124
|
+
* atlas-resolution binary search: candidates must be multiples
|
|
125
|
+
* of `frames` so each per-frame tile stays integer-sized.
|
|
126
|
+
* Default 16.
|
|
127
|
+
* @param {number} [params.resolution] maximum atlas resolution.
|
|
128
|
+
* Upper bound of the search; the baker may pick a smaller value
|
|
129
|
+
* to fit the budget. Default 1024.
|
|
130
|
+
* @returns {VoxelImpostorDescription}
|
|
131
|
+
*/
|
|
132
|
+
bake({
|
|
133
|
+
objects,
|
|
134
|
+
point_budget = 16384,
|
|
135
|
+
capture_type = ImpostorCaptureType.FullSphere,
|
|
136
|
+
frames = 16,
|
|
137
|
+
resolution = 1024
|
|
138
|
+
}) {
|
|
139
|
+
|
|
140
|
+
console.time('voxel bake');
|
|
141
|
+
|
|
142
|
+
assert.defined(objects, 'objects');
|
|
143
|
+
assert.isNonNegativeInteger(point_budget, 'point_budget');
|
|
144
|
+
assert.greaterThanOrEqual(point_budget, 1, 'point_budget must be >= 1');
|
|
145
|
+
|
|
146
|
+
if (this._renderer === null) {
|
|
147
|
+
throw new Error('No renderer attached. Renderer is required for baking.');
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const renderer = this._renderer;
|
|
151
|
+
|
|
152
|
+
// Bounding box stays the same across re-bakes — compute once.
|
|
153
|
+
const aabb = compute_bounding_box(objects);
|
|
154
|
+
|
|
155
|
+
const octa_baker = new ImpostorBaker();
|
|
156
|
+
octa_baker.renderer = renderer;
|
|
157
|
+
|
|
158
|
+
// Minimum meaningful atlas resolution: 2 pixels per frame
|
|
159
|
+
// (1 pixel per frame is rasteriser-deadtime; 2 gives some
|
|
160
|
+
// content per view). Below this, the search is degenerate.
|
|
161
|
+
const min_resolution = Math.max(frames * 2, frames);
|
|
162
|
+
|
|
163
|
+
// Floor max resolution to a multiple of `frames` so the very
|
|
164
|
+
// first iteration is already a valid candidate.
|
|
165
|
+
const max_resolution = Math.floor(resolution / frames) * frames;
|
|
166
|
+
if (max_resolution < min_resolution) {
|
|
167
|
+
throw new Error(`resolution (=${resolution}) is too small for frames (=${frames}); need at least ${min_resolution}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* One bake-and-voxelise iteration at a given atlas resolution.
|
|
172
|
+
* Each call is a full GPU bake + CPU readback + voxelise; the
|
|
173
|
+
* atlas is disposed immediately after voxelising since the
|
|
174
|
+
* point cloud carries everything we need.
|
|
175
|
+
*
|
|
176
|
+
* @param {number} atlas_res
|
|
177
|
+
* @returns {{
|
|
178
|
+
* atlas_res: number,
|
|
179
|
+
* voxelised: {points: Float32Array, point_count: number, voxel_size: number},
|
|
180
|
+
* sample_count: number,
|
|
181
|
+
* sphere_radius: number,
|
|
182
|
+
* offset: number[],
|
|
183
|
+
* source_geometry_polygon_count: number,
|
|
184
|
+
* source_geometry_vertex_count: number,
|
|
185
|
+
* source_material_count: number,
|
|
186
|
+
* source_instance_count: number
|
|
187
|
+
* }}
|
|
188
|
+
*/
|
|
189
|
+
const bake_and_voxelise_at = (atlas_res) => {
|
|
190
|
+
console.time(`voxel bake / iter ${atlas_res}`);
|
|
191
|
+
|
|
192
|
+
const atlas = octa_baker.bake({
|
|
193
|
+
objects,
|
|
194
|
+
frames,
|
|
195
|
+
resolution: atlas_res,
|
|
196
|
+
type: capture_type
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const { samples, sample_count } = read_atlas_to_samples({
|
|
200
|
+
impostor: atlas,
|
|
201
|
+
renderer
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// grid_res = atlas pixels per frame, matched 1:1 so each
|
|
205
|
+
// atlas pixel maps to roughly one voxel cell. With many
|
|
206
|
+
// views (frames²), each cell still gets multiple samples
|
|
207
|
+
// for noise-averaging — just fewer than at higher atlas
|
|
208
|
+
// resolutions.
|
|
209
|
+
const grid_resolution = atlas_res / frames;
|
|
210
|
+
|
|
211
|
+
// Use the AABB plus a small margin (1% of bounding-sphere
|
|
212
|
+
// radius) so depth-quantisation jitter at the AABB
|
|
213
|
+
// boundary doesn't get rejected by the voxeliser.
|
|
214
|
+
const margin = atlas.sphere_radius * 0.01;
|
|
215
|
+
const bounds_min = [aabb.min[0] - margin, aabb.min[1] - margin, aabb.min[2] - margin];
|
|
216
|
+
const bounds_max = [aabb.max[0] + margin, aabb.max[1] + margin, aabb.max[2] + margin];
|
|
217
|
+
|
|
218
|
+
const voxelised = voxelize_samples({
|
|
219
|
+
samples,
|
|
220
|
+
sample_count,
|
|
221
|
+
bounds_min,
|
|
222
|
+
bounds_max,
|
|
223
|
+
grid_resolution
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
const sphere_radius = atlas.sphere_radius;
|
|
227
|
+
const offset = [atlas.offset[0], atlas.offset[1], atlas.offset[2]];
|
|
228
|
+
const source_geometry_polygon_count = atlas.source_geometry_polygon_count;
|
|
229
|
+
const source_geometry_vertex_count = atlas.source_geometry_vertex_count;
|
|
230
|
+
const source_material_count = atlas.source_material_count;
|
|
231
|
+
const source_instance_count = atlas.source_instance_count;
|
|
232
|
+
|
|
233
|
+
// Free GPU MRT — we have everything we need on CPU now.
|
|
234
|
+
atlas.rt.dispose();
|
|
235
|
+
|
|
236
|
+
console.timeEnd(`voxel bake / iter ${atlas_res}`);
|
|
237
|
+
console.log(` atlas ${atlas_res} (grid ${grid_resolution}): ${voxelised.point_count} points from ${sample_count} samples`);
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
atlas_res,
|
|
241
|
+
voxelised,
|
|
242
|
+
sample_count,
|
|
243
|
+
sphere_radius,
|
|
244
|
+
offset,
|
|
245
|
+
source_geometry_polygon_count,
|
|
246
|
+
source_geometry_vertex_count,
|
|
247
|
+
source_material_count,
|
|
248
|
+
source_instance_count
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
// --- PHASE 1: coarse halving ---
|
|
254
|
+
// Find the largest power-of-two-halving of max_resolution that
|
|
255
|
+
// fits the budget, plus the smallest one that doesn't. These
|
|
256
|
+
// bracket the optimal atlas resolution for phase 2.
|
|
257
|
+
let coarse_under = null;
|
|
258
|
+
let coarse_over_res = null;
|
|
259
|
+
|
|
260
|
+
let res = max_resolution;
|
|
261
|
+
|
|
262
|
+
while (true) {
|
|
263
|
+
const result = bake_and_voxelise_at(res);
|
|
264
|
+
|
|
265
|
+
if (result.voxelised.point_count <= point_budget) {
|
|
266
|
+
coarse_under = result;
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
coarse_over_res = res;
|
|
271
|
+
|
|
272
|
+
const next = Math.max(
|
|
273
|
+
min_resolution,
|
|
274
|
+
Math.floor((res / 2) / frames) * frames
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
if (next >= res) {
|
|
278
|
+
// Halving would not make progress — accept the floor.
|
|
279
|
+
return this._compose_result({
|
|
280
|
+
bake_result: bake_and_voxelise_at(min_resolution),
|
|
281
|
+
capture_type,
|
|
282
|
+
grid_resolution: min_resolution / frames,
|
|
283
|
+
source_atlas_frames: frames,
|
|
284
|
+
source_atlas_resolution: min_resolution
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
res = next;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
// --- PHASE 2: binary-search refinement ---
|
|
293
|
+
// Between (coarse_over_res, coarse_under.atlas_res], find the
|
|
294
|
+
// largest atlas resolution that still fits the budget. Step
|
|
295
|
+
// granularity is `frames` so per-frame tiles stay integer-sized.
|
|
296
|
+
let best = coarse_under;
|
|
297
|
+
|
|
298
|
+
if (coarse_over_res !== null) {
|
|
299
|
+
let lo = coarse_under.atlas_res; // confirmed fits budget
|
|
300
|
+
let hi = coarse_over_res; // confirmed overflows
|
|
301
|
+
|
|
302
|
+
while (hi - lo > frames) {
|
|
303
|
+
// Round mid down to a multiple of `frames`.
|
|
304
|
+
const mid_raw = Math.floor((lo + hi) / 2);
|
|
305
|
+
const mid = Math.floor(mid_raw / frames) * frames;
|
|
306
|
+
|
|
307
|
+
if (mid <= lo || mid >= hi) {
|
|
308
|
+
// No more integer-step candidates between lo and hi.
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const result = bake_and_voxelise_at(mid);
|
|
313
|
+
|
|
314
|
+
if (result.voxelised.point_count <= point_budget) {
|
|
315
|
+
lo = mid;
|
|
316
|
+
best = result;
|
|
317
|
+
} else {
|
|
318
|
+
hi = mid;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
console.timeEnd('voxel bake');
|
|
325
|
+
console.log(`VoxelImpostorBaker: settled on atlas ${best.atlas_res} → ${best.voxelised.point_count} points (budget ${point_budget})`);
|
|
326
|
+
|
|
327
|
+
return this._compose_result({
|
|
328
|
+
bake_result: best,
|
|
329
|
+
capture_type,
|
|
330
|
+
grid_resolution: best.atlas_res / frames,
|
|
331
|
+
source_atlas_frames: frames,
|
|
332
|
+
source_atlas_resolution: best.atlas_res
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Pack the search result into a final VoxelImpostorDescription.
|
|
339
|
+
* @private
|
|
340
|
+
*/
|
|
341
|
+
_compose_result({
|
|
342
|
+
bake_result,
|
|
343
|
+
capture_type,
|
|
344
|
+
grid_resolution,
|
|
345
|
+
source_atlas_frames,
|
|
346
|
+
source_atlas_resolution
|
|
347
|
+
}) {
|
|
348
|
+
const result = new VoxelImpostorDescription();
|
|
349
|
+
|
|
350
|
+
result.capture_type = capture_type;
|
|
351
|
+
result.sphere_radius = bake_result.sphere_radius;
|
|
352
|
+
vec3.copy(result.offset, bake_result.offset);
|
|
353
|
+
|
|
354
|
+
result.points = bake_result.voxelised.points;
|
|
355
|
+
result.point_count = bake_result.voxelised.point_count;
|
|
356
|
+
result.voxel_size = bake_result.voxelised.voxel_size;
|
|
357
|
+
result.grid_resolution = grid_resolution;
|
|
358
|
+
|
|
359
|
+
// Auto-tuned splat diameter — sqrt(2) covers the worst-case
|
|
360
|
+
// oblique projection of a voxel cell (a 45°-to-view face is
|
|
361
|
+
// sqrt(2)x wider in screen than its on-axis projection). Less-
|
|
362
|
+
// oblique angles get overlap, depth-test resolves the
|
|
363
|
+
// stacking. Render-time inward-shift (see shaders) keeps the
|
|
364
|
+
// silhouette tight regardless.
|
|
365
|
+
result.point_diameter = bake_result.voxelised.voxel_size * Math.SQRT2;
|
|
366
|
+
|
|
367
|
+
result.source_atlas_resolution = source_atlas_resolution;
|
|
368
|
+
result.source_atlas_frames = source_atlas_frames;
|
|
369
|
+
result.source_geometry_polygon_count = bake_result.source_geometry_polygon_count;
|
|
370
|
+
result.source_geometry_vertex_count = bake_result.source_geometry_vertex_count;
|
|
371
|
+
result.source_material_count = bake_result.source_material_count;
|
|
372
|
+
result.source_instance_count = bake_result.source_instance_count;
|
|
373
|
+
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
}
|