├── .gitignore ├── Doc ├── Img │ └── DataFlow.png └── DataFlow.md ├── Source ├── Base │ ├── Source │ │ ├── Util.cpp │ │ ├── pch.hpp │ │ ├── Timer.cpp │ │ └── ErrorHandling.cpp │ ├── Include │ │ └── Base │ │ │ ├── MiniWindows.hpp │ │ │ ├── Noncopyable.hpp │ │ │ ├── Timer.hpp │ │ │ ├── SmartPtrHelper.hpp │ │ │ ├── Util.hpp │ │ │ ├── Dll.hpp │ │ │ ├── ErrorHandling.hpp │ │ │ └── Uuid.hpp │ └── CMakeLists.txt ├── Lib │ ├── Source │ │ ├── SfM │ │ │ ├── MoGe │ │ │ │ └── __init__.py │ │ │ ├── ConvertDatasheet.py │ │ │ ├── PointCloudEstimator.py │ │ │ └── Shader │ │ │ │ └── UndistortCs.hlsl │ │ ├── Delighter │ │ │ ├── ModMidas │ │ │ │ ├── __init__.py │ │ │ │ ├── Effnet │ │ │ │ │ └── __init__.py │ │ │ │ └── Wsl.py │ │ │ ├── Shader │ │ │ │ └── MergeMaskCs.hlsl │ │ │ └── Delighter.hpp │ │ ├── MeshGen │ │ │ ├── Trellis │ │ │ │ ├── Models │ │ │ │ │ ├── StructuredLatentVae │ │ │ │ │ │ └── __init__.py │ │ │ │ │ └── __init__.py │ │ │ │ ├── Pipelines │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── Samplers │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── ClassifierFreeGuidanceMixin.py │ │ │ │ │ │ └── GuidanceIntervalMixin.py │ │ │ │ └── Modules │ │ │ │ │ ├── Sparse │ │ │ │ │ ├── Conv │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Transformer │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Attention │ │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Nonlinearity.py │ │ │ │ │ ├── Linear.py │ │ │ │ │ ├── Norm.py │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Attention │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Transformer │ │ │ │ │ └── __init__.py │ │ │ │ │ ├── Norm.py │ │ │ │ │ └── Spatial.py │ │ │ ├── Shader │ │ │ │ ├── InvisibleFacesRemover │ │ │ │ │ ├── FaceIdPs.hlsl │ │ │ │ │ ├── FaceIdVs.hlsl │ │ │ │ │ ├── AccumFacesCs.hlsl │ │ │ │ │ ├── MarkFacesCs.hlsl │ │ │ │ │ └── FilterFacesCs.hlsl │ │ │ │ ├── RotatePs.hlsl │ │ │ │ ├── ScatterIndexCs.hlsl │ │ │ │ ├── ExtractMaskCs.hlsl │ │ │ │ ├── RotateVs.hlsl │ │ │ │ ├── ResizeCs.hlsl │ │ │ │ ├── ApplyVertexColorCs.hlsl │ │ │ │ ├── MergeTextureCs.hlsl │ │ │ │ ├── MarchingCubes │ │ │ │ │ ├── CalcCubeIndicesCs.hlsl │ │ │ │ │ ├── MarchingCubesUtil.hlslh │ │ │ │ │ └── ProcessNonEmptyCubesCs.hlsl │ │ │ │ ├── DilateCs.hlsl │ │ │ │ └── Dilate3DCs.hlsl │ │ │ ├── MarchingCubes.hpp │ │ │ ├── InvisibleFacesRemover.hpp │ │ │ ├── MeshGenerator.hpp │ │ │ └── DiffOptimizer.hpp │ │ ├── Util │ │ │ ├── Shader │ │ │ │ ├── Utils.hlslh │ │ │ │ ├── Lanczos.hlslh │ │ │ │ └── Nn.hlslh │ │ │ ├── FormatConversion.hpp │ │ │ ├── PerfProfiler.hpp │ │ │ ├── BoundingBox.hpp │ │ │ └── FormatConversion.cpp │ │ ├── pch.hpp │ │ ├── TextureRecon │ │ │ ├── Shader │ │ │ │ ├── FlattenPs.hlsl │ │ │ │ ├── GenShadowMapVs.hlsl │ │ │ │ ├── FlattenVs.hlsl │ │ │ │ ├── ResolveTextureCs.hlsl │ │ │ │ └── ProjectTextureCs.hlsl │ │ │ └── TextureReconstruction.hpp │ │ ├── MeshSimp │ │ │ └── MeshSimplification.hpp │ │ ├── MaskGen │ │ │ ├── Shader │ │ │ │ ├── MergeMaskCs.hlsl │ │ │ │ ├── DownsampleCs.hlsl │ │ │ │ ├── NormalizeImageCs.hlsl │ │ │ │ ├── UpsampleCs.hlsl │ │ │ │ ├── StatImageCs.hlsl │ │ │ │ ├── StatPredCs.hlsl │ │ │ │ ├── GaussianBlurCs.hlsl │ │ │ │ └── ErosionDilationCs.hlsl │ │ │ ├── MaskGenerator.hpp │ │ │ └── MaskGenerator.py │ │ ├── AIHoloImagerInternal.hpp │ │ ├── ElementFormat.cpp │ │ └── Python │ │ │ └── PythonSystem.py │ └── Include │ │ └── AIHoloImager │ │ ├── ElementFormat.hpp │ │ ├── AIHoloImager.hpp │ │ └── Texture.hpp ├── TensorConverter │ ├── Source │ │ └── pch.hpp │ └── CMakeLists.txt ├── GpuDiffRender │ └── Source │ │ ├── pch.hpp │ │ ├── Shader │ │ ├── TextureBwdMipCs.hlsl │ │ ├── TextureFwdMipCs.hlsl │ │ ├── RasterizeBwdDerivateBcCs.hlsl │ │ ├── RasterizeFwdDerivateBcGs.hlsl │ │ ├── RasterizeFwdDerivateBcPs.hlsl │ │ ├── InterpolateBwdDerivateAttribsCs.hlsl │ │ ├── InterpolateFwdDerivateAttribsCs.hlsl │ │ ├── RasterizeFwdVs.hlsl │ │ ├── TextureCopyCs.hlsl │ │ ├── AntiAliasIndirectCs.hlsl │ │ ├── RasterizeFwdGs.hlsl │ │ ├── TextureFwdCs.hlsl │ │ ├── AccumGradMipsCs.hlsl │ │ ├── AntiAliasConstructOppoVertHashCs.hlsl │ │ ├── AntiAliasConstructOppoVertCs.hlsl │ │ └── InterpolateFwdCs.hlsl │ │ └── Torch │ │ └── PyTorchBindings.cpp ├── SubMConv │ ├── Source │ │ ├── pch.hpp │ │ └── Torch │ │ │ ├── Shader │ │ │ ├── Common.hlslh │ │ │ ├── BuildCoordHashCs.hlsl │ │ │ └── FindAvailableNeighborsCs.hlsl │ │ │ └── PyTorchBindings.cpp │ └── CMakeLists.txt ├── GpuSystem │ ├── Source │ │ ├── pch.hpp │ │ ├── GpuResource.cpp │ │ ├── Shader │ │ │ ├── Platform.hlslh │ │ │ └── GenMipmapCs.hlsl │ │ ├── Internal │ │ │ ├── D3D12 │ │ │ │ ├── D3D12Util.cpp │ │ │ │ ├── D3D12ImpDefine.hpp │ │ │ │ ├── D3D12Conversion.hpp │ │ │ │ ├── D3D12CommandPool.hpp │ │ │ │ ├── D3D12VertexLayout.hpp │ │ │ │ ├── D3D12DescriptorHeap.hpp │ │ │ │ ├── D3D12Sampler.hpp │ │ │ │ └── D3D12Resource.hpp │ │ │ ├── GpuBufferInternal.cpp │ │ │ ├── GpuSystemInternal.cpp │ │ │ ├── GpuTextureInternal.cpp │ │ │ ├── GpuResourceInternal.cpp │ │ │ ├── GpuSystemInternalFactory.hpp │ │ │ ├── GpuCommandListInternal.cpp │ │ │ ├── GpuCommandPoolInternal.cpp │ │ │ ├── GpuCommandPoolInternal.hpp │ │ │ ├── GpuVertexLayoutInternal.cpp │ │ │ ├── GpuVertexLayoutInternal.hpp │ │ │ ├── Vulkan │ │ │ │ ├── VulkanUtil.cpp │ │ │ │ ├── VulkanErrorhandling.cpp │ │ │ │ ├── VulkanImpDefine.hpp │ │ │ │ ├── VulkanConversion.hpp │ │ │ │ ├── VulkanCommandPool.hpp │ │ │ │ ├── VulkanResource.hpp │ │ │ │ ├── VulkanVertexLayout.hpp │ │ │ │ ├── VulkanDescriptorAllocator.hpp │ │ │ │ ├── VulkanSampler.hpp │ │ │ │ └── VulkanErrorhandling.hpp │ │ │ ├── GpuSamplerInternal.cpp │ │ │ ├── GpuShaderInternal.cpp │ │ │ ├── GpuBufferInternal.hpp │ │ │ ├── GpuSamplerInternal.hpp │ │ │ ├── GpuSystemInternalFactory.cpp │ │ │ ├── GpuTextureInternal.hpp │ │ │ ├── GpuShaderInternal.hpp │ │ │ ├── GpuResourceInternal.hpp │ │ │ └── GpuResourceViewsInternal.cpp │ │ ├── GpuCommandPool.cpp │ │ ├── GpuConstantBuffer.cpp │ │ ├── InternalImp.hpp │ │ └── GpuVertexLayout.cpp │ └── Include │ │ └── Gpu │ │ ├── InternalDefine.hpp │ │ ├── Vulkan │ │ └── VulkanTraits.hpp │ │ ├── GpuCommandPool.hpp │ │ ├── D3D12 │ │ └── D3D12Traits.hpp │ │ ├── GpuMipmapper.hpp │ │ ├── GpuVertexLayout.hpp │ │ └── GpuFormat.hpp └── App │ └── CMakeLists.txt ├── External ├── PythonVenv │ ├── Setup.bat │ └── requirements.txt ├── U-2-Net │ ├── DownloadGd.bat │ └── CMakeLists.txt ├── stb │ └── CMakeLists.txt ├── glm │ └── CMakeLists.txt ├── DirectX-Headers │ └── CMakeLists.txt ├── .gitignore ├── cxxopts │ └── CMakeLists.txt ├── xatlas │ └── CMakeLists.txt ├── Vulkan-Headers │ └── CMakeLists.txt ├── volk │ └── CMakeLists.txt ├── SPIRV-Reflect │ └── CMakeLists.txt ├── zlib │ └── CMakeLists.txt ├── DirectXShaderCompiler │ └── CMakeLists.txt ├── Intrinsic │ └── CMakeLists.txt ├── MoGe │ └── CMakeLists.txt ├── assimp │ └── CMakeLists.txt └── TRELLIS │ └── CMakeLists.txt ├── LICENSE ├── .clang-format ├── CMake └── Modules │ └── Platform.cmake ├── azure-pipelines.yml ├── CMakeLists.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Build/ 2 | *.pyc 3 | __pycache__ 4 | -------------------------------------------------------------------------------- /Doc/Img/DataFlow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongminmin/AIHoloImager/HEAD/Doc/Img/DataFlow.png -------------------------------------------------------------------------------- /Source/Base/Source/Util.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gongminmin/AIHoloImager/HEAD/Source/Base/Source/Util.cpp -------------------------------------------------------------------------------- /Source/Lib/Source/SfM/MoGe/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | from .MoGeModel import MoGeModel 5 | -------------------------------------------------------------------------------- /Source/TensorConverter/Source/pch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /Source/Base/Source/pch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/MiniWindows.hpp" 7 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/pch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Gpu/GpuSystem.hpp" 7 | -------------------------------------------------------------------------------- /Source/SubMConv/Source/pch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | -------------------------------------------------------------------------------- /Source/Lib/Source/Delighter/ModMidas/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Simplified from https://github.com/CCareaga/MiDaS 5 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/TextureBwdMipCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #define ENABLE_MIP 1 5 | #include "TextureBwdCs.hlsl" 6 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/TextureFwdMipCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #define ENABLE_MIP 1 5 | #include "TextureFwdCs.hlsl" 6 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Models/StructuredLatentVae/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | from .DecoderVolume import SLatMeshDecoder 5 | -------------------------------------------------------------------------------- /Source/Lib/Source/Delighter/ModMidas/Effnet/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Simplified from https://github.com/rwightman/gen-efficientnet-pytorch/ 5 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/RasterizeBwdDerivateBcCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #define ENABLE_DERIVATIVE_BC 1 5 | #include "RasterizeBwdCs.hlsl" 6 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/RasterizeFwdDerivateBcGs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #define ENABLE_DERIVATIVE_BC 1 5 | #include "RasterizeFwdGs.hlsl" 6 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/RasterizeFwdDerivateBcPs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #define ENABLE_DERIVATIVE_BC 1 5 | #include "RasterizeFwdPs.hlsl" 6 | -------------------------------------------------------------------------------- /External/PythonVenv/Setup.bat: -------------------------------------------------------------------------------- 1 | %1 -m venv PythonVenv --without-pip 2 | call PythonVenv\Scripts\activate.bat 3 | python -m ensurepip --upgrade 4 | python -m pip install -r requirements.txt 5 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/InterpolateBwdDerivateAttribsCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #define ENABLE_DERIVATIVE_BC 1 5 | #include "InterpolateBwdCs.hlsl" 6 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/InterpolateFwdDerivateAttribsCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #define ENABLE_DERIVATIVE_BC 1 5 | #include "InterpolateFwdCs.hlsl" 6 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Pipelines/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | from . import Samplers 5 | from .TrellisImageTo3D import TrellisImageTo3DPipeline 6 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/pch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include "Base/MiniWindows.hpp" 10 | -------------------------------------------------------------------------------- /Source/App/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(AIHoloImager 2 | Main.cpp 3 | ) 4 | 5 | target_link_libraries(AIHoloImager 6 | PRIVATE 7 | cxxopts 8 | AIHoloImagerLib 9 | ) 10 | -------------------------------------------------------------------------------- /Source/Lib/Source/Util/Shader/Utils.hlslh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | uint32_t DivUp(uint32_t a, uint32_t b) 7 | { 8 | return (a + b - 1) / b; 9 | } 10 | -------------------------------------------------------------------------------- /External/U-2-Net/DownloadGd.bat: -------------------------------------------------------------------------------- 1 | call ..\PythonVenv\PythonVenv\Scripts\activate.bat 2 | mkdir U2NetModels 3 | gdown 1ao1ovG1Qtx4b7EoskHXmi2E9rp5CHLcZ -O U2NetModels\u2net.pth 4 | gdown 1rbSTGKAE-MTxBYHd-51l2hMOQPT_7EPy -O U2NetModels\u2netp.pth 5 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/InvisibleFacesRemover/FaceIdPs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | uint32_t main(uint32_t face_id : SV_PrimitiveID) : SV_Target0 5 | { 6 | return face_id + 1; // 0 is reserved as empty 7 | } 8 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Sparse/Conv/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/sparse/conv/__init__.py 5 | 6 | from .ConvSpconv import * 7 | -------------------------------------------------------------------------------- /Source/Lib/Source/pch.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "Base/MiniWindows.hpp" 11 | 12 | #include 13 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/GpuResource.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Gpu/GpuResource.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuResource::~GpuResource() noexcept = default; 9 | } // namespace AIHoloImager 10 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Attention/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/attention/__init__.py 5 | 6 | from .FullAttn import * 7 | from .Modules import * 8 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Transformer/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/transformer/__init__.py 5 | 6 | from .Blocks import * 7 | from .Modulated import * 8 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Sparse/Transformer/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/sparse/transformer/__init__.py 5 | 6 | from .Blocks import * 7 | from .Modulated import * 8 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/RasterizeFwdVs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Platform.hlslh" 5 | 6 | void main(float4 pos : POSITION, 7 | out float4 out_pos : POSITION) 8 | { 9 | out_pos = pos; 10 | 11 | AdjustYDir(out_pos); 12 | } 13 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Sparse/Attention/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/sparse/attention/__init__.py 5 | 6 | from .FullAttn import * 7 | from .Modules import * 8 | from .WindowedAttn import * 9 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Pipelines/Samplers/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/pipelines/samplers/__init__.py 5 | 6 | from .FlowEuler import FlowEulerSampler, FlowEulerCfgSampler, FlowEulerGuidanceIntervalSampler 7 | -------------------------------------------------------------------------------- /Source/Base/Include/Base/MiniWindows.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #ifdef _WIN32 7 | #ifndef WIN32_LEAN_AND_MEAN 8 | #define WIN32_LEAN_AND_MEAN 9 | #endif 10 | #ifndef NOMINMAX 11 | #define NOMINMAX 12 | #endif 13 | #include 14 | #endif 15 | -------------------------------------------------------------------------------- /Source/SubMConv/Source/Torch/Shader/Common.hlslh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | uint32_t HashFunc(uint32_t4 val) 7 | { 8 | uint32_t h = val.x ^ val.y; 9 | h ^= h >> 16; 10 | h *= 0x85EBCA6BU; 11 | h ^= val.z ^ (h >> 13); 12 | h *= 0xC2B2AE35U; 13 | h ^= val.w ^ (h >> 16); 14 | return h; 15 | } 16 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Shader/Platform.hlslh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #ifdef __spirv__ 7 | #define ALLOW_UAV_CONDITION 8 | #else 9 | #define ALLOW_UAV_CONDITION [allow_uav_condition] 10 | #endif 11 | 12 | void AdjustYDir(inout float4 out_pos) 13 | { 14 | #ifdef VULKAN_SHADER 15 | out_pos.y *= -1; 16 | #endif 17 | } 18 | -------------------------------------------------------------------------------- /Source/Lib/Source/Util/FormatConversion.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "AIHoloImager/ElementFormat.hpp" 7 | #include "Gpu/GpuFormat.hpp" 8 | 9 | namespace AIHoloImager 10 | { 11 | GpuFormat ToGpuFormat(ElementFormat fmt); 12 | ElementFormat ToElementFormat(GpuFormat fmt); 13 | } // namespace AIHoloImager 14 | -------------------------------------------------------------------------------- /Source/Lib/Source/TextureRecon/Shader/FlattenPs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | void main(float3 pos_ws : TEXCOORD0, 5 | float3 normal_ws : TEXCOORD1, 6 | out float4 pos_rt : SV_Target0, 7 | out float4 normal_rt : SV_Target1) 8 | { 9 | pos_rt = float4(pos_ws, 1); 10 | normal_rt = float4(normalize(normal_ws) * 0.5f + 0.5f, 1); 11 | } 12 | -------------------------------------------------------------------------------- /External/stb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "stb" 5 | URL "https://github.com/nothings/stb.git" 6 | REV "b42009b3b9d4ca35bc703f5310eedc74f584be58" 7 | ) 8 | 9 | add_library(stb INTERFACE) 10 | target_include_directories(stb 11 | INTERFACE 12 | ${CMAKE_CURRENT_SOURCE_DIR}/stb 13 | ) 14 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/InvisibleFacesRemover/FaceIdVs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Platform.hlslh" 5 | 6 | cbuffer param_cb 7 | { 8 | float4x4 mvp; 9 | }; 10 | 11 | void main(float3 pos : POSITION, 12 | out float4 out_pos : SV_Position) 13 | { 14 | out_pos = mul(float4(pos, 1), mvp); 15 | 16 | AdjustYDir(out_pos); 17 | } 18 | -------------------------------------------------------------------------------- /Source/Lib/Source/TextureRecon/Shader/GenShadowMapVs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Platform.hlslh" 5 | 6 | cbuffer param_cb 7 | { 8 | float4x4 mvp; 9 | }; 10 | 11 | void main(float3 pos : POSITION, 12 | out float4 out_pos : SV_Position) 13 | { 14 | out_pos = mul(float4(pos.xyz, 1), mvp); 15 | 16 | AdjustYDir(out_pos); 17 | } 18 | -------------------------------------------------------------------------------- /Source/Lib/Source/Delighter/ModMidas/Wsl.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Inspired by https://github.com/facebookresearch/WSL-Images/blob/main/hubconf.py 5 | 6 | from torchvision.models import resnet 7 | 8 | def Resnext101_32(width_per_group): 9 | kwargs = {} 10 | kwargs["groups"] = 32 11 | kwargs["width_per_group"] = width_per_group 12 | return resnet.ResNet(resnet.Bottleneck, [3, 4, 23, 3], **kwargs) 13 | -------------------------------------------------------------------------------- /Source/GpuSystem/Include/Gpu/InternalDefine.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #define DEFINE_INTERNAL(ClassName) \ 7 | public: \ 8 | ClassName##Internal& Internal() noexcept; \ 9 | const ClassName##Internal& Internal() const noexcept; \ 10 | \ 11 | private: 12 | -------------------------------------------------------------------------------- /Source/Base/Include/Base/Noncopyable.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #define DISALLOW_COPY_AND_ASSIGN(ClassName) \ 7 | ClassName(ClassName const& other) = delete; \ 8 | ClassName& operator=(ClassName const& other) = delete; 9 | 10 | #define DISALLOW_COPY_MOVE_AND_ASSIGN(ClassName) \ 11 | ClassName(ClassName&& other) = delete; \ 12 | ClassName& operator=(ClassName&& other) = delete; 13 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/RotatePs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #ifdef __spirv__ 5 | [[vk::binding(1)]] 6 | #endif 7 | Texture2D image_tex; 8 | 9 | #ifdef __spirv__ 10 | [[vk::binding(2)]] 11 | #endif 12 | SamplerState bilinear_sampler; 13 | 14 | float4 main(float2 texcoord : TEXCOORD0) : SV_Target0 15 | { 16 | const float4 color = image_tex.Sample(bilinear_sampler, texcoord); 17 | return float4(color.rgb * color.a, 1); 18 | } 19 | -------------------------------------------------------------------------------- /External/glm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "glm" 5 | URL "https://github.com/g-truc/glm.git" 6 | REV "33b4a621a697a305bc3a7610d290677b96beb181" 7 | ) 8 | 9 | set(BUILD_SHARED_LIBS OFF) 10 | set(GLM_BUILD_TESTS OFF CACHE BOOL "" FORCE) 11 | set(GLM_ENABLE_CXX_20 ON CACHE BOOL "" FORCE) 12 | 13 | add_subdirectory(glm EXCLUDE_FROM_ALL) 14 | 15 | set_target_properties(glm PROPERTIES FOLDER "External") 16 | -------------------------------------------------------------------------------- /External/DirectX-Headers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "DirectX-Headers" 5 | URL "https://github.com/microsoft/DirectX-Headers.git" 6 | REV "980971e835876dc0cde415e8f9bc646e64667bf7" 7 | ) 8 | 9 | set(DXHEADERS_BUILD_TEST OFF CACHE BOOL "" FORCE) 10 | set(DXHEADERS_INSTALL OFF CACHE BOOL "" FORCE) 11 | set(DXHEADERS_BUILD_GOOGLE_TEST OFF CACHE BOOL "" FORCE) 12 | 13 | add_subdirectory(DirectX-Headers EXCLUDE_FROM_ALL) 14 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/D3D12/D3D12Util.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "D3D12Util.hpp" 5 | 6 | #include "Base/Util.hpp" 7 | 8 | namespace AIHoloImager 9 | { 10 | void SetName(ID3D12Object& d3d12_object, std::string_view name) 11 | { 12 | std::u16string utf16_name; 13 | Convert(utf16_name, std::move(name)); 14 | d3d12_object.SetName(name.empty() ? L"" : reinterpret_cast(utf16_name.c_str())); 15 | } 16 | } // namespace AIHoloImager 17 | -------------------------------------------------------------------------------- /External/.gitignore: -------------------------------------------------------------------------------- 1 | assimp/assimp/ 2 | cxxopts/cxxopts/ 3 | dinov2/dinov2/ 4 | dinov2/Dinov2Models/ 5 | DirectX-Headers/DirectX-Headers/ 6 | DirectXShaderCompiler/PrebuiltDxc/ 7 | glm/glm/ 8 | Intrinsic/IntrinsicModels/ 9 | MoGe/moge-vitl 10 | nvdiffrast/nvdiffrast/ 11 | openMVG/openMVG/ 12 | openMVS/OpenMVS_* 13 | PythonVenv/PythonVenv/ 14 | SPIRV-Reflect/SPIRV-Reflect/ 15 | TRELLIS/TRELLIS-image-large/ 16 | stb/stb/ 17 | U-2-Net/U2NetModels/ 18 | volk/volk/ 19 | Vulkan-Headers/Vulkan-Headers/ 20 | xatlas/xatlas/ 21 | zlib/zlib/ 22 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuBufferInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuBufferInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuBufferInternal::GpuBufferInternal() noexcept = default; 9 | GpuBufferInternal::~GpuBufferInternal() = default; 10 | 11 | GpuBufferInternal::GpuBufferInternal(GpuBufferInternal&& other) noexcept = default; 12 | GpuBufferInternal& GpuBufferInternal::operator=(GpuBufferInternal&& other) noexcept = default; 13 | } // namespace AIHoloImager 14 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuSystemInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuSystemInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuSystemInternal::GpuSystemInternal() noexcept = default; 9 | GpuSystemInternal::~GpuSystemInternal() = default; 10 | 11 | GpuSystemInternal::GpuSystemInternal(GpuSystemInternal&& other) noexcept = default; 12 | GpuSystemInternal& GpuSystemInternal::operator=(GpuSystemInternal&& other) noexcept = default; 13 | } // namespace AIHoloImager 14 | -------------------------------------------------------------------------------- /External/cxxopts/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "cxxopts" 5 | URL "https://github.com/jarro2783/cxxopts.git" 6 | REV "eb787304d67ec22f7c3a184ee8b4c481d04357fd" 7 | ) 8 | 9 | set(CXXOPTS_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) 10 | set(CXXOPTS_BUILD_TESTS OFF CACHE BOOL "" FORCE) 11 | set(CXXOPTS_ENABLE_INSTALL OFF CACHE BOOL "" FORCE) 12 | set(CXXOPTS_USE_UNICODE_HELP OFF CACHE BOOL "" FORCE) 13 | 14 | add_subdirectory(cxxopts EXCLUDE_FROM_ALL) 15 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuTextureInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuTextureInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuTextureInternal::GpuTextureInternal() noexcept = default; 9 | GpuTextureInternal::~GpuTextureInternal() = default; 10 | 11 | GpuTextureInternal::GpuTextureInternal(GpuTextureInternal&& other) noexcept = default; 12 | GpuTextureInternal& GpuTextureInternal::operator=(GpuTextureInternal&& other) noexcept = default; 13 | } // namespace AIHoloImager 14 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuResourceInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuResourceInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuResourceInternal::GpuResourceInternal() noexcept = default; 9 | GpuResourceInternal::~GpuResourceInternal() = default; 10 | 11 | GpuResourceInternal::GpuResourceInternal(GpuResourceInternal&& other) noexcept = default; 12 | GpuResourceInternal& GpuResourceInternal::operator=(GpuResourceInternal&& other) noexcept = default; 13 | } // namespace AIHoloImager 14 | -------------------------------------------------------------------------------- /External/xatlas/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "xatlas" 5 | URL "https://github.com/jpcy/xatlas.git" 6 | REV "f700c7790aaa030e794b52ba7791a05c085faf0c" 7 | ) 8 | 9 | add_library(xatlas STATIC 10 | xatlas/source/xatlas/xatlas.cpp 11 | xatlas/source/xatlas/xatlas.h 12 | ) 13 | 14 | target_include_directories(xatlas 15 | PUBLIC 16 | ${CMAKE_CURRENT_SOURCE_DIR}/xatlas/source 17 | ) 18 | 19 | set_target_properties(xatlas PROPERTIES FOLDER "External") 20 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/TextureCopyCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t2 tex_size; 9 | }; 10 | 11 | Texture2D texture; 12 | 13 | RWTexture2D texture_f32; 14 | 15 | [numthreads(BlockDim, BlockDim, 1)] 16 | void main(uint32_t3 dtid : SV_DispatchThreadID) 17 | { 18 | [branch] 19 | if (any(dtid.xy >= tex_size)) 20 | { 21 | return; 22 | } 23 | 24 | texture_f32[dtid.xy] = texture.Load(uint3(dtid.xy, 0)); 25 | } 26 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuSystemInternalFactory.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include "GpuSystemInternal.hpp" 10 | 11 | namespace AIHoloImager 12 | { 13 | std::unique_ptr CreateGpuSystemInternal(GpuSystem::Api api, GpuSystem& gpu_system, 14 | std::function confirm_device = nullptr, bool enable_sharing = false, 15 | bool enable_debug = false); 16 | } // namespace AIHoloImager 17 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/ScatterIndexCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 256; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t num_features; 9 | }; 10 | 11 | Buffer coords; 12 | 13 | RWTexture3D index_volume; 14 | 15 | [numthreads(BlockDim, 1, 1)] 16 | void main(uint32_t3 dtid : SV_DispatchThreadID) 17 | { 18 | [branch] 19 | if (dtid.x >= num_features) 20 | { 21 | return; 22 | } 23 | 24 | index_volume[coords[dtid.x]] = dtid.x + 1; // 0 is reserved as empty 25 | } 26 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/InvisibleFacesRemover/AccumFacesCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 256; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t num_faces; 9 | }; 10 | 11 | Buffer face_mark_buff; 12 | 13 | RWBuffer view_counter_buff; 14 | 15 | [numthreads(BlockDim, 1, 1)] 16 | void main(uint32_t3 dtid : SV_DispatchThreadID) 17 | { 18 | [branch] 19 | if (dtid.x >= num_faces) 20 | { 21 | return; 22 | } 23 | 24 | view_counter_buff[dtid.x] += face_mark_buff[dtid.x]; 25 | } 26 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuCommandListInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuCommandListInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuCommandListInternal::GpuCommandListInternal() noexcept = default; 9 | GpuCommandListInternal::~GpuCommandListInternal() = default; 10 | 11 | GpuCommandListInternal::GpuCommandListInternal(GpuCommandListInternal&& other) noexcept = default; 12 | GpuCommandListInternal& GpuCommandListInternal::operator=(GpuCommandListInternal&& other) noexcept = default; 13 | } // namespace AIHoloImager 14 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuCommandPoolInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuCommandPoolInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuCommandPoolInternal::GpuCommandPoolInternal() noexcept = default; 9 | GpuCommandPoolInternal::~GpuCommandPoolInternal() noexcept = default; 10 | 11 | GpuCommandPoolInternal::GpuCommandPoolInternal(GpuCommandPoolInternal&& other) noexcept = default; 12 | GpuCommandPoolInternal& GpuCommandPoolInternal::operator=(GpuCommandPoolInternal&& other) noexcept = default; 13 | } // namespace AIHoloImager 14 | -------------------------------------------------------------------------------- /External/Vulkan-Headers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "Vulkan-Headers" 5 | URL "https://github.com/KhronosGroup/Vulkan-Headers.git" 6 | REV "6aefb8eb95c8e170d0805fd0f2d02832ec1e099a" 7 | ) 8 | 9 | set(VULKAN_HEADERS_ENABLE_TESTS OFF CACHE BOOL "" FORCE) 10 | set(ULKAN_HEADERS_ENABLE_INSTALL OFF CACHE BOOL "" FORCE) 11 | set(VULKAN_HEADERS_ENABLE_MODULE OFF CACHE BOOL "" FORCE) 12 | 13 | add_subdirectory(Vulkan-Headers EXCLUDE_FROM_ALL) 14 | 15 | set_target_properties(Vulkan-Headers PROPERTIES FOLDER "External") 16 | -------------------------------------------------------------------------------- /Source/Lib/Source/Delighter/Shader/MergeMaskCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t2 dest_size; 9 | }; 10 | 11 | Texture2D input_tex; 12 | 13 | #ifdef __spirv__ 14 | [[vk::image_format("rgba8")]] 15 | #endif 16 | RWTexture2D delighted_tex; 17 | 18 | [numthreads(BlockDim, BlockDim, 1)] 19 | void main(uint32_t3 dtid : SV_DispatchThreadID) 20 | { 21 | [branch] 22 | if (any(dtid.xy >= dest_size)) 23 | { 24 | return; 25 | } 26 | 27 | delighted_tex[dtid.xy].a = input_tex[dtid.xy].a; 28 | } 29 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/ExtractMaskCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t2 texture_size; 9 | }; 10 | 11 | Texture2D input_tex; 12 | 13 | #ifdef __spirv__ 14 | [[vk::image_format("r8")]] 15 | #endif 16 | RWTexture2D mask_tex; 17 | 18 | [numthreads(BlockDim, BlockDim, 1)] 19 | void main(uint32_t3 dtid : SV_DispatchThreadID) 20 | { 21 | [branch] 22 | if (any(dtid.xy >= texture_size)) 23 | { 24 | return; 25 | } 26 | 27 | mask_tex[dtid.xy] = input_tex.Load(uint32_t3(dtid.xy, 0)).a; 28 | } 29 | -------------------------------------------------------------------------------- /Source/Lib/Include/AIHoloImager/ElementFormat.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace AIHoloImager 9 | { 10 | enum class ElementFormat 11 | { 12 | Unknown, 13 | 14 | R8_UNorm, 15 | RG8_UNorm, 16 | RGB8_UNorm, 17 | RGBA8_UNorm, 18 | 19 | R32_Float, 20 | RG32_Float, 21 | RGB32_Float, 22 | RGBA32_Float, 23 | }; 24 | 25 | uint32_t FormatSize(ElementFormat fmt); 26 | uint32_t FormatChannels(ElementFormat fmt); 27 | uint32_t FormatChannelSize(ElementFormat fmt); 28 | } // namespace AIHoloImager 29 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuCommandPoolInternal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/Noncopyable.hpp" 7 | 8 | namespace AIHoloImager 9 | { 10 | class GpuCommandPoolInternal 11 | { 12 | DISALLOW_COPY_AND_ASSIGN(GpuCommandPoolInternal) 13 | 14 | public: 15 | GpuCommandPoolInternal() noexcept; 16 | virtual ~GpuCommandPoolInternal() noexcept; 17 | 18 | GpuCommandPoolInternal(GpuCommandPoolInternal&& other) noexcept; 19 | virtual GpuCommandPoolInternal& operator=(GpuCommandPoolInternal&& other) noexcept = 0; 20 | }; 21 | } // namespace AIHoloImager 22 | -------------------------------------------------------------------------------- /External/volk/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "volk" 5 | URL "https://github.com/zeux/volk.git" 6 | REV "59660878571aa99e3c9a366bb1d19fdcd701f0e7" 7 | ) 8 | 9 | set(VOLK_PULL_IN_VULKAN ON CACHE BOOL "" FORCE) 10 | set(VOLK_INSTALL OFF CACHE BOOL "" FORCE) 11 | set(VULKAN_HEADERS_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../Vulkan-Headers/Vulkan-Headers" CACHE PATH "" FORCE) 12 | 13 | if(WIN32) 14 | set(VOLK_STATIC_DEFINES VK_USE_PLATFORM_WIN32_KHR) 15 | endif() 16 | 17 | add_subdirectory(volk EXCLUDE_FROM_ALL) 18 | 19 | set_target_properties(volk PROPERTIES FOLDER "External") 20 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Sparse/Nonlinearity.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/sparse/nonlinearity.py 5 | 6 | import torch.nn as nn 7 | 8 | from . import SparseTensor 9 | 10 | __all__ = [ 11 | "SparseSiLU", 12 | "SparseGELU", 13 | ] 14 | 15 | class SparseSiLU(nn.SiLU): 16 | def forward(self, input: SparseTensor) -> SparseTensor: 17 | return input.replace(super().forward(input.feats)) 18 | 19 | class SparseGELU(nn.GELU): 20 | def forward(self, input: SparseTensor) -> SparseTensor: 21 | return input.replace(super().forward(input.feats)) 22 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Shader/GenMipmapCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t2 this_level_size; 9 | }; 10 | 11 | Texture2D last_level_tex; 12 | 13 | RWTexture2D this_level_tex; 14 | 15 | SamplerState mip_sampler : register(space1); 16 | 17 | [numthreads(BlockDim, BlockDim, 1)] 18 | void main(uint32_t3 dtid : SV_DispatchThreadID) 19 | { 20 | [branch] 21 | if (any(dtid.xy >= this_level_size)) 22 | { 23 | return; 24 | } 25 | 26 | this_level_tex[dtid.xy] = last_level_tex.SampleLevel(mip_sampler, (dtid.xy + 0.5f) / this_level_size, 0); 27 | } 28 | -------------------------------------------------------------------------------- /Source/Lib/Source/TextureRecon/Shader/FlattenVs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Platform.hlslh" 5 | 6 | cbuffer param_cb 7 | { 8 | float4x4 model_mtx; 9 | float4x4 model_it_mtx; 10 | }; 11 | 12 | void main(float3 pos : POSITION, 13 | float3 normal : NORMAL, 14 | float2 tc : TEXCOORD0, 15 | out float3 out_pos_ws : TEXCOORD0, 16 | out float3 out_normal_ws : TEXCOORD1, 17 | out float4 out_pos : SV_Position) 18 | { 19 | out_pos = float4(tc.xy * 2 - 1, 0, 1); 20 | out_pos_ws = mul(float4(pos, 1), model_mtx).xyz; 21 | out_normal_ws = mul(normal, (float3x3)model_it_mtx); 22 | 23 | AdjustYDir(out_pos); 24 | } 25 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/InvisibleFacesRemover/MarkFacesCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t2 width_height; 9 | }; 10 | 11 | Texture2D face_id_tex; 12 | 13 | RWBuffer face_mark_buff; 14 | 15 | [numthreads(BlockDim, BlockDim, 1)] 16 | void main(uint32_t3 dtid : SV_DispatchThreadID) 17 | { 18 | [branch] 19 | if (any(dtid.xy >= width_height)) 20 | { 21 | return; 22 | } 23 | 24 | const uint32_t face_id = face_id_tex.Load(uint32_t3(dtid.xy, 0)); 25 | if (face_id > 0) 26 | { 27 | face_mark_buff[face_id - 1] = 1; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /External/SPIRV-Reflect/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "SPIRV-Reflect" 5 | URL "https://github.com/KhronosGroup/SPIRV-Reflect.git" 6 | REV "ef913b3ab3da1becca3cf46b15a10667c67bebe5" 7 | ) 8 | 9 | set(SPIRV_REFLECT_BUILD_TESTS OFF CACHE BOOL "" FORCE) 10 | set(SPIRV_REFLECT_ENABLE_ASAN OFF CACHE BOOL "" FORCE) 11 | set(SPIRV_REFLECT_EXECUTABLE OFF CACHE BOOL "" FORCE) 12 | set(SPIRV_REFLECT_INSTALL OFF CACHE BOOL "" FORCE) 13 | set(SPIRV_REFLECT_STATIC_LIB ON CACHE BOOL "" FORCE) 14 | 15 | add_subdirectory(SPIRV-Reflect EXCLUDE_FROM_ALL) 16 | 17 | set_target_properties(spirv-reflect-static PROPERTIES FOLDER "External") 18 | -------------------------------------------------------------------------------- /Source/Base/Source/Timer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Base/Timer.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | Timer::Timer() noexcept 9 | { 10 | this->Restart(); 11 | } 12 | 13 | void Timer::Restart() noexcept 14 | { 15 | start_time_ = this->Now(); 16 | } 17 | 18 | std::chrono::duration Timer::Elapsed() const noexcept 19 | { 20 | return std::chrono::duration(this->Now() - start_time_); 21 | } 22 | 23 | std::chrono::high_resolution_clock::time_point Timer::Now() const noexcept 24 | { 25 | return std::chrono::high_resolution_clock::now(); 26 | } 27 | } // namespace AIHoloImager 28 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Pipelines/Samplers/ClassifierFreeGuidanceMixin.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/pipelines/samplers/classifier_free_guidance_mixin.py 5 | 6 | class ClassifierFreeGuidanceSamplerMixin: 7 | """ 8 | A mixin class for samplers that apply classifier-free guidance. 9 | """ 10 | 11 | def InferenceModel(self, model, x_t, t, cond, neg_cond, cfg_strength, **kwargs): 12 | pred = super().InferenceModel(model, x_t, t, cond, **kwargs) 13 | neg_pred = super().InferenceModel(model, x_t, t, neg_cond, **kwargs) 14 | return (1 + cfg_strength) * pred - cfg_strength * neg_pred 15 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/AntiAliasIndirectCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Common.hlslh" 5 | 6 | static const uint32_t BlockDim = 32; 7 | 8 | cbuffer param_cb 9 | { 10 | uint32_t bwd_block_dim; 11 | }; 12 | 13 | Buffer silhouette_counter; 14 | 15 | RWBuffer indirect_args; 16 | 17 | [numthreads(BlockDim, 1, 1)] 18 | void main(uint32_t3 dtid : SV_DispatchThreadID) 19 | { 20 | [branch] 21 | if (any(dtid.x >= 3)) 22 | { 23 | return; 24 | } 25 | 26 | if (dtid.x == 0) 27 | { 28 | indirect_args[0] = DivUp(silhouette_counter[0], bwd_block_dim); 29 | } 30 | else 31 | { 32 | indirect_args[dtid.x] = 1; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Sparse/Linear.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/sparse/linear.py 5 | 6 | from typing import Optional 7 | 8 | import torch 9 | import torch.nn as nn 10 | 11 | from . import SparseTensor 12 | 13 | __all__ = [ 14 | "SparseLinear" 15 | ] 16 | 17 | class SparseLinear(nn.Linear): 18 | def __init__(self, in_features, out_features, bias = True, device: Optional[torch.device] = None): 19 | super(SparseLinear, self).__init__(in_features, out_features, bias, device = device) 20 | 21 | def forward(self, input: SparseTensor) -> SparseTensor: 22 | return input.replace(super().forward(input.feats)) 23 | -------------------------------------------------------------------------------- /Source/Base/Include/Base/Timer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace AIHoloImager 9 | { 10 | class Timer final 11 | { 12 | public: 13 | Timer() noexcept; 14 | 15 | void Restart() noexcept; 16 | std::chrono::high_resolution_clock::time_point Now() const noexcept; 17 | 18 | std::chrono::duration Elapsed() const noexcept; 19 | 20 | template 21 | T ElapsedOfType() const noexcept 22 | { 23 | return std::chrono::duration_cast(this->Elapsed()); 24 | } 25 | 26 | private: 27 | std::chrono::high_resolution_clock::time_point start_time_; 28 | }; 29 | } // namespace AIHoloImager -------------------------------------------------------------------------------- /Source/Base/Include/Base/SmartPtrHelper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/MiniWindows.hpp" 7 | 8 | #include 9 | 10 | namespace AIHoloImager 11 | { 12 | #ifdef _WIN32 13 | class Win32HandleDeleter final 14 | { 15 | public: 16 | void operator()(HANDLE handle) 17 | { 18 | if (handle != INVALID_HANDLE_VALUE) 19 | { 20 | ::CloseHandle(handle); 21 | } 22 | } 23 | }; 24 | using Win32UniqueHandle = std::unique_ptr; 25 | 26 | inline Win32UniqueHandle MakeWin32UniqueHandle(HANDLE handle) 27 | { 28 | return Win32UniqueHandle(handle); 29 | } 30 | #endif 31 | } // namespace AIHoloImager 32 | -------------------------------------------------------------------------------- /Source/GpuSystem/Include/Gpu/Vulkan/VulkanTraits.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace AIHoloImager 9 | { 10 | struct VulkanTraits 11 | { 12 | using DeviceType = VkDevice; 13 | using CommandQueueType = VkQueue; 14 | 15 | using CommandListType = VkCommandBuffer; 16 | using GraphicsCommandListType = VkCommandBuffer; 17 | using ComputeCommandListType = VkCommandBuffer; 18 | using VideoEncodeCommandListType = VkCommandBuffer; 19 | 20 | using ResourceType = VkDeviceMemory; 21 | using BufferType = VkBuffer; 22 | using TextureType = VkImage; 23 | 24 | using SharedHandleType = HANDLE; 25 | }; 26 | } // namespace AIHoloImager 27 | -------------------------------------------------------------------------------- /Source/Base/Include/Base/Util.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace AIHoloImager 11 | { 12 | constexpr uint32_t LogNextPowerOf2(uint32_t n) 13 | { 14 | if (n <= 1) 15 | { 16 | return 1; 17 | } 18 | return sizeof(uint32_t) * 8 - std::countl_zero(n - 1) + 1; 19 | } 20 | 21 | // The strings here actually store UTF-8 encoded data 22 | void Convert(std::string& dest, std::string_view src); 23 | void Convert(std::string& dest, std::u16string_view src); 24 | void Convert(std::u16string& dest, std::string_view src); 25 | void Convert(std::u16string& dest, std::u16string_view src); 26 | } // namespace AIHoloImager 27 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/RotateVs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Platform.hlslh" 5 | 6 | #ifdef __spirv__ 7 | [[vk::binding(0)]] 8 | #endif 9 | cbuffer param_cb 10 | { 11 | float4x4 rotation_mtx; 12 | float4 tc_bounding_box; 13 | }; 14 | 15 | void main(uint32_t vertex_id : SV_VertexId, 16 | out float2 out_texcoord : TEXCOORD0, 17 | out float4 out_pos : SV_Position) 18 | { 19 | const float2 Quad[] = { 20 | float2(-1, +1), 21 | float2(+1, +1), 22 | float2(-1, -1), 23 | float2(+1, -1), 24 | }; 25 | 26 | float2 pos = Quad[vertex_id]; 27 | out_pos = mul(float4(pos, 0, 1), rotation_mtx); 28 | out_texcoord = select(pos < 0, tc_bounding_box.xw, tc_bounding_box.zy); 29 | 30 | AdjustYDir(out_pos); 31 | } 32 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshSimp/MeshSimplification.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "AIHoloImager/Mesh.hpp" 9 | #include "Base/Noncopyable.hpp" 10 | 11 | namespace AIHoloImager 12 | { 13 | class MeshSimplification 14 | { 15 | DISALLOW_COPY_AND_ASSIGN(MeshSimplification); 16 | 17 | public: 18 | MeshSimplification(); 19 | MeshSimplification(MeshSimplification&& other) noexcept; 20 | ~MeshSimplification() noexcept; 21 | 22 | MeshSimplification& operator=(MeshSimplification&& other) noexcept; 23 | 24 | Mesh Process(const Mesh& mesh, float face_ratio); 25 | 26 | private: 27 | class Impl; 28 | std::unique_ptr impl_; 29 | }; 30 | } // namespace AIHoloImager 31 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuVertexLayoutInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuVertexLayoutInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuVertexLayoutInternal::GpuVertexLayoutInternal() noexcept = default; 9 | GpuVertexLayoutInternal::~GpuVertexLayoutInternal() = default; 10 | 11 | GpuVertexLayoutInternal::GpuVertexLayoutInternal(const GpuVertexLayoutInternal& other) = default; 12 | GpuVertexLayoutInternal& GpuVertexLayoutInternal::operator=(const GpuVertexLayoutInternal& other) = default; 13 | 14 | GpuVertexLayoutInternal::GpuVertexLayoutInternal(GpuVertexLayoutInternal&& other) noexcept = default; 15 | GpuVertexLayoutInternal& GpuVertexLayoutInternal::operator=(GpuVertexLayoutInternal&& other) noexcept = default; 16 | } // namespace AIHoloImager 17 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Pipelines/Samplers/GuidanceIntervalMixin.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/pipelines/samplers/guidance_interval_mixin.py 5 | 6 | class GuidanceIntervalSamplerMixin: 7 | """ 8 | A mixin class for samplers that apply classifier-free guidance with interval. 9 | """ 10 | 11 | def InferenceModel(self, model, x_t, t, cond, neg_cond, cfg_strength, cfg_interval, **kwargs): 12 | pred = super().InferenceModel(model, x_t, t, cond, **kwargs) 13 | if cfg_interval[0] <= t <= cfg_interval[1]: 14 | neg_pred = super().InferenceModel(model, x_t, t, neg_cond, **kwargs) 15 | return (1 + cfg_strength) * pred - cfg_strength * neg_pred 16 | else: 17 | return pred 18 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuVertexLayoutInternal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace AIHoloImager 9 | { 10 | class GpuVertexLayoutInternal 11 | { 12 | public: 13 | GpuVertexLayoutInternal() noexcept; 14 | GpuVertexLayoutInternal(const GpuVertexLayoutInternal& other); 15 | GpuVertexLayoutInternal(GpuVertexLayoutInternal&& other) noexcept; 16 | virtual ~GpuVertexLayoutInternal(); 17 | 18 | virtual GpuVertexLayoutInternal& operator=(const GpuVertexLayoutInternal& other) = 0; 19 | virtual GpuVertexLayoutInternal& operator=(GpuVertexLayoutInternal&& other) noexcept = 0; 20 | 21 | virtual std::unique_ptr Clone() const = 0; 22 | }; 23 | } // namespace AIHoloImager 24 | -------------------------------------------------------------------------------- /Source/Lib/Source/TextureRecon/Shader/ResolveTextureCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t texture_size; 9 | }; 10 | 11 | Texture2D accum_color_tex; 12 | 13 | #ifdef __spirv__ 14 | [[vk::image_format("rgba8")]] 15 | #endif 16 | RWTexture2D color_tex; 17 | 18 | [numthreads(BlockDim, BlockDim, 1)] 19 | void main(uint32_t3 dtid : SV_DispatchThreadID) 20 | { 21 | [branch] 22 | if (any(dtid.xy >= texture_size)) 23 | { 24 | return; 25 | } 26 | 27 | float4 color = accum_color_tex.Load(uint32_t3(dtid.xy, 0)); 28 | if (color.a < 0.1f) 29 | { 30 | color = 0; 31 | } 32 | else 33 | { 34 | color.a = 1; 35 | } 36 | 37 | color_tex[dtid.xy] = color; 38 | } 39 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/Shader/MergeMaskCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t2 texture_size; 9 | uint32_t4 roi; 10 | }; 11 | 12 | Texture2D mask_tex; 13 | 14 | #ifdef __spirv__ 15 | [[vk::image_format("rgba8")]] 16 | #endif 17 | RWTexture2D output_tex; 18 | 19 | [numthreads(BlockDim, BlockDim, 1)] 20 | void main(uint32_t3 dtid : SV_DispatchThreadID) 21 | { 22 | [branch] 23 | if (any(dtid.xy >= texture_size)) 24 | { 25 | return; 26 | } 27 | 28 | float mask = 0; 29 | if ((dtid.x >= roi.x) && (dtid.x < roi.z) && (dtid.y >= roi.y) && (dtid.y < roi.w)) 30 | { 31 | mask = mask_tex.Load(uint32_t3(dtid.xy - roi.xy, 0)); 32 | } 33 | 34 | output_tex[dtid.xy].w = mask; 35 | } 36 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/ResizeCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Lanczos.hlslh" 5 | 6 | static const uint32_t BlockDim = 16; 7 | static const uint32_t KernelRadius = 3; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t4 src_roi; 12 | uint32_t2 dest_size; 13 | float scale; 14 | bool x_dir; 15 | }; 16 | 17 | Texture2D input_tex; 18 | 19 | #ifdef __spirv__ 20 | [[vk::image_format("rgba8")]] 21 | #endif 22 | RWTexture2D output_tex; 23 | 24 | [numthreads(BlockDim, BlockDim, 1)] 25 | void main(uint32_t3 dtid : SV_DispatchThreadID) 26 | { 27 | [branch] 28 | if (any(dtid.xy >= dest_size)) 29 | { 30 | return; 31 | } 32 | 33 | output_tex[dtid.xy] = LanczosResample(input_tex, dtid.xy, src_roi, scale, KernelRadius, x_dir, float4(0, 0, 0, 0), float4(1, 1, 1, 1)); 34 | } 35 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/Shader/DownsampleCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #include "Lanczos.hlslh" 5 | 6 | static const uint32_t BlockDim = 16; 7 | static const uint32_t KernelRadius = 3; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t4 src_roi; 12 | uint32_t2 dest_size; 13 | float scale; 14 | bool x_dir; 15 | }; 16 | 17 | Texture2D input_tex; 18 | 19 | #ifdef __spirv__ 20 | [[vk::image_format("rgba8")]] 21 | #endif 22 | RWTexture2D output_tex; 23 | 24 | [numthreads(BlockDim, BlockDim, 1)] 25 | void main(uint32_t3 dtid : SV_DispatchThreadID) 26 | { 27 | [branch] 28 | if (any(dtid.xy >= dest_size)) 29 | { 30 | return; 31 | } 32 | 33 | output_tex[dtid.xy] = LanczosResample(input_tex, dtid.xy, src_roi, scale, KernelRadius, x_dir, float4(0, 0, 0, 0), float4(1, 1, 1, 1)); 34 | } 35 | -------------------------------------------------------------------------------- /Source/SubMConv/Source/Torch/PyTorchBindings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "SubMConv.hpp" 5 | 6 | #ifdef _DEBUG 7 | #undef _DEBUG // Stop linking to python_d.lib 8 | #endif 9 | #include 10 | 11 | #ifdef _MSC_VER 12 | #pragma warning(push) 13 | #pragma warning(disable : 4251) // Ignore non dll-interface as member 14 | #endif 15 | #include 16 | #ifdef _MSC_VER 17 | #pragma warning(pop) 18 | #endif 19 | 20 | using namespace AIHoloImager; 21 | 22 | PYBIND11_MODULE(AIHoloImagerSubMConv, mod) 23 | { 24 | pybind11::class_(mod, "SubMConv3DHelper") 25 | .def(pybind11::init()) 26 | .def("BuildCoordsMap", &SubMConv3DHelper::BuildCoordsMap) 27 | .def("FindAvailableNeighbors", &SubMConv3DHelper::FindAvailableNeighbors); 28 | } 29 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/MarchingCubes.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "AIHoloImager/Mesh.hpp" 7 | #include "AIHoloImagerInternal.hpp" 8 | #include "Base/Noncopyable.hpp" 9 | #include "Gpu/GpuTexture.hpp" 10 | 11 | namespace AIHoloImager 12 | { 13 | class MarchingCubes 14 | { 15 | DISALLOW_COPY_AND_ASSIGN(MarchingCubes); 16 | 17 | public: 18 | explicit MarchingCubes(AIHoloImagerInternal& aihi); 19 | MarchingCubes(MarchingCubes&& other) noexcept; 20 | ~MarchingCubes() noexcept; 21 | 22 | MarchingCubes& operator=(MarchingCubes&& other) noexcept; 23 | 24 | Mesh Generate(const GpuTexture3D& scalar_deformation, float isovalue, float scale); 25 | 26 | private: 27 | class Impl; 28 | std::unique_ptr impl_; 29 | }; 30 | } // namespace AIHoloImager 31 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/InvisibleFacesRemover.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "AIHoloImager/Mesh.hpp" 9 | #include "AIHoloImagerInternal.hpp" 10 | #include "Base/Noncopyable.hpp" 11 | 12 | namespace AIHoloImager 13 | { 14 | class InvisibleFacesRemover 15 | { 16 | DISALLOW_COPY_AND_ASSIGN(InvisibleFacesRemover); 17 | 18 | public: 19 | explicit InvisibleFacesRemover(AIHoloImagerInternal& aihi); 20 | InvisibleFacesRemover(InvisibleFacesRemover&& other) noexcept; 21 | ~InvisibleFacesRemover() noexcept; 22 | 23 | InvisibleFacesRemover& operator=(InvisibleFacesRemover&& other) noexcept; 24 | 25 | Mesh Process(const Mesh& mesh); 26 | 27 | private: 28 | class Impl; 29 | std::unique_ptr impl_; 30 | }; 31 | } // namespace AIHoloImager 32 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/MeshGenerator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "AIHoloImager/Mesh.hpp" 7 | #include "AIHoloImagerInternal.hpp" 8 | #include "Base/Noncopyable.hpp" 9 | #include "SfM/StructureFromMotion.hpp" 10 | 11 | namespace AIHoloImager 12 | { 13 | class MeshGenerator 14 | { 15 | DISALLOW_COPY_AND_ASSIGN(MeshGenerator); 16 | 17 | public: 18 | explicit MeshGenerator(AIHoloImagerInternal& aihi); 19 | MeshGenerator(MeshGenerator&& other) noexcept; 20 | ~MeshGenerator() noexcept; 21 | 22 | MeshGenerator& operator=(MeshGenerator&& other) noexcept; 23 | 24 | Mesh Generate(const StructureFromMotion::Result& sfm_input, uint32_t texture_size); 25 | 26 | private: 27 | class Impl; 28 | std::unique_ptr impl_; 29 | }; 30 | } // namespace AIHoloImager 31 | -------------------------------------------------------------------------------- /Source/Lib/Source/Delighter/Delighter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include "AIHoloImagerInternal.hpp" 10 | #include "Base/Noncopyable.hpp" 11 | #include "Gpu/GpuCommandList.hpp" 12 | #include "Gpu/GpuTexture.hpp" 13 | 14 | namespace AIHoloImager 15 | { 16 | class Delighter 17 | { 18 | DISALLOW_COPY_AND_ASSIGN(Delighter); 19 | 20 | public: 21 | explicit Delighter(AIHoloImagerInternal& aihi); 22 | Delighter(Delighter&& other) noexcept; 23 | ~Delighter() noexcept; 24 | 25 | Delighter& operator=(Delighter&& other) noexcept; 26 | 27 | GpuTexture2D Process(GpuCommandList& cmd_list, const GpuTexture2D& image); 28 | 29 | private: 30 | class Impl; 31 | std::unique_ptr impl_; 32 | }; 33 | } // namespace AIHoloImager 34 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/MaskGenerator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "AIHoloImagerInternal.hpp" 9 | #include "Base/Noncopyable.hpp" 10 | #include "Gpu/GpuCommandList.hpp" 11 | #include "Gpu/GpuTexture.hpp" 12 | 13 | namespace AIHoloImager 14 | { 15 | class MaskGenerator 16 | { 17 | DISALLOW_COPY_AND_ASSIGN(MaskGenerator); 18 | 19 | public: 20 | explicit MaskGenerator(AIHoloImagerInternal& aihi); 21 | MaskGenerator(MaskGenerator&& other) noexcept; 22 | ~MaskGenerator() noexcept; 23 | 24 | MaskGenerator& operator=(MaskGenerator&& other) noexcept; 25 | 26 | void Generate(GpuCommandList& cmd_list, GpuTexture2D& image, glm::uvec4& roi); 27 | 28 | private: 29 | class Impl; 30 | std::unique_ptr impl_; 31 | }; 32 | } // namespace AIHoloImager 33 | -------------------------------------------------------------------------------- /Source/GpuSystem/Include/Gpu/GpuCommandPool.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "Base/Noncopyable.hpp" 9 | #include "Gpu/GpuSystem.hpp" 10 | #include "Gpu/InternalDefine.hpp" 11 | 12 | namespace AIHoloImager 13 | { 14 | class GpuCommandPoolInternal; 15 | 16 | class GpuCommandPool 17 | { 18 | DISALLOW_COPY_AND_ASSIGN(GpuCommandPool) 19 | DEFINE_INTERNAL(GpuCommandPool) 20 | 21 | public: 22 | GpuCommandPool() noexcept; 23 | GpuCommandPool(GpuSystem& gpu_system, GpuSystem::CmdQueueType type); 24 | ~GpuCommandPool() noexcept; 25 | 26 | GpuCommandPool(GpuCommandPool&& other) noexcept; 27 | GpuCommandPool& operator=(GpuCommandPool&& other) noexcept; 28 | 29 | private: 30 | class Impl; 31 | std::unique_ptr impl_; 32 | }; 33 | } // namespace AIHoloImager 34 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/InvisibleFacesRemover/FilterFacesCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 256; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t num_faces; 9 | uint32_t threshold; 10 | }; 11 | 12 | Buffer index_buff; 13 | Buffer view_count_buff; 14 | 15 | RWBuffer filtered_index_buff; 16 | RWBuffer counter; 17 | 18 | [numthreads(BlockDim, 1, 1)] 19 | void main(uint32_t3 dtid : SV_DispatchThreadID) 20 | { 21 | [branch] 22 | if (dtid.x >= num_faces) 23 | { 24 | return; 25 | } 26 | 27 | if (view_count_buff[dtid.x] > threshold) 28 | { 29 | uint32_t addr; 30 | InterlockedAdd(counter[0], 1, addr); 31 | 32 | for (uint32_t i = 0; i < 3; ++i) 33 | { 34 | filtered_index_buff[addr * 3 + i] = index_buff[dtid.x * 3 + i]; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Source/GpuSystem/Include/Gpu/D3D12/D3D12Traits.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/MiniWindows.hpp" 7 | 8 | #include 9 | #include 10 | 11 | namespace AIHoloImager 12 | { 13 | struct D3D12Traits 14 | { 15 | using DeviceType = ID3D12Device*; 16 | using CommandQueueType = ID3D12CommandQueue*; 17 | 18 | using CommandListType = ID3D12CommandList*; 19 | using GraphicsCommandListType = ID3D12GraphicsCommandList*; 20 | using ComputeCommandListType = ID3D12GraphicsCommandList*; 21 | using VideoEncodeCommandListType = ID3D12VideoEncodeCommandList*; 22 | 23 | using ResourceType = ID3D12Resource*; 24 | using BufferType = ID3D12Resource*; 25 | using TextureType = ID3D12Resource*; 26 | 27 | using SharedHandleType = HANDLE; 28 | }; 29 | } // namespace AIHoloImager 30 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanUtil.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "VulkanUtil.hpp" 5 | 6 | #include "Base/Util.hpp" 7 | 8 | #include "VulkanSystem.hpp" 9 | 10 | namespace AIHoloImager 11 | { 12 | void SetName(const VulkanSystem& vulkan_system, const void* vulkan_object, VkObjectType type, std::string_view name) 13 | { 14 | const VkDevice vulkan_device = vulkan_system.Device(); 15 | 16 | const std::string debug_name(std::move(name)); 17 | const VkDebugUtilsObjectNameInfoEXT debug_name_info{ 18 | .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, 19 | .objectType = type, 20 | .objectHandle = reinterpret_cast(vulkan_object), 21 | .pObjectName = debug_name.c_str(), 22 | }; 23 | vkSetDebugUtilsObjectNameEXT(vulkan_device, &debug_name_info); 24 | } 25 | } // namespace AIHoloImager 26 | -------------------------------------------------------------------------------- /External/zlib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "zlib" 5 | URL "https://github.com/madler/zlib.git" 6 | REV "09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851" 7 | ) 8 | 9 | set(SKIP_INSTALL_ALL ON CACHE BOOL "" FORCE) 10 | 11 | set(BUILD_SHARED_LIBS ON) 12 | set(ZLIB_BUILD_EXAMPLES OFF CACHE INTERNAL "" FORCE) 13 | 14 | add_subdirectory(zlib EXCLUDE_FROM_ALL) 15 | 16 | set(ZLIB_INCLUDE_DIR 17 | ${CMAKE_CURRENT_SOURCE_DIR}/zlib 18 | ${CMAKE_CURRENT_BINARY_DIR}/zlib 19 | CACHE INTERNAL "" FORCE 20 | ) 21 | set(ZLIB_LIBRARY zlib CACHE INTERNAL "" FORCE) 22 | set(ZLIB_LIBRARIES ${ZLIB_LIBRARY} CACHE INTERNAL "" FORCE) 23 | set(ZLIB_FOUND TRUE CACHE INTERNAL "" FORCE) 24 | add_library(ZLIB::ZLIB ALIAS zlib) 25 | 26 | set(ZLIB_LIBRARY_DEBUG "zlib") 27 | set(ZLIB_LIBRARY_RELEASE "zlib") 28 | 29 | set_target_properties(zlib PROPERTIES FOLDER "External") 30 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanErrorhandling.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "VulkanErrorHandling.hpp" 5 | 6 | #include 7 | #include 8 | 9 | namespace AIHoloImager 10 | { 11 | template 12 | std::string CombineFileLine(ResultType result, std::string_view file, uint32_t line) 13 | { 14 | std::ostringstream ss; 15 | if constexpr (std::is_same_v) 16 | { 17 | ss << "VkResult"; 18 | } 19 | else 20 | { 21 | static_assert(std::is_same_v); 22 | ss << "SpvReflectResult"; 23 | } 24 | ss << " of 0x" << std::hex << std::setfill('0') << std::setw(8) << static_cast(result); 25 | ss << CombineFileLine(std::move(file), line); 26 | return ss.str(); 27 | } 28 | } // namespace AIHoloImager 29 | -------------------------------------------------------------------------------- /Source/Lib/Source/AIHoloImagerInternal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "Gpu/GpuSystem.hpp" 9 | #include "Python/PythonSystem.hpp" 10 | #include "TensorConverter/TensorConverter.hpp" 11 | #include "Util/PerfProfiler.hpp" 12 | 13 | namespace AIHoloImager 14 | { 15 | class AIHoloImagerInternal 16 | { 17 | public: 18 | virtual ~AIHoloImagerInternal() noexcept; 19 | 20 | virtual const std::filesystem::path& ExeDir() noexcept = 0; 21 | virtual const std::filesystem::path& TmpDir() noexcept = 0; 22 | 23 | virtual GpuSystem& GpuSystemInstance() noexcept = 0; 24 | virtual PythonSystem& PythonSystemInstance() noexcept = 0; 25 | virtual PerfProfiler& PerfProfilerInstance() noexcept = 0; 26 | 27 | virtual TensorConverter& TensorConverterInstance() noexcept = 0; 28 | }; 29 | } // namespace AIHoloImager 30 | -------------------------------------------------------------------------------- /Source/GpuSystem/Include/Gpu/GpuMipmapper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "Base/Noncopyable.hpp" 9 | #include "Gpu/GpuSampler.hpp" 10 | #include "Gpu/GpuTexture.hpp" 11 | 12 | namespace AIHoloImager 13 | { 14 | class GpuSystem; 15 | class GpuCommandList; 16 | 17 | class GpuMipmapper final 18 | { 19 | DISALLOW_COPY_AND_ASSIGN(GpuMipmapper) 20 | 21 | public: 22 | GpuMipmapper(); 23 | explicit GpuMipmapper(GpuSystem& gpu_system); 24 | ~GpuMipmapper() noexcept; 25 | 26 | GpuMipmapper(GpuMipmapper&& other) noexcept; 27 | GpuMipmapper& operator=(GpuMipmapper&& other) noexcept; 28 | 29 | void Generate(GpuCommandList& cmd_list, GpuTexture2D& texture, GpuSampler::Filter filter); 30 | 31 | private: 32 | class Impl; 33 | std::unique_ptr impl_; 34 | }; 35 | } // namespace AIHoloImager 36 | -------------------------------------------------------------------------------- /Source/Base/Include/Base/Dll.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include 5 | #include 6 | 7 | #include "Base/Noncopyable.hpp" 8 | 9 | namespace AIHoloImager 10 | { 11 | class Dll final 12 | { 13 | DISALLOW_COPY_AND_ASSIGN(Dll); 14 | 15 | public: 16 | Dll() noexcept; 17 | explicit Dll(const std::filesystem::path& path); 18 | Dll(Dll&& other) noexcept; 19 | ~Dll() noexcept; 20 | 21 | Dll& operator=(Dll&& other) noexcept; 22 | 23 | explicit operator bool() const noexcept; 24 | 25 | void* Func(const char* proc_name) const noexcept; 26 | 27 | template 28 | T Func(const char* proc_name) const noexcept 29 | { 30 | return reinterpret_cast(this->Func(proc_name)); 31 | } 32 | 33 | private: 34 | class Impl; 35 | std::unique_ptr impl_; 36 | }; 37 | } // namespace AIHoloImager 38 | -------------------------------------------------------------------------------- /Source/Base/Source/ErrorHandling.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Base/ErrorHandling.hpp" 5 | 6 | #include 7 | #include 8 | 9 | namespace AIHoloImager 10 | { 11 | std::string CombineFileLine(std::string_view file, uint32_t line) 12 | { 13 | std::ostringstream ss; 14 | ss << " from " << file << ": " << line; 15 | return ss.str(); 16 | } 17 | 18 | std::string CombineFileLine(HRESULT hr, std::string_view file, uint32_t line) 19 | { 20 | std::ostringstream ss; 21 | ss << "HRESULT of 0x" << std::hex << std::setfill('0') << std::setw(8) << static_cast(hr); 22 | ss << CombineFileLine(std::move(file), line); 23 | return ss.str(); 24 | } 25 | 26 | void Verify(bool x) 27 | { 28 | if (!x) 29 | { 30 | throw std::runtime_error("Verify failed."); 31 | } 32 | } 33 | } // namespace AIHoloImager 34 | -------------------------------------------------------------------------------- /External/PythonVenv/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==2.3.0 2 | 3 | --extra-index-url https://download.pytorch.org/whl/cu126 4 | 5 | mpmath==1.3.0 6 | typing-extensions==4.15.0 7 | sympy==1.14.0 8 | networkx==3.5 9 | MarkupSafe==3.0.2 10 | fsspec==2025.10.0 11 | filelock==3.20.1 12 | jinja2==3.1.6 13 | torch==2.9.0+cu126 14 | 15 | #mpmath==1.3.0 16 | #typing-extensions==4.15.0 17 | #sympy==1.14.0 18 | pillow==12.0.0 19 | #numpy==2.3.0 20 | #networkx==3.5 21 | #MarkupSafe==3.0.2 22 | #fsspec==2025.10.0 23 | #filelock==3.20.1 24 | #jinja2==3.1.6 25 | #torch==2.9.0+cu126 26 | torchvision==0.24.0+cu126 27 | 28 | packaging==25.0 29 | safetensors==0.6.2 30 | 31 | colorama==0.4.6 32 | tqdm==4.67.0 33 | 34 | certifi==2025.10.5 35 | charset-normalizer==3.4.0 36 | #colorama==0.4.6 37 | #filelock==3.20.1 38 | idna==3.11 39 | requests==2.32.4 40 | #tqdm==4.67.0 41 | #typing-extensions==4.15.0 42 | urllib3==2.6.0 43 | soupsieve==2.8 44 | PySocks==1.7.1 45 | beautifulsoup4==4.14.2 46 | gdown==5.2.0 47 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/ApplyVertexColorCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 256; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t num_vertices; 9 | float inv_scale; 10 | }; 11 | 12 | Texture3D color_vol_tex; 13 | Buffer pos_vertex_buff; 14 | 15 | SamplerState trilinear_sampler; 16 | 17 | RWBuffer color_vertex_buff; 18 | 19 | [numthreads(BlockDim, 1, 1)] 20 | void main(uint32_t3 dtid : SV_DispatchThreadID) 21 | { 22 | [branch] 23 | if (dtid.x >= num_vertices) 24 | { 25 | return; 26 | } 27 | 28 | float3 pos_os = pos_vertex_buff[dtid.x]; 29 | 30 | const float3 vol_coord = pos_os.zyx * inv_scale + 0.5f; 31 | const float3 color = saturate(color_vol_tex.SampleLevel(trilinear_sampler, vol_coord, 0).rgb); 32 | color_vertex_buff[dtid.x * 3 + 0] = color.r; 33 | color_vertex_buff[dtid.x * 3 + 1] = color.g; 34 | color_vertex_buff[dtid.x * 3 + 2] = color.b; 35 | } 36 | -------------------------------------------------------------------------------- /Source/Base/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | set(aihi_base_files 5 | Include/Base/ComPtr.hpp 6 | Include/Base/Dll.hpp 7 | Include/Base/Enum.hpp 8 | Include/Base/Errorhandling.hpp 9 | Include/Base/MiniWindows.hpp 10 | Include/Base/Noncopyable.hpp 11 | Include/Base/SmartPtrHelper.hpp 12 | Include/Base/Timer.hpp 13 | Include/Base/Util.hpp 14 | Include/Base/Uuid.hpp 15 | Source/Dll.cpp 16 | Source/Errorhandling.cpp 17 | Source/pch.hpp 18 | Source/Timer.cpp 19 | Source/Util.cpp 20 | ) 21 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${aihi_base_files}) 22 | 23 | add_library(AIHoloImagerBase STATIC 24 | ${aihi_base_files} 25 | ) 26 | 27 | target_include_directories(AIHoloImagerBase 28 | PUBLIC 29 | Include 30 | 31 | PRIVATE 32 | ${CMAKE_CURRENT_SOURCE_DIR}/Source 33 | ) 34 | 35 | target_precompile_headers(AIHoloImagerBase 36 | PRIVATE 37 | Source/pch.hpp 38 | ) 39 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/D3D12/D3D12ImpDefine.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #define D3D12_DEFINE_IMP(ClassName) \ 7 | D3D12##ClassName& D3D12Imp(Gpu##ClassName& var); \ 8 | const D3D12##ClassName& D3D12Imp(const Gpu##ClassName& var); 9 | 10 | #define D3D12_IMP_IMP(ClassName) \ 11 | D3D12##ClassName& D3D12Imp(Gpu##ClassName& var) \ 12 | { \ 13 | return static_cast(var.Internal()); \ 14 | } \ 15 | \ 16 | const D3D12##ClassName& D3D12Imp(const Gpu##ClassName& var) \ 17 | { \ 18 | return static_cast(var.Internal()); \ 19 | } 20 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/GpuCommandPool.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Gpu/GpuCommandPool.hpp" 5 | 6 | #include "Internal/GpuCommandPoolInternal.hpp" 7 | #include "Internal/GpuSystemInternal.hpp" 8 | #include "InternalImp.hpp" 9 | 10 | namespace AIHoloImager 11 | { 12 | EMPTY_IMP(GpuCommandPool) 13 | IMP_INTERNAL(GpuCommandPool) 14 | 15 | GpuCommandPool::GpuCommandPool() noexcept = default; 16 | 17 | GpuCommandPool::GpuCommandPool(GpuSystem& gpu_system, GpuSystem::CmdQueueType type) 18 | : impl_(static_cast(gpu_system.Internal().CreateCommandPool(type).release())) 19 | { 20 | static_assert(sizeof(Impl) == sizeof(GpuCommandPoolInternal)); 21 | } 22 | 23 | GpuCommandPool::~GpuCommandPool() noexcept = default; 24 | 25 | GpuCommandPool::GpuCommandPool(GpuCommandPool&& other) noexcept = default; 26 | GpuCommandPool& GpuCommandPool::operator=(GpuCommandPool&& other) noexcept = default; 27 | } // namespace AIHoloImager 28 | -------------------------------------------------------------------------------- /Source/Lib/Source/Util/PerfProfiler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include "Base/NonCopyable.hpp" 10 | 11 | namespace AIHoloImager 12 | { 13 | class PerfRegion; 14 | 15 | class PerfProfiler final 16 | { 17 | friend class PerfRegion; 18 | 19 | DISALLOW_COPY_AND_ASSIGN(PerfProfiler); 20 | 21 | public: 22 | PerfProfiler(); 23 | ~PerfProfiler() noexcept; 24 | 25 | void Output(std::ostream& os) const; 26 | 27 | private: 28 | class Impl; 29 | std::unique_ptr impl_; 30 | }; 31 | 32 | class PerfRegion final 33 | { 34 | DISALLOW_COPY_AND_ASSIGN(PerfRegion); 35 | 36 | public: 37 | PerfRegion(PerfProfiler& profiler, std::string_view name); 38 | ~PerfRegion(); 39 | 40 | private: 41 | class Impl; 42 | std::unique_ptr impl_; 43 | }; 44 | } // namespace AIHoloImager 45 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanImpDefine.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #define VULKAN_DEFINE_IMP(ClassName) \ 7 | Vulkan##ClassName& VulkanImp(Gpu##ClassName& var); \ 8 | const Vulkan##ClassName& VulkanImp(const Gpu##ClassName& var); 9 | 10 | #define VULKAN_IMP_IMP(ClassName) \ 11 | Vulkan##ClassName& VulkanImp(Gpu##ClassName& var) \ 12 | { \ 13 | return static_cast(var.Internal()); \ 14 | } \ 15 | \ 16 | const Vulkan##ClassName& VulkanImp(const Gpu##ClassName& var) \ 17 | { \ 18 | return static_cast(var.Internal()); \ 19 | } 20 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuSamplerInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuSamplerInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuStaticSamplerInternal::GpuStaticSamplerInternal() noexcept = default; 9 | GpuStaticSamplerInternal::~GpuStaticSamplerInternal() = default; 10 | 11 | GpuStaticSamplerInternal::GpuStaticSamplerInternal(GpuStaticSamplerInternal&& other) noexcept = default; 12 | GpuStaticSamplerInternal& GpuStaticSamplerInternal::operator=(GpuStaticSamplerInternal&& other) noexcept = default; 13 | 14 | 15 | GpuDynamicSamplerInternal::GpuDynamicSamplerInternal() noexcept = default; 16 | GpuDynamicSamplerInternal::~GpuDynamicSamplerInternal() = default; 17 | 18 | GpuDynamicSamplerInternal::GpuDynamicSamplerInternal(GpuDynamicSamplerInternal&& other) noexcept = default; 19 | GpuDynamicSamplerInternal& GpuDynamicSamplerInternal::operator=(GpuDynamicSamplerInternal&& other) noexcept = default; 20 | } // namespace AIHoloImager 21 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuShaderInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuShaderInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuRenderPipelineInternal::GpuRenderPipelineInternal() noexcept = default; 9 | GpuRenderPipelineInternal::~GpuRenderPipelineInternal() = default; 10 | 11 | GpuRenderPipelineInternal::GpuRenderPipelineInternal(GpuRenderPipelineInternal&& other) noexcept = default; 12 | GpuRenderPipelineInternal& GpuRenderPipelineInternal::operator=(GpuRenderPipelineInternal&& other) noexcept = default; 13 | 14 | 15 | GpuComputePipelineInternal::GpuComputePipelineInternal() noexcept = default; 16 | GpuComputePipelineInternal::~GpuComputePipelineInternal() = default; 17 | 18 | GpuComputePipelineInternal::GpuComputePipelineInternal(GpuComputePipelineInternal&& other) noexcept = default; 19 | GpuComputePipelineInternal& GpuComputePipelineInternal::operator=(GpuComputePipelineInternal&& other) noexcept = default; 20 | } // namespace AIHoloImager 21 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/RasterizeFwdGs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | struct GsInput 5 | { 6 | float4 pos : POSITION; 7 | }; 8 | 9 | struct PsInput 10 | { 11 | float2 bc : TEXCOORD0; 12 | nointerpolation uint prim_id : PRIMITIVE_ID; 13 | #if ENABLE_DERIVATIVE_BC 14 | float4 position : TEXCOORD1; 15 | #endif 16 | float4 pos : SV_Position; 17 | }; 18 | 19 | [maxvertexcount(3)] 20 | void main(triangle GsInput input[3], 21 | uint32_t prim_id : SV_PrimitiveID, 22 | inout TriangleStream out_stream) 23 | { 24 | static const float2 Barycentric[] = {float2(1, 0), float2(0, 1), float2(0, 0)}; 25 | 26 | PsInput output; 27 | output.prim_id = prim_id + 1; 28 | for (uint32_t i = 0; i < 3; ++i) 29 | { 30 | output.pos = input[i].pos; 31 | output.bc = Barycentric[i]; 32 | #if ENABLE_DERIVATIVE_BC 33 | output.position = input[i].pos; 34 | #endif 35 | out_stream.Append(output); 36 | } 37 | out_stream.RestartStrip(); 38 | } 39 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/Shader/NormalizeImageCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t2 texture_size; 9 | }; 10 | 11 | Texture2D input_tex; 12 | Texture2D max_tex; 13 | 14 | RWTexture2D output_tex; 15 | 16 | [numthreads(BlockDim, BlockDim, 1)] 17 | void main(uint32_t3 dtid : SV_DispatchThreadID) 18 | { 19 | [branch] 20 | if (any(dtid.xy >= texture_size)) 21 | { 22 | return; 23 | } 24 | 25 | float3 color = input_tex.Load(uint3(dtid.xy, 0)).rgb; 26 | color /= max_tex.Load(uint3(0, 0, 0)) / 1e5f; 27 | 28 | static const float3 Mean = float3(0.485f, 0.456f, 0.406f); 29 | static const float3 Std = float3(0.229f, 0.224f, 0.225f); 30 | color = (color - Mean) / Std; 31 | 32 | output_tex[uint32_t2(dtid.x, dtid.y + 0 * texture_size.y)] = color.r; 33 | output_tex[uint32_t2(dtid.x, dtid.y + 1 * texture_size.y)] = color.g; 34 | output_tex[uint32_t2(dtid.x, dtid.y + 2 * texture_size.y)] = color.b; 35 | } 36 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanConversion.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "Gpu/GpuFormat.hpp" 11 | #include "Gpu/GpuResource.hpp" 12 | 13 | namespace AIHoloImager 14 | { 15 | VkFormat ToVkFormat(GpuFormat fmt); 16 | GpuFormat FromVkFormat(VkFormat fmt); 17 | 18 | VkMemoryPropertyFlags ToVulkanMemoryPropertyFlags(GpuHeap heap); 19 | GpuHeap FromVulkanMemoryPropertyFlags(VkMemoryPropertyFlags flags); 20 | 21 | VkImageUsageFlags ToVulkanImageUsageFlags(GpuResourceFlag flags) noexcept; 22 | GpuResourceFlag FromVulkanImageUsageFlags(VkImageUsageFlags flags) noexcept; 23 | 24 | VkImageLayout ToVulkanImageLayout(GpuResourceState state); 25 | 26 | VkImageType ToVulkanImageType(GpuResourceType type); 27 | 28 | std::tuple ToVulkanAccessFlags(VkImageLayout old_layout, VkImageLayout new_layout); 29 | 30 | VkImageAspectFlags ToVulkanAspectMask(GpuFormat fmt) noexcept; 31 | } // namespace AIHoloImager 32 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuBufferInternal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/Noncopyable.hpp" 7 | #include "Gpu/GpuBuffer.hpp" 8 | 9 | #include "GpuResourceInternal.hpp" 10 | 11 | namespace AIHoloImager 12 | { 13 | class GpuBufferInternal : public GpuResourceInternal 14 | { 15 | DISALLOW_COPY_AND_ASSIGN(GpuBufferInternal) 16 | 17 | public: 18 | GpuBufferInternal() noexcept; 19 | virtual ~GpuBufferInternal(); 20 | 21 | GpuBufferInternal(GpuBufferInternal&& other) noexcept; 22 | virtual GpuBufferInternal& operator=(GpuBufferInternal&& other) noexcept = 0; 23 | 24 | virtual void* NativeBuffer() const noexcept = 0; 25 | 26 | virtual GpuHeap Heap() const noexcept = 0; 27 | 28 | virtual uint32_t Size() const noexcept = 0; 29 | 30 | virtual void* Map(const GpuRange& read_range) = 0; 31 | virtual void* Map() = 0; 32 | virtual void Unmap(const GpuRange& write_range) = 0; 33 | virtual void Unmap() = 0; 34 | }; 35 | } // namespace AIHoloImager 36 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuSamplerInternal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/Noncopyable.hpp" 7 | 8 | namespace AIHoloImager 9 | { 10 | class GpuStaticSamplerInternal 11 | { 12 | DISALLOW_COPY_AND_ASSIGN(GpuStaticSamplerInternal) 13 | 14 | public: 15 | GpuStaticSamplerInternal() noexcept; 16 | virtual ~GpuStaticSamplerInternal(); 17 | 18 | GpuStaticSamplerInternal(GpuStaticSamplerInternal&& other) noexcept; 19 | virtual GpuStaticSamplerInternal& operator=(GpuStaticSamplerInternal&& other) noexcept = 0; 20 | }; 21 | 22 | class GpuDynamicSamplerInternal 23 | { 24 | DISALLOW_COPY_AND_ASSIGN(GpuDynamicSamplerInternal) 25 | 26 | public: 27 | GpuDynamicSamplerInternal() noexcept; 28 | virtual ~GpuDynamicSamplerInternal(); 29 | 30 | GpuDynamicSamplerInternal(GpuDynamicSamplerInternal&& other) noexcept; 31 | virtual GpuDynamicSamplerInternal& operator=(GpuDynamicSamplerInternal&& other) noexcept = 0; 32 | }; 33 | } // namespace AIHoloImager 34 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/DiffOptimizer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "AIHoloImager/Mesh.hpp" 9 | #include "AIHoloImagerInternal.hpp" 10 | #include "Base/Noncopyable.hpp" 11 | #include "SfM/StructureFromMotion.hpp" 12 | 13 | namespace AIHoloImager 14 | { 15 | class DiffOptimizer 16 | { 17 | DISALLOW_COPY_AND_ASSIGN(DiffOptimizer); 18 | 19 | public: 20 | explicit DiffOptimizer(AIHoloImagerInternal& aihi); 21 | DiffOptimizer(DiffOptimizer&& other) noexcept; 22 | ~DiffOptimizer() noexcept; 23 | 24 | DiffOptimizer& operator=(DiffOptimizer&& other) noexcept; 25 | 26 | void OptimizeTransform(const Mesh& mesh, glm::mat4x4& model_mtx, const StructureFromMotion::Result& sfm_input); 27 | void OptimizeTexture( 28 | Mesh& mesh, const glm::mat4x4& model_mtx, const StructureFromMotion::Result& sfm_input, const Texture& mask_tex); 29 | 30 | private: 31 | class Impl; 32 | std::unique_ptr impl_; 33 | }; 34 | } // namespace AIHoloImager 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Minmin Gong 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Source/Lib/Source/Util/BoundingBox.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace AIHoloImager 14 | { 15 | struct Aabb 16 | { 17 | glm::vec3 min{std::numeric_limits::max()}; 18 | glm::vec3 max{std::numeric_limits::lowest()}; 19 | 20 | void AddPoint(const glm::vec3& point); 21 | glm::vec3 Center() const; 22 | glm::vec3 Extents() const; 23 | glm::vec3 Size() const; 24 | 25 | static void GetCorners(const Aabb& aabb, std::span corners); 26 | }; 27 | 28 | struct Obb 29 | { 30 | glm::vec3 center; 31 | glm::vec3 extents; 32 | glm::quat orientation; 33 | 34 | static Obb FromPoints(const glm::vec3* positions, uint32_t stride, uint32_t num_vertices); 35 | static Obb Transform(const Obb& obb, const glm::mat4x4& mtx); 36 | static void GetCorners(const Obb& obb, std::span corners); 37 | }; 38 | } // namespace AIHoloImager 39 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/D3D12/D3D12Conversion.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/MiniWindows.hpp" 7 | 8 | #include 9 | #include 10 | 11 | #include "Gpu/GpuFormat.hpp" 12 | #include "Gpu/GpuResource.hpp" 13 | #include "Gpu/GpuShader.hpp" 14 | 15 | namespace AIHoloImager 16 | { 17 | DXGI_FORMAT ToDxgiFormat(GpuFormat fmt); 18 | GpuFormat FromDxgiFormat(DXGI_FORMAT fmt); 19 | 20 | D3D12_HEAP_TYPE ToD3D12HeapType(GpuHeap heap); 21 | GpuHeap FromD3D12HeapType(D3D12_HEAP_TYPE heap_type); 22 | 23 | D3D12_RESOURCE_FLAGS ToD3D12ResourceFlags(GpuResourceFlag flags) noexcept; 24 | GpuResourceFlag FromD3D12ResourceFlags(D3D12_RESOURCE_FLAGS flags) noexcept; 25 | 26 | D3D12_HEAP_FLAGS ToD3D12HeapFlags(GpuResourceFlag flags) noexcept; 27 | 28 | D3D12_RESOURCE_STATES ToD3D12ResourceState(GpuResourceState state); 29 | 30 | D3D12_RESOURCE_DIMENSION ToD3D12ResourceDimension(GpuResourceType type); 31 | 32 | D3D_PRIMITIVE_TOPOLOGY ToD3D12PrimitiveTopology(GpuRenderPipeline::PrimitiveTopology topology) noexcept; 33 | } // namespace AIHoloImager 34 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/MergeTextureCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | float4x4 inv_model; 9 | 10 | uint32_t texture_size; 11 | float inv_scale; 12 | }; 13 | 14 | Texture3D color_vol_tex; 15 | Texture2D pos_tex; 16 | 17 | SamplerState trilinear_sampler; 18 | 19 | #ifdef __spirv__ 20 | [[vk::image_format("rgba8")]] 21 | #endif 22 | RWTexture2D merged_tex; 23 | 24 | [numthreads(BlockDim, BlockDim, 1)] 25 | void main(uint32_t3 dtid : SV_DispatchThreadID) 26 | { 27 | [branch] 28 | if (any(dtid.xy >= texture_size)) 29 | { 30 | return; 31 | } 32 | 33 | [branch] 34 | if (merged_tex[dtid.xy].a > 0.5f) 35 | { 36 | return; 37 | } 38 | 39 | float4 pos_ws = pos_tex[dtid.xy]; 40 | [branch] 41 | if (pos_ws.a < 0.5f) 42 | { 43 | return; 44 | } 45 | 46 | float4 pos_os = mul(pos_ws, inv_model); 47 | pos_os /= pos_os.w; 48 | 49 | const float3 vol_coord = pos_os.zyx * inv_scale + 0.5f; 50 | merged_tex[dtid.xy] = saturate(color_vol_tex.SampleLevel(trilinear_sampler, vol_coord, 0)); 51 | } 52 | -------------------------------------------------------------------------------- /External/DirectXShaderCompiler/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | set(prebuilt_dxc_url "https://github.com/microsoft/DirectXShaderCompiler/releases/download/v1.8.2505.1/dxc_2025_07_14.zip") 5 | cmake_path(GET prebuilt_dxc_url FILENAME prebuilt_dxc_name) 6 | cmake_path(GET prebuilt_dxc_name STEM prebuilt_dxc_stem) 7 | 8 | set(prebuilt_dxc_tmp_dir "${CMAKE_CURRENT_SOURCE_DIR}/PrebuiltDxc") 9 | set(prebuilt_dxc_path "${prebuilt_dxc_tmp_dir}/${prebuilt_dxc_name}") 10 | if(NOT EXISTS ${prebuilt_dxc_path}) 11 | message(STATUS "Downloading prebuilt dxc package from ${prebuilt_dxc_url}") 12 | file(DOWNLOAD ${prebuilt_dxc_url} ${prebuilt_dxc_path} SHOW_PROGRESS) 13 | endif() 14 | 15 | set(prebuilt_dxc_dir "${prebuilt_dxc_tmp_dir}/${prebuilt_dxc_stem}") 16 | if (NOT EXISTS ${prebuilt_dxc_dir}) 17 | message(STATUS "Extracting prebuilt dxc package to ${prebuilt_dxc_dir}") 18 | file(ARCHIVE_EXTRACT INPUT "${prebuilt_dxc_path}" 19 | DESTINATION "${prebuilt_dxc_dir}" 20 | ) 21 | endif() 22 | 23 | set(aihi_dxc_cmd "${prebuilt_dxc_dir}/bin/x64/dxc.exe") 24 | cmake_path(ABSOLUTE_PATH aihi_dxc_cmd OUTPUT_VARIABLE aihi_dxc_cmd) 25 | set(AIHI_DXC_CMD ${aihi_dxc_cmd} CACHE INTERNAL "") 26 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuSystemInternalFactory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuSystemInternalFactory.hpp" 5 | 6 | #include "Base/ErrorHandling.hpp" 7 | 8 | #ifdef AIHI_ENABLE_D3D12 9 | #include "D3D12/D3D12System.hpp" 10 | #endif 11 | #ifdef AIHI_ENABLE_VULKAN 12 | #include "Vulkan/VulkanSystem.hpp" 13 | #endif 14 | 15 | namespace AIHoloImager 16 | { 17 | std::unique_ptr CreateGpuSystemInternal(GpuSystem::Api api, GpuSystem& gpu_system, 18 | std::function confirm_device, bool enable_sharing, bool enable_debug) 19 | { 20 | switch (api) 21 | { 22 | #ifdef AIHI_ENABLE_D3D12 23 | case GpuSystem::Api::D3D12: 24 | return std::make_unique(gpu_system, std::move(confirm_device), enable_sharing, enable_debug); 25 | #endif 26 | #ifdef AIHI_ENABLE_VULKAN 27 | case GpuSystem::Api::Vulkan: 28 | return std::make_unique(gpu_system, std::move(confirm_device), enable_sharing, enable_debug); 29 | #endif 30 | 31 | default: 32 | Unreachable("Invalid API"); 33 | } 34 | } 35 | } // namespace AIHoloImager 36 | -------------------------------------------------------------------------------- /Source/Lib/Include/AIHoloImager/AIHoloImager.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include "AIHoloImager/Mesh.hpp" 10 | 11 | namespace AIHoloImager 12 | { 13 | class AIHoloImager 14 | { 15 | public: 16 | enum class DeviceType 17 | { 18 | Cpu, 19 | Cuda, 20 | }; 21 | enum class Api 22 | { 23 | D3D12, 24 | Vulkan, 25 | 26 | Auto, 27 | }; 28 | 29 | public: 30 | AIHoloImager(DeviceType device, Api api, const std::filesystem::path& tmp_dir, bool gpu_debug = false); 31 | AIHoloImager(const AIHoloImager& rhs) = delete; 32 | AIHoloImager(AIHoloImager&& rhs) noexcept; 33 | ~AIHoloImager() noexcept; 34 | 35 | AIHoloImager& operator=(const AIHoloImager& rhs) = delete; 36 | AIHoloImager& operator=(AIHoloImager&& rhs) noexcept; 37 | 38 | Mesh Generate(const std::filesystem::path& input_path, uint32_t texture_size, bool no_delight = false); 39 | 40 | private: 41 | class Impl; 42 | std::unique_ptr impl_; 43 | }; 44 | } // namespace AIHoloImager 45 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/Shader/UpsampleCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #include "Lanczos.hlslh" 5 | 6 | static const uint32_t BlockDim = 16; 7 | static const uint32_t KernelRadius = 3; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t4 src_roi; 12 | uint32_t2 dest_size; 13 | float scale; 14 | bool x_dir; 15 | }; 16 | 17 | Texture2D input_tex; 18 | Texture2D min_max_tex; 19 | 20 | #ifdef __spirv__ 21 | [[vk::image_format("r8")]] 22 | #endif 23 | RWTexture2D output_tex; 24 | 25 | [numthreads(BlockDim, BlockDim, 1)] 26 | void main(uint32_t3 dtid : SV_DispatchThreadID) 27 | { 28 | [branch] 29 | if (any(dtid.xy >= dest_size)) 30 | { 31 | return; 32 | } 33 | 34 | float min_pred; 35 | float pred_scale; 36 | if (x_dir) 37 | { 38 | min_pred = min_max_tex.Load(uint32_t3(0, 0, 0)) / 1e5f; 39 | const float max_pred = min_max_tex.Load(uint32_t3(1, 0, 0)) / 1e5f; 40 | pred_scale = 1 / (max_pred - min_pred); 41 | } 42 | else 43 | { 44 | min_pred = 0; 45 | pred_scale = 1; 46 | } 47 | 48 | output_tex[dtid.xy] = LanczosResample(input_tex, dtid.xy, src_roi, scale, KernelRadius, x_dir, min_pred, pred_scale); 49 | } 50 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/MarchingCubes/CalcCubeIndicesCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #include "MarchingCubesUtil.hlslh" 5 | 6 | static const uint32_t BlockDim = 256; 7 | static const uint32_t MaxGroupDim = 65535; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t size; 12 | uint32_t total_cubes; 13 | float isovalue; 14 | }; 15 | 16 | #ifdef __spirv__ 17 | [[vk::image_format("r16ui")]] 18 | #endif 19 | Buffer edge_table; 20 | Texture3D scalar_deformation; 21 | 22 | RWBuffer cube_offsets; 23 | RWBuffer counter; 24 | 25 | [numthreads(BlockDim, 1, 1)] 26 | void main(uint32_t3 dtid : SV_DispatchThreadID) 27 | { 28 | const uint32_t cid = dtid.y * MaxGroupDim + dtid.x; 29 | 30 | [branch] 31 | if (cid >= total_cubes) 32 | { 33 | return; 34 | } 35 | 36 | const uint32_t3 coord = DecomposeCoord(cid, size); 37 | const uint32_t cube_index = CalcCubeIndex(scalar_deformation, coord, size, isovalue); 38 | 39 | if (edge_table[cube_index] != 0) 40 | { 41 | uint32_t addr; 42 | InterlockedAdd(counter[0], 1, addr); 43 | cube_offsets[cid] = addr; 44 | } 45 | else 46 | { 47 | cube_offsets[cid] = ~0U; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Norm.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/norm.py 5 | 6 | import torch 7 | import torch.nn as nn 8 | 9 | class LayerNorm32(nn.LayerNorm): 10 | def __init__(self, *args, **kwargs): 11 | super().__init__(*args, **kwargs) 12 | 13 | def forward(self, x: torch.Tensor) -> torch.Tensor: 14 | return super().forward(x.float()).type(x.dtype) 15 | 16 | class GroupNorm32(nn.GroupNorm): 17 | """ 18 | A GroupNorm layer that converts to float32 before the forward pass. 19 | """ 20 | 21 | def __init__(self, *args, **kwargs): 22 | super().__init__(*args, **kwargs) 23 | 24 | def forward(self, x: torch.Tensor) -> torch.Tensor: 25 | return super().forward(x.float()).type(x.dtype) 26 | 27 | class ChannelLayerNorm32(LayerNorm32): 28 | def __init__(self, *args, **kwargs): 29 | super().__init__(*args, **kwargs) 30 | 31 | def forward(self, x: torch.Tensor) -> torch.Tensor: 32 | dim = x.dim() 33 | x = x.permute(0, *range(2, dim), 1).contiguous() 34 | x = super().forward(x) 35 | x = x.permute(0, dim - 1, *range(1, dim - 1)).contiguous() 36 | return x 37 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuTextureInternal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/Noncopyable.hpp" 7 | #include "Gpu/GpuFormat.hpp" 8 | #include "Gpu/GpuResource.hpp" 9 | 10 | #include "GpuResourceInternal.hpp" 11 | 12 | namespace AIHoloImager 13 | { 14 | class GpuTextureInternal : public GpuResourceInternal 15 | { 16 | DISALLOW_COPY_AND_ASSIGN(GpuTextureInternal) 17 | 18 | public: 19 | GpuTextureInternal() noexcept; 20 | virtual ~GpuTextureInternal(); 21 | 22 | GpuTextureInternal(GpuTextureInternal&& other) noexcept; 23 | virtual GpuTextureInternal& operator=(GpuTextureInternal&& other) noexcept = 0; 24 | 25 | virtual void* NativeTexture() const noexcept = 0; 26 | 27 | virtual uint32_t Width(uint32_t mip) const noexcept = 0; 28 | virtual uint32_t Height(uint32_t mip) const noexcept = 0; 29 | virtual uint32_t Depth(uint32_t mip) const noexcept = 0; 30 | virtual uint32_t ArraySize() const noexcept = 0; 31 | virtual uint32_t MipLevels() const noexcept = 0; 32 | virtual uint32_t Planes() const noexcept = 0; 33 | virtual GpuFormat Format() const noexcept = 0; 34 | }; 35 | } // namespace AIHoloImager 36 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/TextureFwdCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #if ENABLE_MIP 5 | #include "Common.hlslh" 6 | #endif 7 | 8 | static const uint32_t BlockDim = 16; 9 | 10 | cbuffer param_cb 11 | { 12 | uint32_t2 gbuffer_size; 13 | uint32_t2 tex_size; 14 | uint32_t mip_levels; 15 | }; 16 | 17 | Texture2D prim_id_tex; 18 | Texture2D texture; 19 | Buffer uv_buff; 20 | #if ENABLE_MIP 21 | Buffer derivative_uv_buff; 22 | #endif 23 | 24 | RWTexture2D image; 25 | 26 | SamplerState tex_sampler : register(space1); 27 | 28 | [numthreads(BlockDim, BlockDim, 1)] 29 | void main(uint32_t3 dtid : SV_DispatchThreadID) 30 | { 31 | [branch] 32 | if (any(dtid.xy >= gbuffer_size)) 33 | { 34 | return; 35 | } 36 | 37 | uint32_t fi = prim_id_tex[dtid.xy]; 38 | [branch] 39 | if (fi == 0) 40 | { 41 | return; 42 | } 43 | 44 | const uint32_t index = dtid.y * gbuffer_size.x + dtid.x; 45 | const float2 uv = uv_buff[index]; 46 | #if ENABLE_MIP 47 | const float level = CalcMipLevel(derivative_uv_buff[index], tex_size, mip_levels); 48 | #else 49 | const float level = 0; 50 | #endif 51 | image[dtid.xy] = texture.SampleLevel(tex_sampler, uv, level); 52 | } 53 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | AccessModifierOffset: -4 2 | AlignAfterOpenBracket: DontAlign 3 | AlignEscapedNewlines: Left 4 | AllowAllParametersOfDeclarationOnNextLine: false 5 | AllowShortBlocksOnASingleLine: false 6 | AllowShortCaseLabelsOnASingleLine: false 7 | AllowShortFunctionsOnASingleLine: None 8 | AllowShortIfStatementsOnASingleLine: false 9 | AllowShortLoopsOnASingleLine: false 10 | AlwaysBreakTemplateDeclarations: true 11 | BreakBeforeBraces: Custom 12 | BraceWrapping: 13 | AfterCaseLabel: true 14 | AfterClass: true 15 | AfterControlStatement: true 16 | AfterEnum: true 17 | AfterFunction: true 18 | AfterNamespace: true 19 | AfterStruct: true 20 | AfterUnion: true 21 | AfterExternBlock: true 22 | BeforeCatch: true 23 | BeforeElse: true 24 | IndentBraces: false 25 | SplitEmptyFunction: true 26 | SplitEmptyRecord: true 27 | SplitEmptyNamespace: true 28 | BreakConstructorInitializers: BeforeColon 29 | ColumnLimit: 140 30 | Cpp11BracedListStyle: true 31 | IndentPPDirectives: BeforeHash 32 | IndentWidth: 4 33 | Language: Cpp 34 | MaxEmptyLinesToKeep: 2 35 | NamespaceIndentation: All 36 | PackConstructorInitializers: BinPack 37 | PointerAlignment: Left 38 | SpaceBeforeParens: ControlStatements 39 | Standard: Cpp11 40 | TabWidth: 4 41 | UseTab: Never 42 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuShaderInternal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/Noncopyable.hpp" 7 | #include "Gpu/GpuCommandList.hpp" 8 | 9 | namespace AIHoloImager 10 | { 11 | class GpuRenderPipelineInternal 12 | { 13 | DISALLOW_COPY_AND_ASSIGN(GpuRenderPipelineInternal) 14 | 15 | public: 16 | GpuRenderPipelineInternal() noexcept; 17 | virtual ~GpuRenderPipelineInternal(); 18 | 19 | GpuRenderPipelineInternal(GpuRenderPipelineInternal&& other) noexcept; 20 | virtual GpuRenderPipelineInternal& operator=(GpuRenderPipelineInternal&& other) noexcept = 0; 21 | 22 | virtual void Bind(GpuCommandList& cmd_list) const = 0; 23 | }; 24 | 25 | class GpuComputePipelineInternal 26 | { 27 | DISALLOW_COPY_AND_ASSIGN(GpuComputePipelineInternal) 28 | 29 | public: 30 | GpuComputePipelineInternal() noexcept; 31 | virtual ~GpuComputePipelineInternal(); 32 | 33 | GpuComputePipelineInternal(GpuComputePipelineInternal&& other) noexcept; 34 | virtual GpuComputePipelineInternal& operator=(GpuComputePipelineInternal&& other) noexcept = 0; 35 | 36 | virtual void Bind(GpuCommandList& cmd_list) const = 0; 37 | }; 38 | } // namespace AIHoloImager 39 | -------------------------------------------------------------------------------- /Source/Lib/Source/TextureRecon/TextureReconstruction.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "AIHoloImager/Mesh.hpp" 9 | #include "AIHoloImagerInternal.hpp" 10 | #include "Base/Noncopyable.hpp" 11 | #include "Gpu/GpuTexture.hpp" 12 | #include "SfM/StructureFromMotion.hpp" 13 | #include "Util/BoundingBox.hpp" 14 | 15 | namespace AIHoloImager 16 | { 17 | class TextureReconstruction 18 | { 19 | DISALLOW_COPY_AND_ASSIGN(TextureReconstruction); 20 | 21 | public: 22 | struct Result 23 | { 24 | GpuTexture2D color_tex; 25 | GpuTexture2D pos_tex; 26 | }; 27 | 28 | public: 29 | explicit TextureReconstruction(AIHoloImagerInternal& aihi); 30 | TextureReconstruction(TextureReconstruction&& other) noexcept; 31 | ~TextureReconstruction() noexcept; 32 | 33 | TextureReconstruction& operator=(TextureReconstruction&& other) noexcept; 34 | 35 | Result Process(const Mesh& mesh, const glm::mat4x4& model_mtx, const Obb& world_obb, const StructureFromMotion::Result& sfm_input, 36 | uint32_t texture_size); 37 | 38 | private: 39 | class Impl; 40 | std::unique_ptr impl_; 41 | }; 42 | } // namespace AIHoloImager 43 | -------------------------------------------------------------------------------- /External/Intrinsic/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | if(is_ci_env) 5 | set(copy_files ) 6 | else() 7 | set(copy_files 8 | stage_0.pt 9 | stage_1.pt 10 | stage_2.pt 11 | stage_3.pt 12 | ) 13 | endif() 14 | 15 | if(NOT is_ci_env) 16 | set(url "https://github.com/compphoto/Intrinsic/releases/download/v2.0/") 17 | set(local_dir "${CMAKE_CURRENT_SOURCE_DIR}/IntrinsicModels/") 18 | foreach(src_file ${copy_files}) 19 | DownloadFile("${url}${src_file}" "${local_dir}${src_file}") 20 | endforeach() 21 | endif() 22 | 23 | set(deployed_files ) 24 | 25 | foreach(src_file ${copy_files}) 26 | set(output_file ${aihi_output_dir}/Models/Intrinsic/${src_file}) 27 | set(src_file IntrinsicModels/${src_file}) 28 | add_custom_command(OUTPUT ${output_file} 29 | COMMAND ${CMAKE_COMMAND} -E create_hardlink ${src_file} ${output_file} 30 | COMMENT "Deploying ${src_file}..." 31 | DEPENDS ${src_file} 32 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 33 | VERBATIM COMMAND_EXPAND_LISTS 34 | ) 35 | 36 | list(APPEND deployed_files ${output_file}) 37 | endforeach() 38 | 39 | add_custom_target(DeployIntrinsicModels DEPENDS ${deployed_files}) 40 | 41 | set_target_properties(DeployIntrinsicModels PROPERTIES FOLDER "External") 42 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuResourceInternal.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/Noncopyable.hpp" 7 | #include "Gpu/GpuCommandList.hpp" 8 | #include "Gpu/GpuResource.hpp" 9 | 10 | namespace AIHoloImager 11 | { 12 | class GpuResourceInternal 13 | { 14 | DISALLOW_COPY_AND_ASSIGN(GpuResourceInternal) 15 | 16 | public: 17 | GpuResourceInternal() noexcept; 18 | virtual ~GpuResourceInternal(); 19 | 20 | GpuResourceInternal(GpuResourceInternal&& other) noexcept; 21 | virtual GpuResourceInternal& operator=(GpuResourceInternal&& other) noexcept = 0; 22 | 23 | virtual void Name(std::string_view name) = 0; 24 | 25 | virtual void* NativeResource() const noexcept = 0; 26 | 27 | virtual void Reset() = 0; 28 | 29 | virtual void* SharedHandle() const noexcept = 0; 30 | 31 | virtual GpuResourceType Type() const noexcept = 0; 32 | virtual GpuResourceFlag Flags() const noexcept = 0; 33 | virtual uint32_t AllocationSize() const noexcept = 0; 34 | 35 | virtual void Transition(GpuCommandList& cmd_list, uint32_t sub_resource, GpuResourceState target_state) const = 0; 36 | virtual void Transition(GpuCommandList& cmd_list, GpuResourceState target_state) const = 0; 37 | }; 38 | } // namespace AIHoloImager 39 | -------------------------------------------------------------------------------- /Source/SubMConv/Source/Torch/Shader/BuildCoordHashCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Common.hlslh" 5 | #include "Platform.hlslh" 6 | 7 | static const uint32_t BlockDim = 256; 8 | static const uint32_t MaxProbeTime = 1024; 9 | static const uint32_t Empty = ~0U; 10 | 11 | cbuffer param_cb 12 | { 13 | uint32_t num_coords; 14 | uint32_t hash_size; 15 | }; 16 | 17 | Buffer coords_buff; 18 | 19 | RWBuffer hash_table; 20 | 21 | [numthreads(BlockDim, 1, 1)] 22 | void main(uint32_t3 dtid : SV_DispatchThreadID) 23 | { 24 | [branch] 25 | if (dtid.x >= num_coords) 26 | { 27 | return; 28 | } 29 | 30 | const uint32_t4 coord = coords_buff[dtid.x]; // (B, z, y, x) 31 | 32 | uint32_t slot = HashFunc(coord) % hash_size; 33 | 34 | ALLOW_UAV_CONDITION 35 | for (uint32_t t = 0; t < MaxProbeTime; ++t) 36 | { 37 | uint32_t ori_val; 38 | InterlockedCompareExchange(hash_table[slot * 5 + 0], Empty, coord.x, ori_val); 39 | if (ori_val == Empty) 40 | { 41 | hash_table[slot * 5 + 1] = coord.y; 42 | hash_table[slot * 5 + 2] = coord.z; 43 | hash_table[slot * 5 + 3] = coord.w; 44 | hash_table[slot * 5 + 4] = dtid.x; 45 | break; 46 | } 47 | 48 | slot = (slot + 1) % hash_size; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Source/Lib/Include/AIHoloImager/Texture.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "AIHoloImager/ElementFormat.hpp" 11 | 12 | namespace AIHoloImager 13 | { 14 | class Texture 15 | { 16 | public: 17 | Texture(); 18 | Texture(uint32_t width, uint32_t height, ElementFormat format); 19 | Texture(const Texture& rhs); 20 | Texture(Texture&& rhs) noexcept; 21 | ~Texture() noexcept; 22 | 23 | Texture& operator=(const Texture& rhs); 24 | Texture& operator=(Texture&& rhs) noexcept; 25 | 26 | bool Valid() const noexcept; 27 | 28 | uint32_t Width() const noexcept; 29 | uint32_t Height() const noexcept; 30 | ElementFormat Format() const noexcept; 31 | 32 | std::byte* Data() noexcept; 33 | const std::byte* Data() const noexcept; 34 | uint32_t DataSize() const noexcept; 35 | 36 | Texture Convert(ElementFormat format) const; 37 | void ConvertInPlace(ElementFormat format); 38 | 39 | private: 40 | class Impl; 41 | std::unique_ptr impl_; 42 | }; 43 | 44 | Texture LoadTexture(const std::filesystem::path& path); 45 | void SaveTexture(const Texture& tex, const std::filesystem::path& path); 46 | } // namespace AIHoloImager 47 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/DilateCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t texture_size; 9 | }; 10 | 11 | Texture2D input_tex; 12 | 13 | #ifdef __spirv__ 14 | [[vk::image_format("rgba8")]] 15 | #endif 16 | RWTexture2D dilated_tex; 17 | 18 | [numthreads(BlockDim, BlockDim, 1)] 19 | void main(uint32_t3 dtid : SV_DispatchThreadID) 20 | { 21 | [branch] 22 | if (any(dtid.xy >= texture_size)) 23 | { 24 | return; 25 | } 26 | 27 | float4 curr = input_tex.Load(uint32_t3(dtid.xy, 0)); 28 | 29 | [branch] 30 | if (curr.a > 0) 31 | { 32 | dilated_tex[dtid.xy] = curr; 33 | return; 34 | } 35 | 36 | float4 sum = 0; 37 | for (int dy = -1; dy <= 1; ++dy) 38 | { 39 | for (int dx = -1; dx <= 1; ++dx) 40 | { 41 | int2 coord = dtid.xy + int2(dx, dy); 42 | if (all(bool4(coord >= 0, coord < texture_size))) 43 | { 44 | float4 color = input_tex.Load(uint32_t3(coord, 0)); 45 | if (color.a > 0) 46 | { 47 | sum += float4(color.rgb, 1); 48 | } 49 | } 50 | } 51 | } 52 | 53 | if (sum.a > 0) 54 | { 55 | sum.rgb /= sum.a; 56 | } 57 | 58 | dilated_tex[dtid.xy] = sum; 59 | } 60 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/GpuConstantBuffer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Gpu/GpuConstantBuffer.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuConstantBuffer::GpuConstantBuffer() noexcept = default; 9 | GpuConstantBuffer::GpuConstantBuffer(GpuSystem& gpu_system, uint32_t size, std::string_view name) 10 | : gpu_system_(&gpu_system), mem_block_(gpu_system.AllocUploadMemBlock(size, gpu_system.ConstantDataAlignment())), 11 | name_(std::move(name)) 12 | { 13 | } 14 | 15 | GpuConstantBuffer::~GpuConstantBuffer() 16 | { 17 | if ((gpu_system_ != nullptr) && mem_block_) 18 | { 19 | gpu_system_->DeallocUploadMemBlock(std::move(mem_block_)); 20 | } 21 | } 22 | 23 | GpuConstantBuffer::GpuConstantBuffer(GpuConstantBuffer&& other) noexcept = default; 24 | GpuConstantBuffer& GpuConstantBuffer::operator=(GpuConstantBuffer&& other) noexcept = default; 25 | 26 | GpuConstantBuffer::operator bool() const noexcept 27 | { 28 | return mem_block_ ? true : false; 29 | } 30 | 31 | const GpuMemoryBlock& GpuConstantBuffer::MemBlock() const noexcept 32 | { 33 | return mem_block_; 34 | } 35 | 36 | void* GpuConstantBuffer::NativeResource() const noexcept 37 | { 38 | return mem_block_ ? mem_block_.Buffer()->NativeBuffer() : nullptr; 39 | } 40 | } // namespace AIHoloImager 41 | -------------------------------------------------------------------------------- /Source/GpuSystem/Include/Gpu/GpuVertexLayout.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "Gpu/GpuFormat.hpp" 12 | #include "Gpu/InternalDefine.hpp" 13 | 14 | namespace AIHoloImager 15 | { 16 | struct GpuVertexAttrib 17 | { 18 | static constexpr uint32_t AppendOffset = ~0U; 19 | 20 | std::string semantic; 21 | uint32_t semantic_index; 22 | GpuFormat format; 23 | uint32_t slot = 0; 24 | uint32_t offset = AppendOffset; 25 | }; 26 | 27 | class GpuSystem; 28 | class GpuVertexLayoutInternal; 29 | 30 | class GpuVertexLayout 31 | { 32 | DEFINE_INTERNAL(GpuVertexLayout) 33 | 34 | public: 35 | GpuVertexLayout() noexcept; 36 | GpuVertexLayout(GpuSystem& gpu_system, std::span attribs, std::span slot_strides = {}); 37 | ~GpuVertexLayout() noexcept; 38 | 39 | GpuVertexLayout(const GpuVertexLayout& other); 40 | GpuVertexLayout& operator=(const GpuVertexLayout& other); 41 | 42 | GpuVertexLayout(GpuVertexLayout&& other) noexcept; 43 | GpuVertexLayout& operator=(GpuVertexLayout&& other) noexcept; 44 | 45 | private: 46 | class Impl; 47 | std::unique_ptr impl_; 48 | }; 49 | } // namespace AIHoloImager 50 | -------------------------------------------------------------------------------- /CMake/Modules/Platform.cmake: -------------------------------------------------------------------------------- 1 | if(WIN32) 2 | if(MSVC AND (CMAKE_GENERATOR MATCHES "^Visual Studio")) 3 | if((CMAKE_GENERATOR_PLATFORM STREQUAL "x64") OR (CMAKE_GENERATOR MATCHES "Win64") OR (CMAKE_GENERATOR_PLATFORM STREQUAL "")) 4 | set(ai_holo_imager_arch_name "x64") 5 | else() 6 | message(FATAL_ERROR "This CPU architecture is not supported") 7 | endif() 8 | endif() 9 | set(ai_holo_imager_platform_name "win") 10 | set(ai_holo_imager_platform_windows TRUE) 11 | endif() 12 | 13 | if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") 14 | set(ai_holo_imager_host_platform_name "win") 15 | set(ai_holo_imager_host_platform_windows TRUE) 16 | endif() 17 | 18 | if(NOT ai_holo_imager_arch_name) 19 | if((CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64") OR (CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")) 20 | set(ai_holo_imager_arch_name "x64") 21 | else() 22 | set(ai_holo_imager_arch_name "x86") 23 | endif() 24 | endif() 25 | 26 | if((CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64") OR (CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")) 27 | set(ai_holo_imager_host_arch_name "x64") 28 | else() 29 | set(ai_holo_imager_host_arch_name "x86") 30 | endif() 31 | 32 | set(ai_holo_imager_platform_name ${ai_holo_imager_platform_name}_${ai_holo_imager_arch_name}) 33 | set(ai_holo_imager_host_platform_name ${ai_holo_imager_host_platform_name}_${ai_holo_imager_host_arch_name}) 34 | -------------------------------------------------------------------------------- /External/U-2-Net/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | if(is_ci_env) 5 | add_custom_target(DeployU2NetModels) 6 | else() 7 | set(u2net_pth_file "${CMAKE_CURRENT_SOURCE_DIR}/U2NetModels/u2net.pth") 8 | set(u2netp_pth_file "${CMAKE_CURRENT_SOURCE_DIR}/U2NetModels/u2netp.pth") 9 | if((NOT EXISTS ${u2net_pth_file}) OR (NOT EXISTS ${u2netp_pth_file})) 10 | execute_process( 11 | COMMAND DownloadGd.bat 12 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 13 | ) 14 | endif() 15 | 16 | set(deployed_files ) 17 | foreach(pth_file ${u2net_pth_file} ${u2netp_pth_file}) 18 | get_filename_component(pth_file_name ${pth_file} NAME) 19 | set(output_file "${aihi_output_dir}/Models/U-2-Net/${pth_file_name}") 20 | add_custom_command(OUTPUT ${output_file} 21 | COMMAND ${CMAKE_COMMAND} -E create_hardlink ${pth_file} ${output_file} 22 | COMMENT "Deploying ${pth_file}..." 23 | DEPENDS ${pth_file} 24 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 25 | VERBATIM COMMAND_EXPAND_LISTS 26 | ) 27 | 28 | list(APPEND deployed_files ${output_file}) 29 | endforeach() 30 | 31 | add_custom_target(DeployU2NetModels DEPENDS ${deployed_files}) 32 | add_dependencies(DeployU2NetModels DeployPython) 33 | endif() 34 | 35 | set_target_properties(DeployU2NetModels PROPERTIES FOLDER "External") 36 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - stage: CodeFormatting 3 | jobs: 4 | - job: CodeFormatting 5 | pool: 6 | vmImage: Ubuntu-24.04 7 | 8 | steps: 9 | - script: | 10 | clang-format --version 11 | find . -iname "*.hpp" -o -iname "*.cpp" | xargs clang-format -i 12 | git diff --exit-code $(Build.SourceVersion) 13 | failOnStderr: true 14 | displayName: 'Check code formatting' 15 | 16 | - stage: Build 17 | condition: succeeded('CodeFormatting') 18 | jobs: 19 | - job: Build 20 | strategy: 21 | matrix: 22 | Windows_vc143_Debug: 23 | configuration: Debug 24 | Windows_vc143_Release: 25 | configuration: Release 26 | 27 | pool: 28 | vmImage: windows-2025 29 | 30 | steps: 31 | - checkout: self 32 | fetchDepth: 1 33 | 34 | - bash: | 35 | choco install ninja 36 | displayName: 'Install' 37 | 38 | - bash: | 39 | git config --global user.email "dummy@example.com" 40 | git config --global user.name "Dummy Name" 41 | displayName: 'Config git' 42 | 43 | - script: | 44 | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 45 | cmake -B Build -G Ninja . -DCMAKE_BUILD_TYPE=$(configuration) -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl 46 | cmake --build Build -j 47 | displayName: 'Build' 48 | -------------------------------------------------------------------------------- /Source/Lib/Source/SfM/ConvertDatasheet.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | import struct 5 | import sys 6 | 7 | def ParseDatabase(file_path): 8 | database = {} 9 | try: 10 | with open(file_path, "r") as file: 11 | for line in file: 12 | line = line.strip() 13 | if line and (not line[0] == "#"): 14 | splitted = line.split(";") 15 | if len(splitted) == 2: 16 | model, sensor_size = splitted 17 | database[model] = float(sensor_size) 18 | return database 19 | except ValueError as e: 20 | print(f"Error: Invalid data format in file. {e}") 21 | return {} 22 | except Exception as e: 23 | print(f"Error: An unexpected error occurred. {e}") 24 | return {} 25 | 26 | def WriteToBinary(database, file_path): 27 | try: 28 | with open(file_path, "wb") as file: 29 | file.write(struct.pack(" dilated_tex; 17 | 18 | [numthreads(BlockDim, BlockDim, 1)] 19 | void main(uint32_t3 dtid : SV_DispatchThreadID) 20 | { 21 | [branch] 22 | if (any(dtid >= texture_size)) 23 | { 24 | return; 25 | } 26 | 27 | float4 curr = input_tex.Load(uint32_t4(dtid, 0)); 28 | 29 | [branch] 30 | if (curr.a > 0) 31 | { 32 | dilated_tex[dtid] = curr; 33 | return; 34 | } 35 | 36 | float4 sum = 0; 37 | for (int dz = -1; dz <= 1; ++dz) 38 | { 39 | for (int dy = -1; dy <= 1; ++dy) 40 | { 41 | for (int dx = -1; dx <= 1; ++dx) 42 | { 43 | int3 coord = dtid + int3(dx, dy, dz); 44 | if (all(coord >= 0) && all(coord < texture_size)) 45 | { 46 | float4 color = input_tex.Load(uint32_t4(coord, 0)); 47 | if (color.a > 0) 48 | { 49 | sum += float4(color.rgb, 1); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | 56 | if (sum.a > 0) 57 | { 58 | sum.rgb /= sum.a; 59 | } 60 | 61 | dilated_tex[dtid] = sum; 62 | } 63 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Sparse/Norm.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/sparse/norm.py 5 | 6 | from typing import Optional 7 | 8 | import torch 9 | import torch.nn as nn 10 | 11 | from . import SparseTensor 12 | 13 | __all__ = [ 14 | "SparseGroupNorm", 15 | "SparseGroupNorm32", 16 | ] 17 | 18 | class SparseGroupNorm(nn.GroupNorm): 19 | def __init__(self, num_groups, num_channels, eps = 1e-5, affine = True, device: Optional[torch.device] = None): 20 | super(SparseGroupNorm, self).__init__(num_groups, num_channels, eps, affine, device = device) 21 | 22 | def forward(self, input: SparseTensor) -> SparseTensor: 23 | nfeats = torch.zeros_like(input.feats) 24 | for k in range(input.shape[0]): 25 | bfeats = input.feats[input.layout[k]] 26 | bfeats = bfeats.permute(1, 0).reshape(1, input.shape[1], -1) 27 | bfeats = super().forward(bfeats) 28 | bfeats = bfeats.reshape(input.shape[1], -1).permute(1, 0) 29 | nfeats[input.layout[k]] = bfeats 30 | return input.replace(nfeats) 31 | 32 | class SparseGroupNorm32(SparseGroupNorm): 33 | """ 34 | A GroupNorm layer that converts to float32 before the forward pass. 35 | """ 36 | 37 | def __init__(self, *args, **kwargs): 38 | super().__init__(*args, **kwargs) 39 | 40 | def forward(self, x: SparseTensor) -> SparseTensor: 41 | return super().forward(x.float()).type(x.dtype) 42 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/AccumGradMipsCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Common.hlslh" 5 | 6 | static const uint32_t BlockDim = 16; 7 | 8 | cbuffer param_cb 9 | { 10 | uint32_t2 tex_size; 11 | uint32_t num_channels; 12 | uint32_t mip_levels; 13 | uint32_t4 mip_level_offsets[4]; 14 | }; 15 | 16 | Buffer grad_texture_mips; 17 | 18 | RWBuffer grad_texture; 19 | 20 | [numthreads(BlockDim, BlockDim, 1)] 21 | void main(uint32_t3 dtid : SV_DispatchThreadID) 22 | { 23 | [branch] 24 | if (any(dtid.xy >= tex_size)) 25 | { 26 | return; 27 | } 28 | 29 | // Fig 2 (c) 30 | 31 | float4 accum = 0; 32 | const uint32_t mip0_texels = tex_size.x * tex_size.y; 33 | for (uint32_t level = 0; level < mip_levels; ++level) 34 | { 35 | const uint32_t2 level_size = MipLevelSize(tex_size, level); 36 | const float weight = float(level_size.x * level_size.y) / mip0_texels; 37 | 38 | const uint32_t2 coord = dtid.xy >> level; 39 | const uint32_t offset = MipLevelOffset(mip_level_offsets, level) + (coord.y * level_size.x + coord.x) * num_channels; 40 | for (uint32_t i = 0; i < num_channels; ++i) 41 | { 42 | accum[i] += grad_texture_mips[offset + i] * weight; 43 | } 44 | } 45 | 46 | const uint32_t output_offset = (dtid.y * tex_size.x + dtid.x) * num_channels; 47 | for (uint32_t i = 0; i < num_channels; ++i) 48 | { 49 | grad_texture[output_offset + i] = accum[i]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Source/TensorConverter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | set(aihi_tensor_converter_files 5 | Include/TensorConverter/TensorConverter.hpp 6 | Source/MiniCudaRt.cpp 7 | Source/MiniCudaRt.hpp 8 | Source/TensorConverter.cpp 9 | Source/pch.hpp 10 | ) 11 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${aihi_tensor_converter_files}) 12 | 13 | add_library(AIHoloImagerTensorConverter SHARED 14 | ${aihi_tensor_converter_files} 15 | ) 16 | 17 | set(torch_dir ${PROJECT_SOURCE_DIR}/External/PythonVenv/PythonVenv/Lib/site-packages/torch) 18 | 19 | target_include_directories(AIHoloImagerTensorConverter 20 | PUBLIC 21 | Include 22 | ${torch_dir}/include 23 | ${torch_dir}/include/torch/csrc/api/include 24 | 25 | PRIVATE 26 | ${CMAKE_CURRENT_SOURCE_DIR}/Source 27 | ) 28 | 29 | target_precompile_headers(AIHoloImagerTensorConverter 30 | PRIVATE 31 | Source/pch.hpp 32 | ) 33 | 34 | if(MSVC) 35 | target_compile_options(AIHoloImagerTensorConverter 36 | PRIVATE 37 | /wd4702 # Ignore unreachable code in PyTorch 38 | ) 39 | endif() 40 | 41 | target_link_directories(AIHoloImagerTensorConverter 42 | PRIVATE 43 | ${torch_dir}/lib 44 | ) 45 | 46 | target_link_libraries(AIHoloImagerTensorConverter 47 | PUBLIC 48 | AIHoloImagerBase 49 | AIHoloImagerGpuSystem 50 | 51 | PRIVATE 52 | c10.lib 53 | torch_cpu.lib 54 | torch.lib 55 | torch_python.lib 56 | Python3::Python 57 | ) 58 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Sparse/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/sparse/__init__.py 5 | 6 | import importlib 7 | from typing import * 8 | 9 | __attributes = { 10 | "SparseTensor": "Basic", 11 | "SparseBatchBroadcast": "Basic", 12 | "SparseUnbind": "Basic", 13 | "SparseGroupNorm": "Norm", 14 | "SparseGroupNorm32": "Norm", 15 | "SparseSiLU": "Nonlinearity", 16 | "SparseGELU": "Nonlinearity", 17 | "SparseLinear": "Linear", 18 | "SparseScaledDotProductAttention": "Attention", 19 | "SparseWindowedScaledDotProductSelfAttention": "Attention", 20 | "SparseMultiHeadAttention": "Attention", 21 | "SparseConv3D": "Conv", 22 | "SparseDownsample": "Spatial", 23 | "SparseUpsample": "Spatial", 24 | "SparseSubdivide" : "Spatial" 25 | } 26 | 27 | __submodules = ["Transformer"] 28 | 29 | __all__ = list(__attributes.keys()) + __submodules 30 | 31 | def __getattr__(name): 32 | if name not in globals(): 33 | if name in __attributes: 34 | module_name = __attributes[name] 35 | module = importlib.import_module(f".{module_name}", __name__) 36 | globals()[name] = getattr(module, name) 37 | elif name in __submodules: 38 | module = importlib.import_module(f".{name}", __name__) 39 | globals()[name] = module 40 | else: 41 | raise AttributeError(f"module {__name__} has no attribute {name}") 42 | return globals()[name] 43 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/AntiAliasConstructOppoVertHashCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Common.hlslh" 5 | #include "Platform.hlslh" 6 | 7 | static const uint32_t BlockDim = 256; 8 | static const uint32_t MaxProbeTime = 256; 9 | 10 | cbuffer param_cb 11 | { 12 | uint32_t num_indices; 13 | uint32_t hash_size; 14 | }; 15 | 16 | Buffer indices_buff; 17 | 18 | RWBuffer hash_table; 19 | 20 | [numthreads(BlockDim, 1, 1)] 21 | void main(uint32_t3 dtid : SV_DispatchThreadID) 22 | { 23 | [branch] 24 | if (dtid.x >= num_indices) 25 | { 26 | return; 27 | } 28 | 29 | const uint32_t face_id = dtid.x / 3; 30 | const uint32_t index = dtid.x - face_id * 3; 31 | 32 | uint32_t2 edge = uint32_t2(indices_buff[face_id * 3 + ((index + 1) % 3)], indices_buff[face_id * 3 + ((index + 2) % 3)]); 33 | if (edge.y < edge.x) 34 | { 35 | Swap(edge.x, edge.y); 36 | } 37 | 38 | uint32_t slot = HashFunc(edge) % hash_size; 39 | const uint32_t this_vertex = indices_buff[face_id * 3 + index]; 40 | 41 | ALLOW_UAV_CONDITION 42 | for (uint32_t t = 0; t < MaxProbeTime; ++t) 43 | { 44 | uint32_t ori_val; 45 | InterlockedCompareExchange(hash_table[slot * 3 + 0], ~0U, edge.x, ori_val); 46 | if (ori_val == ~0U) 47 | { 48 | hash_table[slot * 3 + 1] = edge.y; 49 | hash_table[slot * 3 + 2] = this_vertex; 50 | break; 51 | } 52 | 53 | slot = (slot + 1) % hash_size; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /External/MoGe/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | if(is_ci_env) 5 | add_custom_target(DeployMoGeModels) 6 | else() 7 | if(DEFINED ENV{GIT_LFS_SKIP_SMUDGE}) 8 | set(lfs_skip "$ENV{GIT_LFS_SKIP_SMUDGE}") 9 | else() 10 | set(lfs_skip 0) 11 | endif() 12 | 13 | set(ENV{GIT_LFS_SKIP_SMUDGE} 1) 14 | UpdateExternalLib(NAME "moge-vitl" 15 | URL "https://huggingface.co/Ruicheng/moge-vitl" 16 | REV "979e84da9415762c30e6c0cf8dc0962896c793df" 17 | NEED_CHECKOUT need_checkout 18 | ) 19 | set(ENV{GIT_LFS_SKIP_SMUDGE} ${lfs_skip}) 20 | 21 | if(need_checkout) 22 | PullLfsFile("moge-vitl" "model.pt") 23 | endif() 24 | 25 | set(deployed_files ) 26 | 27 | set(copy_files 28 | model.pt 29 | ) 30 | foreach(src_file ${copy_files}) 31 | set(src_file moge-vitl/${src_file}) 32 | set(output_file ${aihi_output_dir}/Models/${src_file}) 33 | add_custom_command(OUTPUT ${output_file} 34 | COMMAND ${CMAKE_COMMAND} -E create_hardlink ${src_file} ${output_file} 35 | COMMENT "Deploying ${src_file}..." 36 | DEPENDS ${src_file} 37 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 38 | VERBATIM COMMAND_EXPAND_LISTS 39 | ) 40 | 41 | list(APPEND deployed_files ${output_file}) 42 | endforeach() 43 | 44 | add_custom_target(DeployMoGeModels DEPENDS ${output_file}) 45 | endif() 46 | 47 | set_target_properties(DeployMoGeModels PROPERTIES FOLDER "External") 48 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/MarchingCubes/MarchingCubesUtil.hlslh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | uint32_t3 CalcCoord(uint32_t3 coord, uint32_t size) 7 | { 8 | return min(coord, size - 1).zyx; 9 | } 10 | 11 | uint32_t3 DecomposeCoord(uint32_t index, uint32_t size) 12 | { 13 | const uint32_t xy = index / size; 14 | const uint32_t z = index - xy * size; 15 | const uint32_t x = xy / size; 16 | const uint32_t y = xy - x * size; 17 | return uint32_t3(x, y, z); 18 | }; 19 | 20 | uint32_t CalcCubeIndex(Texture3D scalar_deformation, uint32_t3 coord, uint32_t size, float isovalue) 21 | { 22 | const float scalars[] = { 23 | scalar_deformation[CalcCoord(coord + uint32_t3(0, 0, 0), size)].x, 24 | scalar_deformation[CalcCoord(coord + uint32_t3(1, 0, 0), size)].x, 25 | scalar_deformation[CalcCoord(coord + uint32_t3(1, 1, 0), size)].x, 26 | scalar_deformation[CalcCoord(coord + uint32_t3(0, 1, 0), size)].x, 27 | scalar_deformation[CalcCoord(coord + uint32_t3(0, 0, 1), size)].x, 28 | scalar_deformation[CalcCoord(coord + uint32_t3(1, 0, 1), size)].x, 29 | scalar_deformation[CalcCoord(coord + uint32_t3(1, 1, 1), size)].x, 30 | scalar_deformation[CalcCoord(coord + uint32_t3(0, 1, 1), size)].x, 31 | }; 32 | 33 | uint32_t cube_index = 0; 34 | for (uint32_t m = 0; m < sizeof(scalars) / sizeof(scalars[0]); ++m) 35 | { 36 | if (scalars[m] <= isovalue) 37 | { 38 | cube_index |= 1U << m; 39 | } 40 | } 41 | 42 | return cube_index; 43 | } 44 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanCommandPool.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "Gpu/GpuCommandPool.hpp" 11 | #include "Gpu/GpuSystem.hpp" 12 | 13 | #include "../GpuCommandPoolInternal.hpp" 14 | #include "VulkanImpDefine.hpp" 15 | #include "VulkanUtil.hpp" 16 | 17 | namespace AIHoloImager 18 | { 19 | class VulkanCommandPool : public GpuCommandPoolInternal 20 | { 21 | public: 22 | VulkanCommandPool(GpuSystem& gpu_system, GpuSystem::CmdQueueType type); 23 | ~VulkanCommandPool() noexcept override; 24 | 25 | VulkanCommandPool(VulkanCommandPool&& other) noexcept; 26 | explicit VulkanCommandPool(GpuCommandPoolInternal&& other) noexcept; 27 | VulkanCommandPool& operator=(VulkanCommandPool&& other) noexcept; 28 | GpuCommandPoolInternal& operator=(GpuCommandPoolInternal&& other) noexcept override; 29 | 30 | VkCommandPool CmdPool() const noexcept; 31 | 32 | uint64_t FenceValue() const noexcept; 33 | void FenceValue(uint64_t value) noexcept; 34 | 35 | void RegisterAllocatedCommandBuffer(VkCommandBuffer cmd_buff); 36 | void UnregisterAllocatedCommandBuffer(VkCommandBuffer cmd_buff); 37 | bool EmptyAllocatedCommandBuffers() const noexcept; 38 | 39 | private: 40 | VulkanRecyclableObject cmd_pool_; 41 | uint64_t fence_val_ = 0; 42 | 43 | std::list allocated_cmd_buffs_; 44 | }; 45 | 46 | VULKAN_DEFINE_IMP(CommandPool) 47 | } // namespace AIHoloImager 48 | -------------------------------------------------------------------------------- /Source/SubMConv/Source/Torch/Shader/FindAvailableNeighborsCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Common.hlslh" 5 | 6 | static const uint32_t BlockDim = 256; 7 | static const uint32_t MaxProbeTime = 1024; 8 | static const uint32_t Empty = ~0U; 9 | 10 | cbuffer param_cb 11 | { 12 | uint32_t num_offsets; 13 | uint32_t num_coords; 14 | uint32_t hash_size; 15 | }; 16 | 17 | Buffer coords_buff; 18 | Buffer hash_table; 19 | Buffer offsets_buff; 20 | 21 | RWBuffer nei_indices; 22 | RWBuffer nei_indices_count; 23 | 24 | [numthreads(BlockDim, 1, 1)] 25 | void main(uint32_t3 dtid : SV_DispatchThreadID) 26 | { 27 | [branch] 28 | if (dtid.x >= num_coords) 29 | { 30 | return; 31 | } 32 | 33 | const uint32_t4 coord = asuint(asint(coords_buff[dtid.x]) + int32_t4(0, offsets_buff[dtid.y])); // (B, z, y, x) 34 | 35 | uint32_t slot = HashFunc(coord) % hash_size; 36 | 37 | for (uint32_t t = 0; t < MaxProbeTime; ++t) 38 | { 39 | if (hash_table[slot * 5 + 0] == Empty) 40 | { 41 | break; 42 | } 43 | else if ((hash_table[slot * 5 + 0] == coord.x) && (hash_table[slot * 5 + 1] == coord.y) && (hash_table[slot * 5 + 2] == coord.z) && (hash_table[slot * 5 + 3] == coord.w)) 44 | { 45 | uint32_t addr; 46 | InterlockedAdd(nei_indices_count[dtid.y], 1, addr); 47 | nei_indices[dtid.y * num_coords + addr] = uint32_t2(dtid.x, hash_table[slot * 5 + 4]); 48 | break; 49 | } 50 | 51 | slot = (slot + 1) % hash_size; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanResource.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/SmartPtrHelper.hpp" 7 | #include "Gpu/GpuResource.hpp" 8 | 9 | #include "VulkanCommandList.hpp" 10 | #include "VulkanImpDefine.hpp" 11 | #include "VulkanUtil.hpp" 12 | 13 | namespace AIHoloImager 14 | { 15 | class VulkanResource 16 | { 17 | public: 18 | explicit VulkanResource(GpuSystem& gpu_system); 19 | virtual ~VulkanResource(); 20 | 21 | VulkanResource(VulkanResource&& other) noexcept; 22 | VulkanResource& operator=(VulkanResource&& other) noexcept; 23 | 24 | virtual void Transition(VulkanCommandList& cmd_list, uint32_t sub_resource, GpuResourceState target_state) const = 0; 25 | virtual void Transition(VulkanCommandList& cmd_list, GpuResourceState target_state) const = 0; 26 | 27 | protected: 28 | void CreateMemory(GpuResourceType type, const VkMemoryRequirements& requirements, GpuHeap heap, GpuResourceFlag flags); 29 | void Name(void* object, std::string_view name); 30 | void Reset(); 31 | VkDeviceMemory Memory() const noexcept; 32 | void* SharedHandle() const noexcept; 33 | GpuResourceType Type() const noexcept; 34 | GpuResourceFlag Flags() const noexcept; 35 | 36 | private: 37 | GpuResourceType type_ = GpuResourceType::Buffer; 38 | GpuResourceFlag flags_ = GpuResourceFlag::None; 39 | VulkanRecyclableObject memory_; 40 | Win32UniqueHandle shared_handle_; 41 | }; 42 | 43 | VULKAN_DEFINE_IMP(Resource) 44 | } // namespace AIHoloImager 45 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/D3D12/D3D12CommandPool.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "Base/MiniWindows.hpp" 9 | 10 | #include 11 | 12 | #include "Base/ComPtr.hpp" 13 | #include "Gpu/GpuCommandPool.hpp" 14 | #include "Gpu/GpuSystem.hpp" 15 | 16 | #include "../GpuCommandPoolInternal.hpp" 17 | #include "D3D12ImpDefine.hpp" 18 | 19 | namespace AIHoloImager 20 | { 21 | class D3D12CommandPool : public GpuCommandPoolInternal 22 | { 23 | public: 24 | D3D12CommandPool(GpuSystem& gpu_system, GpuSystem::CmdQueueType type); 25 | ~D3D12CommandPool() noexcept override; 26 | 27 | D3D12CommandPool(D3D12CommandPool&& other) noexcept; 28 | explicit D3D12CommandPool(GpuCommandPoolInternal&& other) noexcept; 29 | D3D12CommandPool& operator=(D3D12CommandPool&& other) noexcept; 30 | GpuCommandPoolInternal& operator=(GpuCommandPoolInternal&& other) noexcept override; 31 | 32 | ID3D12CommandAllocator* CmdAllocator() const noexcept; 33 | 34 | uint64_t FenceValue() const noexcept; 35 | void FenceValue(uint64_t value) noexcept; 36 | 37 | void RegisterAllocatedCommandList(ID3D12CommandList* cmd_list); 38 | void UnregisterAllocatedCommandList(ID3D12CommandList* cmd_list); 39 | bool EmptyAllocatedCommandLists() const noexcept; 40 | 41 | private: 42 | ComPtr cmd_allocator_; 43 | uint64_t fence_val_ = 0; 44 | 45 | std::list allocated_cmd_lists_; 46 | }; 47 | 48 | D3D12_DEFINE_IMP(CommandPool) 49 | } // namespace AIHoloImager 50 | -------------------------------------------------------------------------------- /Source/Lib/Source/SfM/PointCloudEstimator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | from pathlib import Path 5 | 6 | import torch 7 | 8 | from PythonSystem import ComputeDevice, PurgeTorchCache, TensorFromBytes 9 | from MoGe import MoGeModel 10 | 11 | class PointCloudEstimator: 12 | def __init__(self): 13 | self.device = ComputeDevice() 14 | 15 | this_py_dir = Path(__file__).parent.resolve() 16 | 17 | self.model = MoGeModel.FromPretrained(this_py_dir / "Models/moge-vitl/model.pt") 18 | self.model.eval() 19 | self.model = self.model.to(self.device) 20 | 21 | def Destroy(self): 22 | del self.model 23 | PurgeTorchCache() 24 | 25 | @torch.no_grad() 26 | def Focal(self, image, image_width, image_height, channels): 27 | image = TensorFromBytes(image, torch.uint8, image_height * image_width * channels, self.device) 28 | image = image.reshape(image_height, image_width, channels)[..., 0 : 3].permute(2, 0, 1) 29 | 30 | image = image.to(torch.float16).contiguous() 31 | image /= 255.0 32 | 33 | return self.model.Focal(image) 34 | 35 | @torch.no_grad() 36 | def PointCloud(self, image, image_width, image_height, channels, fov_x): 37 | image = TensorFromBytes(image, torch.uint8, image_height * image_width * channels, self.device) 38 | image = image.reshape(image_height, image_width, channels)[..., 0 : 3].permute(2, 0, 1) 39 | 40 | image = image.to(torch.float16).contiguous() 41 | image /= 255.0 42 | 43 | point_cloud = self.model.PointCloud(image, fov_x) 44 | return (point_cloud, point_cloud.shape[-2], point_cloud.shape[-3]) 45 | -------------------------------------------------------------------------------- /Source/GpuSystem/Include/Gpu/GpuFormat.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace AIHoloImager 9 | { 10 | enum class GpuBaseFormat 11 | { 12 | Unknown, 13 | UNorm, 14 | Uint, 15 | Sint, 16 | Float, 17 | }; 18 | 19 | enum class GpuFormat 20 | { 21 | Unknown, 22 | 23 | R8_UNorm, 24 | RG8_UNorm, 25 | RGBA8_UNorm, 26 | RGBA8_UNorm_SRGB, 27 | BGRA8_UNorm, 28 | BGRA8_UNorm_SRGB, 29 | BGRX8_UNorm, 30 | BGRX8_UNorm_SRGB, 31 | 32 | R16_Uint, 33 | R16_Sint, 34 | R16_Float, 35 | RG16_Uint, 36 | RG16_Sint, 37 | RG16_Float, 38 | RGBA16_Uint, 39 | RGBA16_Sint, 40 | RGBA16_Float, 41 | 42 | R32_Uint, 43 | R32_Sint, 44 | R32_Float, 45 | RG32_Uint, 46 | RG32_Sint, 47 | RG32_Float, 48 | RGB32_Uint, 49 | RGB32_Sint, 50 | RGB32_Float, 51 | RGBA32_Uint, 52 | RGBA32_Sint, 53 | RGBA32_Float, 54 | 55 | D16_UNorm, 56 | D24_UNorm_S8_Uint, 57 | D32_Float, 58 | D32_Float_S8X24_Uint, 59 | 60 | NV12, 61 | }; 62 | 63 | uint32_t FormatSize(GpuFormat fmt); 64 | GpuBaseFormat BaseFormat(GpuFormat fmt); 65 | uint32_t FormatChannels(GpuFormat fmt); 66 | uint32_t FormatChannelSize(GpuFormat fmt); 67 | uint32_t NumPlanes(GpuFormat fmt) noexcept; 68 | 69 | bool IsDepthStencilFormat(GpuFormat fmt) noexcept; 70 | bool IsStencilFormat(GpuFormat fmt) noexcept; 71 | } // namespace AIHoloImager 72 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/MaskGenerator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 Minmin Gong 2 | # 3 | 4 | from pathlib import Path 5 | 6 | import torch 7 | from torch.nn.utils import skip_init 8 | 9 | from PythonSystem import ComputeDevice, GeneralDevice, PurgeTorchCache 10 | from U2Net import U2Net, U2NetSmall 11 | 12 | class MaskGenerator: 13 | def __init__(self): 14 | this_py_dir = Path(__file__).parent.resolve() 15 | 16 | self.device = ComputeDevice() 17 | 18 | u2net_model_path = this_py_dir / "Models/U-2-Net/u2net.pth" 19 | self.u2net = skip_init(U2Net, 3, 1) 20 | self.u2net.load_state_dict(torch.load(u2net_model_path, map_location = GeneralDevice(), weights_only = True)) 21 | self.u2net.eval() 22 | self.u2net.to(self.device) 23 | 24 | u2net_small_model_path = this_py_dir / "Models/U-2-Net/u2netp.pth" 25 | self.u2net_small = skip_init(U2NetSmall, 3, 1) 26 | self.u2net_small.load_state_dict(torch.load(u2net_small_model_path, map_location = GeneralDevice(), weights_only = True)) 27 | self.u2net_small.eval() 28 | self.u2net_small.to(self.device) 29 | 30 | def Destroy(self): 31 | del self.u2net 32 | del self.u2net_small 33 | PurgeTorchCache() 34 | 35 | @torch.no_grad() 36 | def Gen(self, norm_img: torch.Tensor, width: int, height: int, num_channels: int, large_model: bool) -> torch.Tensor: 37 | norm_img = norm_img.reshape(1, num_channels, height, width) 38 | 39 | if large_model: 40 | pred = self.u2net(norm_img) 41 | else: 42 | pred = self.u2net_small(norm_img) 43 | 44 | pred = pred.reshape(height, width, 1) 45 | return pred 46 | -------------------------------------------------------------------------------- /Source/Lib/Source/SfM/Shader/UndistortCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | float3 k; // (0, 0), (0, 2), (1, 2) 9 | float3 params; 10 | float4 width_height; 11 | }; 12 | 13 | Texture2D distorted_tex; 14 | SamplerState bilinear_sampler; 15 | 16 | #ifdef __spirv__ 17 | [[vk::image_format("rgba8")]] 18 | #endif 19 | RWTexture2D undistorted_tex; 20 | 21 | // From Pinhole_Intrinsic_Radial_K3 22 | 23 | float Focal() 24 | { 25 | return k.x; 26 | } 27 | 28 | float2 PrincipalPoint() 29 | { 30 | return k.yz; 31 | } 32 | 33 | float2 Image2Camera(float2 p) 34 | { 35 | return (p - PrincipalPoint()) / Focal(); 36 | } 37 | 38 | float2 Camera2Image(float2 p) 39 | { 40 | return Focal() * p + PrincipalPoint(); 41 | } 42 | 43 | float2 AddDistortion(float2 p) 44 | { 45 | float r2 = dot(p, p); 46 | float r4 = r2 * r2; 47 | float r6 = r4 * r2; 48 | float r_coeff = 1 + dot(params, float3(r2, r4, r6)); 49 | 50 | return p * r_coeff; 51 | } 52 | 53 | float2 GetDistortedCoord(float2 p) 54 | { 55 | return Camera2Image(AddDistortion(Image2Camera(p))); 56 | } 57 | 58 | [numthreads(BlockDim, BlockDim, 1)] 59 | void main(uint32_t3 dtid : SV_DispatchThreadID) 60 | { 61 | float2 undistort_coord = dtid.xy; 62 | float2 distort_coord = GetDistortedCoord(undistort_coord); 63 | 64 | float4 color = float4(0, 0, 0, 1); 65 | if (all(bool4(distort_coord >= 0, distort_coord < width_height.xy))) 66 | { 67 | color.rgb = distorted_tex.SampleLevel(bilinear_sampler, distort_coord * width_height.zw, 0).rgb; 68 | } 69 | 70 | undistorted_tex[dtid.xy] = color; 71 | } 72 | -------------------------------------------------------------------------------- /Doc/DataFlow.md: -------------------------------------------------------------------------------- 1 | # Data Flow in AIHoloImager 2 | 3 | This is the overall data flow graph. 4 | 5 | ![Data flow](Img/DataFlow.png) 6 | 7 | 1. Input Images and Structure from Motion (SfM) Module: 8 | * The journey begins with input images, which are fed into the **Structure from Motion** module (implemented using [openMVG](https://github.com/openMVG/openMVG)). This module performs several critical tasks: 9 | * Generates a feature point cloud representing the scene. 10 | * Determines camera poses for each image. 11 | * Produces undistorted versions of the input images. 12 | * Additionally, a **Mask Generator** (implemented with [rembg](https://github.com/danielgatis/rembg)) processes the undistorted images, effectively separating foreground objects from the background. A **Delighter** (implemented with [Intrinsic](https://github.com/compphoto/Intrinsic) remove the lighting in images. 13 | 14 | 2. AI Mesh Generator: 15 | * All the processed data are further handled by the **AI Mesh Generator** module (implemented using [TRELLIS](https://github.com/Microsoft/TRELLIS)). This AI-powered step refines the 3D mesh, enhancing its completeness. 16 | 17 | 3. Differentiable Optimizer: 18 | * The **Differentiable Optimizer** module takes the AI-generated mesh, refines its transformation to match the delighted images. This step is crucial for improving the mesh's quality and accuracy. 19 | 20 | 4. Post Processing: 21 | * Finally, in the **Post Processing** module: 22 | * Project the texture to the 3D mesh. 23 | * Transform the mesh to a suitable pose. 24 | 25 | In summary, AIHoloImager combines traditional and AI-driven techniques to reconstruct a comprehensive 3D mesh from a limited set of input photos. 26 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanVertexLayout.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "Gpu/GpuVertexLayout.hpp" 12 | 13 | #include "../GpuVertexLayoutInternal.hpp" 14 | #include "VulkanImpDefine.hpp" 15 | 16 | namespace AIHoloImager 17 | { 18 | class VulkanVertexLayout : public GpuVertexLayoutInternal 19 | { 20 | public: 21 | explicit VulkanVertexLayout(std::span attribs, std::span slot_strides = {}); 22 | ~VulkanVertexLayout() override; 23 | 24 | VulkanVertexLayout(const VulkanVertexLayout& other); 25 | explicit VulkanVertexLayout(const GpuVertexLayoutInternal& other); 26 | 27 | VulkanVertexLayout& operator=(const VulkanVertexLayout& other); 28 | GpuVertexLayoutInternal& operator=(const GpuVertexLayoutInternal& other) override; 29 | 30 | VulkanVertexLayout(VulkanVertexLayout&& other) noexcept; 31 | explicit VulkanVertexLayout(GpuVertexLayoutInternal&& other) noexcept; 32 | 33 | VulkanVertexLayout& operator=(VulkanVertexLayout&& other) noexcept; 34 | GpuVertexLayoutInternal& operator=(GpuVertexLayoutInternal&& other) noexcept override; 35 | 36 | std::unique_ptr Clone() const override; 37 | 38 | std::span InputBindings() const; 39 | std::span InputAttribs() const; 40 | 41 | private: 42 | std::vector input_bindings_; 43 | std::vector input_attribs_; 44 | }; 45 | 46 | VULKAN_DEFINE_IMP(VertexLayout) 47 | } // namespace AIHoloImager 48 | -------------------------------------------------------------------------------- /Source/Lib/Source/ElementFormat.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "AIHoloImager/ElementFormat.hpp" 5 | 6 | #include "Base/ErrorHandling.hpp" 7 | 8 | namespace AIHoloImager 9 | { 10 | uint32_t FormatSize(ElementFormat fmt) 11 | { 12 | return FormatChannelSize(fmt) * FormatChannels(fmt); 13 | } 14 | 15 | uint32_t FormatChannels(ElementFormat fmt) 16 | { 17 | switch (fmt) 18 | { 19 | case ElementFormat::Unknown: 20 | return 0; 21 | 22 | case ElementFormat::R8_UNorm: 23 | case ElementFormat::R32_Float: 24 | return 1; 25 | 26 | case ElementFormat::RG8_UNorm: 27 | case ElementFormat::RG32_Float: 28 | return 2; 29 | 30 | case ElementFormat::RGB8_UNorm: 31 | case ElementFormat::RGB32_Float: 32 | return 3; 33 | 34 | case ElementFormat::RGBA8_UNorm: 35 | case ElementFormat::RGBA32_Float: 36 | return 4; 37 | 38 | default: 39 | Unreachable("Invalid format"); 40 | } 41 | } 42 | 43 | uint32_t FormatChannelSize(ElementFormat fmt) 44 | { 45 | switch (fmt) 46 | { 47 | case ElementFormat::Unknown: 48 | return 0; 49 | 50 | case ElementFormat::R8_UNorm: 51 | case ElementFormat::RG8_UNorm: 52 | case ElementFormat::RGB8_UNorm: 53 | case ElementFormat::RGBA8_UNorm: 54 | return 1; 55 | 56 | case ElementFormat::R32_Float: 57 | case ElementFormat::RG32_Float: 58 | case ElementFormat::RGB32_Float: 59 | case ElementFormat::RGBA32_Float: 60 | return 4; 61 | 62 | default: 63 | Unreachable("Invalid format"); 64 | } 65 | } 66 | } // namespace AIHoloImager 67 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/InternalImp.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #define IMP_INTERNAL(ClassName) \ 9 | ClassName##Internal& ClassName::Internal() noexcept \ 10 | { \ 11 | assert(impl_); \ 12 | return *impl_; \ 13 | } \ 14 | \ 15 | const ClassName##Internal& ClassName::Internal() const noexcept \ 16 | { \ 17 | return const_cast(*this).Internal(); \ 18 | } 19 | 20 | 21 | #define IMP_INTERNAL2(ClassName, ReturnName) \ 22 | ReturnName##Internal& ClassName::Internal() noexcept \ 23 | { \ 24 | assert(impl_); \ 25 | return *impl_; \ 26 | } \ 27 | \ 28 | const ReturnName##Internal& ClassName::Internal() const noexcept \ 29 | { \ 30 | return const_cast(*this).Internal(); \ 31 | } 32 | 33 | #define EMPTY_IMP(ClassName) \ 34 | class ClassName::Impl : public ClassName##Internal \ 35 | { \ 36 | }; 37 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.25 FATAL_ERROR) 2 | 3 | set(aihi_cmake_module_dir "${CMAKE_CURRENT_SOURCE_DIR}/CMake/Modules") 4 | list(APPEND CMAKE_MODULE_PATH "${aihi_cmake_module_dir}") 5 | 6 | set(ai_holo_imager_major_version 0) 7 | set(ai_holo_imager_minor_version 6) 8 | set(ai_holo_imager_patch_version 0) 9 | set(ai_holo_imager_version ${ai_holo_imager_major_version}.${ai_holo_imager_minor_version}.${ai_holo_imager_patch_version}) 10 | 11 | project(AIHoloImager LANGUAGES CXX VERSION ${ai_holo_imager_version}) 12 | 13 | if(DEFINED ENV{BUILD_BUILDID}) 14 | set(is_ci_env TRUE) 15 | else() 16 | set(is_ci_env FALSE) 17 | endif() 18 | 19 | include(${aihi_cmake_module_dir}/Platform.cmake) 20 | include(${aihi_cmake_module_dir}/Compiler.cmake) 21 | 22 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 23 | 24 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin) 25 | 26 | get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 27 | if(is_multi_config) 28 | set(aihi_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}) 29 | else() 30 | set(aihi_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 31 | endif() 32 | 33 | set(CMAKE_CXX_VISIBILITY_PRESET hidden) 34 | set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) 35 | 36 | option(AIHI_KEEP_INTERMEDIATES "Keep intermediate results" OFF) 37 | if(ai_holo_imager_platform_windows) 38 | option(AIHI_ENABLE_D3D12 "Enable D3D12" ON) 39 | endif() 40 | option(AIHI_ENABLE_VULKAN "Enable Vulkan" ON) 41 | 42 | # 3.13.4 has issues with lib name. See https://github.com/python/cpython/issues/135151 43 | find_package(Python3 3.11...<3.13.4 COMPONENTS Interpreter Development.Embed REQUIRED) 44 | 45 | add_subdirectory(External) 46 | add_subdirectory(Source) 47 | 48 | set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT "AIHoloImager") 49 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/Shader/StatImageCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Utils.hlslh" 5 | 6 | static const uint32_t BlockDim = 16; 7 | static const uint32_t MinWaveSize = 16; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t2 texture_size; 12 | }; 13 | 14 | Texture2D input_tex; 15 | 16 | RWTexture2D max_tex; 17 | 18 | groupshared float group_wave_max[BlockDim * BlockDim / MinWaveSize]; 19 | 20 | [numthreads(BlockDim, BlockDim, 1)] 21 | void main(uint32_t3 dtid : SV_DispatchThreadID, uint32_t group_index : SV_GroupIndex) 22 | { 23 | uint32_t2 coord = clamp(uint32_t2(dtid.xy), 0, texture_size - 1); 24 | float3 color = input_tex.Load(uint32_t3(coord, 0)).rgb; 25 | float data = max(max(color.r, color.g), color.b); 26 | GroupMemoryBarrierWithGroupSync(); 27 | 28 | const uint32_t wave_size = WaveGetLaneCount(); 29 | const uint32_t wave_index = group_index / wave_size; 30 | 31 | float max_ch = WaveActiveMax(data); 32 | 33 | uint32_t num_active_waves = DivUp(BlockDim * BlockDim, wave_size); 34 | while (num_active_waves > 1) 35 | { 36 | if (WaveIsFirstLane() && (wave_index < num_active_waves)) 37 | { 38 | group_wave_max[wave_index] = max_ch; 39 | } 40 | GroupMemoryBarrierWithGroupSync(); 41 | 42 | if (group_index < num_active_waves) 43 | { 44 | max_ch = group_wave_max[group_index]; 45 | } 46 | GroupMemoryBarrier(); 47 | 48 | if (group_index < num_active_waves) 49 | { 50 | max_ch = WaveActiveMax(max_ch); 51 | } 52 | 53 | num_active_waves = DivUp(num_active_waves, wave_size); 54 | } 55 | 56 | if (group_index == 0) 57 | { 58 | InterlockedMax(max_tex[uint32_t2(0, 0)], uint32_t(max_ch * 1e5f)); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Source/Lib/Source/Util/Shader/Lanczos.hlslh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | float Sinc(float x) 7 | { 8 | static const float Pi = 3.1415926f; 9 | 10 | if (x == 0) 11 | { 12 | return 1; 13 | } 14 | else 15 | { 16 | x *= Pi; 17 | return sin(x) / x; 18 | } 19 | } 20 | 21 | float Lanczos(float f, uint32_t kernel_radius) 22 | { 23 | return abs(f) < kernel_radius ? Sinc(f) * Sinc(f / kernel_radius) : 0; 24 | } 25 | 26 | template 27 | T LanczosResample(Texture2D input_tex, uint32_t2 dest_coord, uint32_t4 src_roi, float scale, uint32_t kernel_radius, bool x_dir, T min_value, T value_scale) 28 | { 29 | const float src_coord = ((x_dir ? dest_coord.x : dest_coord.y) + 0.5f) * scale - 0.5f; 30 | 31 | const float sampling_scale = max(scale, 1); 32 | int32_t sampling_range = int32_t(round(kernel_radius * sampling_scale)); 33 | 34 | T sum = 0; 35 | float total_weight = 0; 36 | for (int32_t i = -sampling_range; i <= sampling_range; ++i) 37 | { 38 | const float f = frac(src_coord) - i; 39 | const float weight = Lanczos(f / sampling_scale, kernel_radius); 40 | 41 | uint32_t2 input_coord; 42 | if (x_dir) 43 | { 44 | const uint32_t x = clamp(src_roi.x + int32_t(src_coord + i), src_roi.x, src_roi.z - 1); 45 | input_coord = uint32_t2(x, src_roi.y + dest_coord.y); 46 | } 47 | else 48 | { 49 | const uint32_t y = clamp(src_roi.y + int32_t(src_coord + i), src_roi.y, src_roi.w - 1); 50 | input_coord = uint32_t2(src_roi.x + dest_coord.x, y); 51 | } 52 | 53 | sum += (input_tex.Load(uint32_t3(input_coord, 0)) - min_value) * value_scale * weight; 54 | total_weight += weight; 55 | } 56 | 57 | return sum / total_weight; 58 | } 59 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/AntiAliasConstructOppoVertCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "Common.hlslh" 5 | 6 | static const uint32_t BlockDim = 256; 7 | static const uint32_t MaxProbeTime = 256; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t num_indices; 12 | uint32_t hash_size; 13 | }; 14 | 15 | Buffer indices_buff; 16 | Buffer hash_table; 17 | 18 | RWBuffer oppo_vert; 19 | 20 | [numthreads(BlockDim, 1, 1)] 21 | void main(uint32_t3 dtid : SV_DispatchThreadID) 22 | { 23 | [branch] 24 | if (dtid.x >= num_indices) 25 | { 26 | return; 27 | } 28 | 29 | const uint32_t face_id = dtid.x / 3; 30 | const uint32_t index = dtid.x - face_id * 3; 31 | 32 | uint32_t2 edge = uint32_t2(indices_buff[face_id * 3 + ((index + 1) % 3)], indices_buff[face_id * 3 + ((index + 2) % 3)]); 33 | if (edge.y < edge.x) 34 | { 35 | Swap(edge.x, edge.y); 36 | } 37 | 38 | uint32_t slot = HashFunc(edge) % hash_size; 39 | const uint32_t this_vertex = indices_buff[face_id * 3 + index]; 40 | 41 | bool found = false; 42 | for (uint32_t t = 0; t < MaxProbeTime; ++t) 43 | { 44 | if (hash_table[slot * 3 + 0] == ~0U) 45 | { 46 | oppo_vert[dtid.x] = ~0U; 47 | found = true; 48 | } 49 | else if ((hash_table[slot * 3 + 0] == edge.x) && (hash_table[slot * 3 + 1] == edge.y) && (hash_table[slot * 3 + 2] != this_vertex)) 50 | { 51 | oppo_vert[dtid.x] = hash_table[slot * 3 + 2]; 52 | found = true; 53 | } 54 | 55 | if (found) 56 | { 57 | break; 58 | } 59 | else 60 | { 61 | slot = (slot + 1) % hash_size; 62 | } 63 | } 64 | 65 | if (!found) 66 | { 67 | oppo_vert[dtid.x] = ~0U; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Source/Base/Include/Base/ErrorHandling.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "Base/MiniWindows.hpp" 12 | 13 | namespace AIHoloImager 14 | { 15 | std::string CombineFileLine(std::string_view file, uint32_t line); 16 | std::string CombineFileLine(HRESULT hr, std::string_view file, uint32_t line); 17 | void Verify(bool value); 18 | 19 | #ifdef _WIN32 20 | class HrException : public std::runtime_error 21 | { 22 | public: 23 | HrException(HRESULT hr, std::string_view file, uint32_t line) 24 | : std::runtime_error(CombineFileLine(hr, std::move(file), line)), hr_(hr) 25 | { 26 | } 27 | 28 | HRESULT Error() const noexcept 29 | { 30 | return hr_; 31 | } 32 | 33 | private: 34 | const HRESULT hr_; 35 | }; 36 | #endif 37 | 38 | [[noreturn]] inline void Unreachable([[maybe_unused]] std::string_view msg = {}) 39 | { 40 | #if defined(_MSC_VER) 41 | assert(false); 42 | __assume(false); 43 | #else 44 | __builtin_unreachable(); 45 | #endif 46 | } 47 | } // namespace AIHoloImager 48 | 49 | #ifdef _WIN32 50 | #define TIFHR(x) \ 51 | { \ 52 | const auto inner_hr = (x); \ 53 | if (FAILED(inner_hr)) \ 54 | { \ 55 | throw AIHoloImager::HrException(inner_hr, __FILE__, __LINE__); \ 56 | } \ 57 | } 58 | #endif 59 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/D3D12/D3D12VertexLayout.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include "Base/MiniWindows.hpp" 10 | 11 | #include 12 | 13 | #include "Gpu/GpuVertexLayout.hpp" 14 | 15 | #include "../GpuVertexLayoutInternal.hpp" 16 | #include "D3D12ImpDefine.hpp" 17 | 18 | namespace AIHoloImager 19 | { 20 | class D3D12VertexLayout : public GpuVertexLayoutInternal 21 | { 22 | public: 23 | explicit D3D12VertexLayout(std::span attribs, std::span slot_strides = {}); 24 | ~D3D12VertexLayout() override; 25 | 26 | D3D12VertexLayout(const D3D12VertexLayout& other); 27 | explicit D3D12VertexLayout(const GpuVertexLayoutInternal& other); 28 | 29 | D3D12VertexLayout& operator=(const D3D12VertexLayout& other); 30 | GpuVertexLayoutInternal& operator=(const GpuVertexLayoutInternal& other) override; 31 | 32 | D3D12VertexLayout(D3D12VertexLayout&& other) noexcept; 33 | explicit D3D12VertexLayout(GpuVertexLayoutInternal&& other) noexcept; 34 | 35 | D3D12VertexLayout& operator=(D3D12VertexLayout&& other) noexcept; 36 | GpuVertexLayoutInternal& operator=(GpuVertexLayoutInternal&& other) noexcept override; 37 | 38 | std::unique_ptr Clone() const override; 39 | 40 | std::span InputElementDescs() const noexcept; 41 | std::span SlotStrides() const noexcept; 42 | 43 | private: 44 | void UpdateSemantics(); 45 | 46 | private: 47 | std::vector input_elems_; 48 | std::vector semantics_; 49 | std::vector slot_strides_; 50 | }; 51 | 52 | D3D12_DEFINE_IMP(VertexLayout) 53 | } // namespace AIHoloImager 54 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanDescriptorAllocator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "Base/Noncopyable.hpp" 11 | #include "Gpu/GpuSystem.hpp" 12 | 13 | #include "VulkanUtil.hpp" 14 | 15 | namespace AIHoloImager 16 | { 17 | class VulkanDescriptorPool final 18 | { 19 | DISALLOW_COPY_AND_ASSIGN(VulkanDescriptorPool) 20 | 21 | public: 22 | explicit VulkanDescriptorPool(GpuSystem& gpu_system); 23 | ~VulkanDescriptorPool(); 24 | 25 | VulkanDescriptorPool(VulkanDescriptorPool&& other) noexcept; 26 | VulkanDescriptorPool& operator=(VulkanDescriptorPool&& other) noexcept; 27 | 28 | VkDescriptorPool Pool() const noexcept; 29 | 30 | private: 31 | VulkanRecyclableObject pool_; 32 | }; 33 | 34 | class VulkanDescriptorSetAllocator final 35 | { 36 | DISALLOW_COPY_AND_ASSIGN(VulkanDescriptorSetAllocator) 37 | 38 | public: 39 | VulkanDescriptorSetAllocator(); 40 | explicit VulkanDescriptorSetAllocator(GpuSystem& gpu_system); 41 | ~VulkanDescriptorSetAllocator(); 42 | 43 | VulkanDescriptorSetAllocator(VulkanDescriptorSetAllocator&& other) noexcept; 44 | VulkanDescriptorSetAllocator& operator=(VulkanDescriptorSetAllocator&& other) noexcept; 45 | 46 | explicit operator bool() const; 47 | 48 | VkDescriptorSet Allocate(VkDescriptorSetLayout layout); 49 | void Deallocate(VkDescriptorSet desc_set); 50 | 51 | private: 52 | GpuSystem* gpu_system_ = nullptr; 53 | 54 | struct PoolInfo 55 | { 56 | VulkanDescriptorPool pool; 57 | std::vector> allocated_sets; 58 | }; 59 | 60 | std::vector pools_; 61 | }; 62 | } // namespace AIHoloImager 63 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/Shader/StatPredCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Utils.hlslh" 5 | 6 | static const uint32_t BlockDim = 16; 7 | static const uint32_t MinWaveSize = 16; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t2 texture_size; 12 | }; 13 | 14 | Texture2D input_tex; 15 | 16 | RWTexture2D min_max_tex; 17 | 18 | groupshared float2 group_wave_min_max[BlockDim * BlockDim / MinWaveSize]; 19 | 20 | [numthreads(BlockDim, BlockDim, 1)] 21 | void main(uint32_t3 dtid : SV_DispatchThreadID, uint32_t group_index : SV_GroupIndex) 22 | { 23 | uint32_t2 coord = clamp(uint32_t2(dtid.xy), 0, texture_size - 1); 24 | float data = input_tex.Load(uint32_t3(coord, 0)); 25 | GroupMemoryBarrierWithGroupSync(); 26 | 27 | const uint32_t wave_size = WaveGetLaneCount(); 28 | const uint32_t wave_index = group_index / wave_size; 29 | 30 | float2 min_max = float2(WaveActiveMin(data), WaveActiveMax(data)); 31 | 32 | uint32_t num_active_waves = DivUp(BlockDim * BlockDim, wave_size); 33 | while (num_active_waves > 1) 34 | { 35 | if (WaveIsFirstLane() && (wave_index < num_active_waves)) 36 | { 37 | group_wave_min_max[wave_index] = min_max; 38 | } 39 | GroupMemoryBarrierWithGroupSync(); 40 | 41 | if (group_index < num_active_waves) 42 | { 43 | min_max = group_wave_min_max[group_index]; 44 | } 45 | GroupMemoryBarrier(); 46 | 47 | if (group_index < num_active_waves) 48 | { 49 | min_max = float2(WaveActiveMin(min_max.x), WaveActiveMax(min_max.y)); 50 | } 51 | 52 | num_active_waves = DivUp(num_active_waves, wave_size); 53 | } 54 | 55 | if (group_index == 0) 56 | { 57 | InterlockedMin(min_max_tex[uint32_t2(0, 0)], uint32_t(min_max.x * 1e5f)); 58 | InterlockedMax(min_max_tex[uint32_t2(1, 0)], uint32_t(min_max.y * 1e5f)); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/Shader/GaussianBlurCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | static const int32_t KernelRadius = 2; 6 | 7 | cbuffer param_cb 8 | { 9 | uint32_t2 texture_size; 10 | bool x_dir; 11 | float weights[KernelRadius * 2 + 1]; 12 | }; 13 | 14 | Texture2D input_tex; 15 | 16 | #ifdef __spirv__ 17 | [[vk::image_format("r8")]] 18 | #endif 19 | RWTexture2D output_tex; 20 | 21 | groupshared float group_cache[BlockDim * (BlockDim + KernelRadius * 2)]; 22 | 23 | [numthreads(BlockDim, BlockDim, 1)] 24 | void main(uint32_t3 group_id : SV_GroupID, uint32_t3 gt_id : SV_GroupThreadID, uint32_t3 dtid : SV_DispatchThreadID, uint32_t group_index : SV_GroupIndex) 25 | { 26 | const uint32_t cache_width = BlockDim + (x_dir ? KernelRadius * 2 : 0); 27 | const uint32_t cache_height = BlockDim + (x_dir ? 0 : KernelRadius * 2); 28 | 29 | const int32_t2 start = int32_t2(x_dir ? KernelRadius : 0, x_dir ? 0 : KernelRadius); 30 | for (uint32_t i = group_index; i < cache_width * cache_height; i += BlockDim * BlockDim) 31 | { 32 | const uint32_t y = i / cache_width; 33 | const uint32_t x = i - y * cache_width; 34 | uint32_t2 coord = clamp(int32_t2(group_id.xy * BlockDim) - start + int32_t2(x, y), 0, texture_size - 1); 35 | group_cache[y * cache_width + x] = input_tex.Load(uint32_t3(coord, 0)); 36 | } 37 | GroupMemoryBarrierWithGroupSync(); 38 | 39 | [branch] 40 | if (any(dtid.xy >= texture_size)) 41 | { 42 | return; 43 | } 44 | 45 | float sum = 0; 46 | for (int32_t i = -KernelRadius; i <= KernelRadius; ++i) 47 | { 48 | const int32_t2 cache_coord = start + gt_id.xy + (x_dir ? int32_t2(i, 0) : int32_t2(0, i)); 49 | sum += group_cache[cache_coord.y * cache_width + cache_coord.x] * weights[i + KernelRadius]; 50 | } 51 | 52 | output_tex[dtid.xy] = x_dir ? sum : (sum > 0.5f); 53 | } 54 | -------------------------------------------------------------------------------- /Source/Lib/Source/MaskGen/Shader/ErosionDilationCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | static const int32_t KernelRadius = 1; 6 | 7 | static const uint32_t CacheDim = BlockDim + KernelRadius * 2; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t2 texture_size; 12 | bool erosion; 13 | bool weights[(KernelRadius * 2 + 1) * (KernelRadius * 2 + 1)]; 14 | }; 15 | 16 | Texture2D input_tex; 17 | 18 | #ifdef __spirv__ 19 | [[vk::image_format("r8")]] 20 | #endif 21 | RWTexture2D output_tex; 22 | 23 | groupshared bool sh_cache[CacheDim][CacheDim]; 24 | 25 | [numthreads(BlockDim, BlockDim, 1)] 26 | void main(uint32_t3 group_id : SV_GroupID, uint32_t3 gt_id : SV_GroupThreadID, uint32_t3 dtid : SV_DispatchThreadID, uint32_t group_index : SV_GroupIndex) 27 | { 28 | for (uint32_t i = group_index; i < CacheDim * CacheDim; i += BlockDim * BlockDim) 29 | { 30 | const uint32_t y = i / CacheDim; 31 | const uint32_t x = i - y * CacheDim; 32 | uint32_t2 coord = clamp(int32_t2(group_id.xy * BlockDim) - KernelRadius + int32_t2(x, y), 0, texture_size - 1); 33 | sh_cache[y][x] = input_tex.Load(uint32_t3(coord, 0)) > 0.5f; 34 | if (erosion) 35 | { 36 | sh_cache[y][x] = !sh_cache[y][x]; 37 | } 38 | } 39 | GroupMemoryBarrierWithGroupSync(); 40 | 41 | [branch] 42 | if (any(dtid.xy >= texture_size)) 43 | { 44 | return; 45 | } 46 | 47 | bool mark = false; 48 | for (int32_t y = -KernelRadius; y <= KernelRadius; ++y) 49 | { 50 | for (int32_t x = -KernelRadius; x <= KernelRadius; ++x) 51 | { 52 | if (weights[(y + KernelRadius) * (KernelRadius * 2 + 1) + (x + KernelRadius)] && 53 | sh_cache[gt_id.y + KernelRadius + y][gt_id.x + KernelRadius + x]) 54 | { 55 | mark = true; 56 | } 57 | } 58 | } 59 | 60 | output_tex[dtid.xy] = erosion ? !mark : mark; 61 | } 62 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/GpuVertexLayout.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Gpu/GpuVertexLayout.hpp" 5 | 6 | #include "Gpu/GpuSystem.hpp" 7 | 8 | #include "Internal/GpuSystemInternal.hpp" 9 | #include "Internal/GpuVertexLayoutInternal.hpp" 10 | #include "InternalImp.hpp" 11 | 12 | namespace AIHoloImager 13 | { 14 | EMPTY_IMP(GpuVertexLayout) 15 | IMP_INTERNAL(GpuVertexLayout) 16 | 17 | GpuVertexLayout::GpuVertexLayout() noexcept = default; 18 | 19 | GpuVertexLayout::GpuVertexLayout( 20 | GpuSystem& gpu_system, std::span attribs, std::span slot_strides) 21 | : impl_(static_cast(gpu_system.Internal().CreateVertexLayout(std::move(attribs), std::move(slot_strides)).release())) 22 | { 23 | static_assert(sizeof(Impl) == sizeof(GpuVertexLayoutInternal)); 24 | } 25 | 26 | GpuVertexLayout::GpuVertexLayout(const GpuVertexLayout& other) : impl_(static_cast(other.impl_->Clone().release())) 27 | { 28 | } 29 | 30 | GpuVertexLayout::~GpuVertexLayout() noexcept = default; 31 | 32 | GpuVertexLayout& GpuVertexLayout::operator=(const GpuVertexLayout& other) 33 | { 34 | if (this != &other) 35 | { 36 | if (impl_) 37 | { 38 | static_cast(*impl_) = static_cast(*other.impl_); 39 | } 40 | else 41 | { 42 | impl_.reset(static_cast(other.impl_->Clone().release())); 43 | } 44 | } 45 | return *this; 46 | } 47 | 48 | GpuVertexLayout::GpuVertexLayout(GpuVertexLayout&& other) noexcept : impl_(std::move(other.impl_)) 49 | { 50 | } 51 | 52 | GpuVertexLayout& GpuVertexLayout::operator=(GpuVertexLayout&& other) noexcept 53 | { 54 | if (this != &other) 55 | { 56 | impl_ = std::move(other.impl_); 57 | } 58 | return *this; 59 | } 60 | } // namespace AIHoloImager 61 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/D3D12/D3D12DescriptorHeap.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "Base/MiniWindows.hpp" 9 | 10 | #include 11 | 12 | #include "Base/ComPtr.hpp" 13 | #include "Base/Noncopyable.hpp" 14 | #include "Gpu/GpuSystem.hpp" 15 | 16 | namespace AIHoloImager 17 | { 18 | D3D12_CPU_DESCRIPTOR_HANDLE OffsetHandle(D3D12_CPU_DESCRIPTOR_HANDLE handle, int32_t offset, uint32_t desc_size); 19 | D3D12_GPU_DESCRIPTOR_HANDLE OffsetHandle(D3D12_GPU_DESCRIPTOR_HANDLE handle, int32_t offset, uint32_t desc_size); 20 | std::tuple OffsetHandle( 21 | D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, int32_t offset, uint32_t desc_size); 22 | 23 | class D3D12DescriptorHeap 24 | { 25 | DISALLOW_COPY_AND_ASSIGN(D3D12DescriptorHeap) 26 | 27 | public: 28 | D3D12DescriptorHeap( 29 | GpuSystem& gpu_system, uint32_t size, D3D12_DESCRIPTOR_HEAP_TYPE type, bool shader_visible, std::string_view name = ""); 30 | ~D3D12DescriptorHeap() noexcept; 31 | 32 | D3D12DescriptorHeap(D3D12DescriptorHeap&& other) noexcept; 33 | D3D12DescriptorHeap& operator=(D3D12DescriptorHeap&& other) noexcept; 34 | 35 | void Name(std::string_view name); 36 | 37 | ID3D12DescriptorHeap* DescriptorHeap() const noexcept; 38 | void* NativeDescriptorHeap() const noexcept; 39 | 40 | D3D12_DESCRIPTOR_HEAP_TYPE Type() const noexcept; 41 | 42 | D3D12_CPU_DESCRIPTOR_HANDLE CpuHandleStart() const noexcept; 43 | D3D12_GPU_DESCRIPTOR_HANDLE GpuHandleStart() const noexcept; 44 | 45 | uint32_t Size() const noexcept; 46 | 47 | void Reset() noexcept; 48 | 49 | private: 50 | ComPtr heap_; 51 | D3D12_DESCRIPTOR_HEAP_DESC desc_{}; 52 | D3D12_DESCRIPTOR_HEAP_TYPE type_{}; 53 | }; 54 | } // namespace AIHoloImager 55 | -------------------------------------------------------------------------------- /Source/Lib/Source/Util/FormatConversion.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | #include "Util/FormatConversion.hpp" 5 | 6 | #include "Base/ErrorHandling.hpp" 7 | 8 | namespace AIHoloImager 9 | { 10 | GpuFormat ToGpuFormat(ElementFormat fmt) 11 | { 12 | switch (fmt) 13 | { 14 | case ElementFormat::Unknown: 15 | return GpuFormat::Unknown; 16 | 17 | case ElementFormat::R8_UNorm: 18 | return GpuFormat::R8_UNorm; 19 | case ElementFormat::RG8_UNorm: 20 | return GpuFormat::RG8_UNorm; 21 | case ElementFormat::RGBA8_UNorm: 22 | return GpuFormat::RGBA8_UNorm; 23 | 24 | case ElementFormat::R32_Float: 25 | return GpuFormat::R32_Float; 26 | case ElementFormat::RG32_Float: 27 | return GpuFormat::RG32_Float; 28 | case ElementFormat::RGB32_Float: 29 | return GpuFormat::RGB32_Float; 30 | case ElementFormat::RGBA32_Float: 31 | return GpuFormat::RGBA32_Float; 32 | 33 | default: 34 | Unreachable("Invalid format"); 35 | } 36 | } 37 | 38 | ElementFormat ToElementFormat(GpuFormat fmt) 39 | { 40 | switch (fmt) 41 | { 42 | case GpuFormat::Unknown: 43 | return ElementFormat::Unknown; 44 | 45 | case GpuFormat::R8_UNorm: 46 | return ElementFormat::R8_UNorm; 47 | case GpuFormat::RG8_UNorm: 48 | return ElementFormat::RG8_UNorm; 49 | case GpuFormat::RGBA8_UNorm: 50 | return ElementFormat::RGBA8_UNorm; 51 | 52 | case GpuFormat::R32_Float: 53 | return ElementFormat::R32_Float; 54 | case GpuFormat::RG32_Float: 55 | return ElementFormat::RG32_Float; 56 | case GpuFormat::RGB32_Float: 57 | return ElementFormat::RGB32_Float; 58 | case GpuFormat::RGBA32_Float: 59 | return ElementFormat::RGBA32_Float; 60 | 61 | default: 62 | Unreachable("Invalid format"); 63 | } 64 | } 65 | } // namespace AIHoloImager 66 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Modules/Spatial.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/modules/spatial.py 5 | 6 | import torch 7 | 8 | def PixelShuffle3D(x: torch.Tensor, scale_factor: int) -> torch.Tensor: 9 | """ 10 | 3D pixel shuffle. 11 | """ 12 | 13 | batch, channels, height, width, depth = x.shape 14 | channels = channels // (scale_factor ** 3) 15 | x = x.reshape(batch, channels, scale_factor, scale_factor, scale_factor, height, width, depth) 16 | x = x.permute(0, 1, 5, 2, 6, 3, 7, 4) 17 | x = x.reshape(batch, channels, height * scale_factor, width * scale_factor, depth * scale_factor) 18 | return x 19 | 20 | def Patchify(x: torch.Tensor, patch_size: int): 21 | """ 22 | Patchify a tensor. 23 | 24 | Args: 25 | x (torch.Tensor): (N, C, *spatial) tensor 26 | patch_size (int): Patch size 27 | """ 28 | 29 | dim = x.dim() - 2 30 | for d in range(2, dim + 2): 31 | assert x.shape[d] % patch_size == 0, f"Dimension {d} of input tensor must be divisible by patch size, got {x.shape[d]} and {patch_size}" 32 | 33 | x = x.reshape(*x.shape[:2], *sum([[x.shape[d] // patch_size, patch_size] for d in range(2, dim + 2)], [])) 34 | x = x.permute(0, 1, *([2 * i + 3 for i in range(dim)] + [2 * i + 2 for i in range(dim)])) 35 | x = x.reshape(x.shape[0], x.shape[1] * (patch_size ** dim), *(x.shape[-dim :])) 36 | return x 37 | 38 | def Unpatchify(x: torch.Tensor, patch_size: int): 39 | """ 40 | Unpatchify a tensor. 41 | 42 | Args: 43 | x (torch.Tensor): (N, C, *spatial) tensor 44 | patch_size (int): Patch size 45 | """ 46 | 47 | dim = x.dim() - 2 48 | assert x.shape[1] % (patch_size ** dim) == 0, f"Second dimension of input tensor must be divisible by patch size to unpatchify, got {x.shape[1]} and {patch_size ** dim}" 49 | 50 | x = x.reshape(x.shape[0], x.shape[1] // (patch_size ** dim), *([patch_size] * dim), *(x.shape[-dim :])) 51 | x = x.permute(0, 1, *(sum([[2 + dim + i, 2 + i] for i in range(dim)], []))) 52 | x = x.reshape(x.shape[0], x.shape[1], *[x.shape[2 + 2 * i] * patch_size for i in range(dim)]) 53 | return x 54 | -------------------------------------------------------------------------------- /Source/SubMConv/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | set(aihi_subm_conv_files 5 | Source/pch.hpp 6 | Source/Torch/Shader/BuildCoordHashCs.hlsl 7 | Source/Torch/Shader/Common.hlslh 8 | Source/Torch/Shader/FindAvailableNeighborsCs.hlsl 9 | Source/Torch/PyTorchBindings.cpp 10 | Source/Torch/SubMConv.cpp 11 | Source/Torch/SubMConv.hpp 12 | ) 13 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${aihi_subm_conv_files}) 14 | 15 | add_library(AIHoloImagerSubMConv SHARED 16 | ${aihi_subm_conv_files} 17 | ) 18 | 19 | AddShaderFile(Source/Torch/Shader/BuildCoordHashCs.hlsl "cs" "main") 20 | AddShaderFile(Source/Torch/Shader/FindAvailableNeighborsCs.hlsl "cs" "main") 21 | 22 | set(torch_dir ${PROJECT_SOURCE_DIR}/External/PythonVenv/PythonVenv/Lib/site-packages/torch) 23 | 24 | target_include_directories(AIHoloImagerSubMConv 25 | PRIVATE 26 | ${torch_dir}/include 27 | ${torch_dir}/include/torch/csrc/api/include 28 | ${CMAKE_CURRENT_SOURCE_DIR}/Source 29 | ${CMAKE_CURRENT_BINARY_DIR} 30 | ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} 31 | ) 32 | 33 | target_precompile_headers(AIHoloImagerSubMConv 34 | PRIVATE 35 | Source/pch.hpp 36 | ) 37 | 38 | if(MSVC) 39 | target_compile_options(AIHoloImagerSubMConv 40 | PRIVATE 41 | /wd4702 # Ignore unreachable code in PyTorch 42 | ) 43 | endif() 44 | 45 | target_compile_definitions(AIHoloImagerSubMConv 46 | PRIVATE 47 | TORCH_API_INCLUDE_EXTENSION_H 48 | ) 49 | 50 | target_link_directories(AIHoloImagerSubMConv 51 | PRIVATE 52 | ${torch_dir}/lib 53 | ) 54 | 55 | target_link_libraries(AIHoloImagerSubMConv 56 | PRIVATE 57 | AIHoloImagerGpuSystem 58 | AIHoloImagerTensorConverter 59 | 60 | c10.lib 61 | torch_cpu.lib 62 | torch.lib 63 | torch_python.lib 64 | Python3::Python 65 | glm 66 | ) 67 | 68 | set_target_properties(AIHoloImagerSubMConv 69 | PROPERTIES 70 | SUFFIX ".pyd" 71 | POSTFIX "" 72 | DEBUG_POSTFIX "" 73 | MINSIZEREL_POSTFIX "" 74 | RELWITHDEBINFO_POSTFIX "" 75 | RELEASE_POSTFIX "" 76 | ) 77 | 78 | add_dependencies(AIHoloImagerSubMConv DeployPython) 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AIHoloImager 2 | 3 | [![Build Status](https://gongminmin.visualstudio.com/AIHoloImager/_apis/build/status%2Fgongminmin.AIHoloImager?branchName=main)](https://gongminmin.visualstudio.com/AIHoloImager/_build/latest?definitionId=8&branchName=main) 4 | 5 | In the futuristic world of Star Trek: Voyager, the Doc is an avid fan of holograms. Armed with a holo-imager, a device akin to a camera, he captures moments in 3D splendor. These holograms come to life within the holodeck, a virtual reality environment. But how does one transform mere photos into intricate 3D structures? The show leaves this question unanswered, as it operates in the realm of 24th-century technology. 6 | 7 | Now, let's shift our focus back to reality. In our world, we have tools like structure from motion and multi-view stereo that can generate 3D meshes from a handful of images. However, there's a catch: these methods work primarily on visible surfaces. Any regions not captured by the photos remain blank, leaving gaps in the reconstructed model. On the flip side, AI-powered techniques can create a complete 3D mesh from a single image. Yet, they rely on educated guesses for content not explicitly present in that image. 8 | 9 | So, here's the intriguing proposition: AIHoloImage aims to combine the best of both worlds. By breaking down the reconstruction pipeline into distinct stages, we can selectively apply either AI-driven or traditional methods for each stage. The result? A relatively complete 3D mesh assembled from just a few photos or a video clip. 10 | 11 | # Getting started 12 | 13 | AIHoloImager currently supports only Windows. To get started, use CMake to generate the project file and build the application. Before you begin, ensure that you have the following prerequisites installed: 14 | 15 | * [Git](http://git-scm.com/downloads). Put git into the PATH is recommended. 16 | * [Visual Studio 2022](https://www.visualstudio.com/downloads). 17 | * [CMake](https://www.cmake.org/download/). Version 3.20 or up. It's highly recommended to choose "Add CMake to the system PATH for all users" during installation. 18 | * [Python](https://www.python.org/downloads/). Version 3.11 to 3.13. 19 | 20 | # License 21 | 22 | AIHoloImager is distributed under the terms of MIT License. See [LICENSE](LICENSE) for details. 23 | -------------------------------------------------------------------------------- /Source/Base/Include/Base/Uuid.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #ifdef _WIN32 10 | #include 11 | #endif 12 | 13 | namespace AIHoloImager 14 | { 15 | struct Uuid 16 | { 17 | uint32_t data1; 18 | uint16_t data2; 19 | uint16_t data3; 20 | uint8_t data4[8]; 21 | 22 | Uuid() noexcept = default; 23 | constexpr Uuid(uint32_t d1, uint16_t d2, uint16_t d3, const std::array d4) noexcept 24 | : data1(d1), data2(d2), data3(d3), data4{d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7]} 25 | { 26 | } 27 | 28 | #ifdef _WIN32 29 | constexpr Uuid(const GUID& value) noexcept 30 | : Uuid(value.Data1, value.Data2, value.Data3, 31 | {value.Data4[0], value.Data4[1], value.Data4[2], value.Data4[3], value.Data4[4], value.Data4[5], value.Data4[6], 32 | value.Data4[7]}) 33 | { 34 | } 35 | 36 | operator const GUID&() const noexcept 37 | { 38 | return reinterpret_cast(*this); 39 | } 40 | #endif 41 | }; 42 | 43 | template 44 | const Uuid& UuidOf(); 45 | 46 | template 47 | inline const Uuid& UuidOf([[maybe_unused]] T* p) 48 | { 49 | return UuidOf(); 50 | } 51 | 52 | template 53 | inline const Uuid& UuidOf([[maybe_unused]] const T* p) 54 | { 55 | return UuidOf(); 56 | } 57 | 58 | template 59 | inline const Uuid& UuidOf([[maybe_unused]] T& p) 60 | { 61 | return UuidOf(); 62 | } 63 | 64 | template 65 | inline const Uuid& UuidOf([[maybe_unused]] const T& p) 66 | { 67 | return UuidOf(); 68 | } 69 | } // namespace AIHoloImager 70 | 71 | #define DEFINE_UUID_OF(x) \ 72 | template <> \ 73 | const AIHoloImager::Uuid& AIHoloImager::UuidOf() \ 74 | { \ 75 | return reinterpret_cast(IID_##x); \ 76 | } 77 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Trellis/Models/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | # Based on https://github.com/microsoft/TRELLIS/blob/main/trellis/models/__init__.py 5 | 6 | from torch.nn.utils import skip_init 7 | 8 | __attributes = { 9 | "SparseStructureDecoder": "SparseStructureVae", 10 | "SparseStructureFlowModel": "SparseStructureFlow", 11 | "SLatMeshDecoder": "StructuredLatentVae", 12 | "SLatFlowModel": "StructuredLatentFlow", 13 | } 14 | 15 | __submodules = [] 16 | 17 | __all__ = list(__attributes.keys()) + __submodules 18 | 19 | def __getattr__(name): 20 | if name not in globals(): 21 | import importlib 22 | if name in __attributes: 23 | module_name = __attributes[name] 24 | module = importlib.import_module(f".{module_name}", __name__) 25 | globals()[name] = getattr(module, name) 26 | elif name in __submodules: 27 | module = importlib.import_module(f".{name}", __name__) 28 | globals()[name] = module 29 | else: 30 | raise AttributeError(f"module {__name__} has no attribute {name}") 31 | return globals()[name] 32 | 33 | def FromPretrained(path: str, **kwargs): 34 | from pathlib import Path 35 | import json 36 | from safetensors.torch import load_file 37 | 38 | config_file_path = Path(f"{path}.json") 39 | model_file_path = Path(f"{path}.safetensors") 40 | 41 | with open(config_file_path, "r") as file: 42 | config = json.load(file) 43 | model = skip_init(__getattr__(config["name"]), **config["args"], **kwargs) 44 | state_dict = load_file(model_file_path) 45 | new_state_dict = {} 46 | for key, value in state_dict.items(): 47 | if key.find("adaLN_modulation") != -1: 48 | key = key.replace("adaLN_modulation", "ada_ln_modulation") 49 | elif key.startswith("upsample.") or key.startswith("input_blocks.") or key.startswith("out_blocks."): 50 | if key.endswith("conv.weight"): 51 | key = key.replace("conv.weight", "weight") 52 | elif key.endswith("conv.bias"): 53 | key = key.replace("conv.bias", "bias") 54 | new_state_dict[key] = value 55 | model.load_state_dict(new_state_dict) 56 | 57 | return model 58 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Shader/InterpolateFwdCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | uint32_t2 gbuffer_size; 9 | uint32_t num_attribs; 10 | }; 11 | 12 | Texture2D barycentric_tex; 13 | Texture2D prim_id_tex; 14 | Buffer vtx_attribs_buff; 15 | Buffer indices_buff; 16 | #if ENABLE_DERIVATIVE_BC 17 | Texture2D derivative_barycentric_tex; 18 | #endif 19 | 20 | RWBuffer shading; 21 | #if ENABLE_DERIVATIVE_BC 22 | RWBuffer derivative_shading; 23 | #endif 24 | 25 | [numthreads(BlockDim, BlockDim, 1)] 26 | void main(uint32_t3 dtid : SV_DispatchThreadID) 27 | { 28 | [branch] 29 | if (any(dtid.xy >= gbuffer_size)) 30 | { 31 | return; 32 | } 33 | 34 | uint32_t fi = prim_id_tex[dtid.xy]; 35 | [branch] 36 | if (fi == 0) 37 | { 38 | return; 39 | } 40 | 41 | --fi; 42 | 43 | uint32_t in_offsets[3]; 44 | for (uint32_t i = 0; i < 3; ++i) 45 | { 46 | in_offsets[i] = indices_buff[fi * 3 + i] * num_attribs; 47 | } 48 | 49 | const uint32_t out_offset = (dtid.y * gbuffer_size.x + dtid.x) * num_attribs; 50 | float3 bc; 51 | bc.xy = barycentric_tex[dtid.xy]; 52 | bc.z = 1 - bc.x - bc.y; 53 | #if ENABLE_DERIVATIVE_BC 54 | const float4 duv_dxy = derivative_barycentric_tex[dtid.xy]; 55 | #endif 56 | for (uint32_t i = 0; i < num_attribs; ++i) 57 | { 58 | const float3 attribs = float3(vtx_attribs_buff[in_offsets[0] + i], 59 | vtx_attribs_buff[in_offsets[1] + i], 60 | vtx_attribs_buff[in_offsets[2] + i]); 61 | 62 | shading[out_offset + i] = bc.x * attribs.x + 63 | bc.y * attribs.y + 64 | bc.z * attribs.z; 65 | 66 | #if ENABLE_DERIVATIVE_BC 67 | // Eq 4 68 | // dA/d{u,v} = {A0 - A2, A1 - A2} 69 | const float2 da_duv = attribs.xy - attribs.z; 70 | 71 | // dA/d{x,y} = dA/d{u,v} * d{u,v}/d{x,y} 72 | const float2 da_dxy = float2(dot(da_duv, duv_dxy.xz), dot(da_duv, duv_dxy.yw)); 73 | derivative_shading[out_offset + i] = da_dxy; 74 | #endif 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Source/GpuDiffRender/Source/Torch/PyTorchBindings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuDiffRenderTorch.hpp" 5 | 6 | #ifdef _DEBUG 7 | #undef _DEBUG // Stop linking to python_d.lib 8 | #endif 9 | #include 10 | 11 | #ifdef _MSC_VER 12 | #pragma warning(push) 13 | #pragma warning(disable : 4251) // Ignore non dll-interface as member 14 | #endif 15 | #include 16 | #ifdef _MSC_VER 17 | #pragma warning(pop) 18 | #endif 19 | 20 | using namespace AIHoloImager; 21 | 22 | PYBIND11_MODULE(AIHoloImagerGpuDiffRender, mod) 23 | { 24 | pybind11::class_(mod, "GpuDiffRenderTorch") 25 | .def(pybind11::init()) 26 | .def("Rasterize", &GpuDiffRenderTorch::Rasterize, py::arg("positions"), py::arg("indices"), py::arg("resolution"), 27 | py::arg("viewport") = py::none(), py::arg("needs_derivative_barycentric") = false) 28 | .def("Interpolate", &GpuDiffRenderTorch::Interpolate, py::arg("vtx_attribs"), py::arg("barycentric"), py::arg("prim_id"), 29 | py::arg("indices"), py::arg("derivative_barycentric") = py::none()) 30 | .def("Texture", &GpuDiffRenderTorch::Texture, py::arg("texture"), py::arg("prim_id"), py::arg("uv"), py::arg("filter"), 31 | py::arg("address_mode"), py::arg("derivative_uv") = py::none()) 32 | .def("AntiAliasConstructOppositeVertices", &GpuDiffRenderTorch::AntiAliasConstructOppositeVertices, py::arg("indices")) 33 | .def("AntiAlias", &GpuDiffRenderTorch::AntiAlias, py::arg("shading"), py::arg("prim_id"), py::arg("positions"), py::arg("indices"), 34 | py::arg("viewport") = py::none(), py::arg("opposite_vertices") = py::none()); 35 | 36 | pybind11::class_(mod, "Viewport") 37 | .def(pybind11::init<>()) 38 | .def_readwrite("left", &GpuDiffRenderTorch::Viewport::left) 39 | .def_readwrite("top", &GpuDiffRenderTorch::Viewport::top) 40 | .def_readwrite("width", &GpuDiffRenderTorch::Viewport::width) 41 | .def_readwrite("height", &GpuDiffRenderTorch::Viewport::height); 42 | 43 | pybind11::class_(mod, "AntiAliasOppositeVertices").def(pybind11::init<>()); 44 | } 45 | -------------------------------------------------------------------------------- /Source/Lib/Source/MeshGen/Shader/MarchingCubes/ProcessNonEmptyCubesCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #include "MarchingCubesUtil.hlslh" 5 | 6 | static const uint32_t BlockDim = 256; 7 | static const uint32_t MaxGroupDim = 65535; 8 | 9 | cbuffer param_cb 10 | { 11 | uint32_t size; 12 | uint32_t total_cubes; 13 | float isovalue; 14 | }; 15 | 16 | #ifdef __spirv__ 17 | [[vk::image_format("r16ui")]] 18 | #endif 19 | Buffer edge_table; 20 | #ifdef __spirv__ 21 | [[vk::image_format("r16ui")]] 22 | #endif 23 | Buffer triangle_table; 24 | Buffer cube_offsets; 25 | Texture3D scalar_deformation; 26 | 27 | RWBuffer non_empty_cube_ids; 28 | RWBuffer non_empty_cube_indices; 29 | RWBuffer vertex_index_offsets; 30 | RWBuffer counter; 31 | 32 | [numthreads(BlockDim, 1, 1)] 33 | void main(uint32_t3 dtid : SV_DispatchThreadID) 34 | { 35 | const uint32_t cid = dtid.y * MaxGroupDim + dtid.x; 36 | 37 | [branch] 38 | if (cid >= total_cubes) 39 | { 40 | return; 41 | } 42 | 43 | const uint32_t offset = cube_offsets[cid]; 44 | [branch] 45 | if (offset == ~0U) 46 | { 47 | return; 48 | } 49 | 50 | const uint32_t OwnedEdges[] = {0, 3, 8}; 51 | 52 | non_empty_cube_ids[offset] = cid; 53 | 54 | const uint32_t3 coord = DecomposeCoord(cid, size); 55 | const uint32_t cube_index = CalcCubeIndex(scalar_deformation, coord, size, isovalue); 56 | 57 | non_empty_cube_indices[offset] = cube_index; 58 | const uint32_t cube_num_indices = triangle_table[cube_index * 16 + 0]; 59 | 60 | const uint32_t edges = edge_table[cube_index]; 61 | uint32_t cube_num_vertices = 0; 62 | if (edges != 0) 63 | { 64 | for (uint32_t i = 0; i < sizeof(OwnedEdges) / sizeof(OwnedEdges[0]); ++i) 65 | { 66 | const uint32_t e = OwnedEdges[i]; 67 | if (edges & (1U << e)) 68 | { 69 | ++cube_num_vertices; 70 | } 71 | } 72 | } 73 | 74 | uint32_t vertex_addr; 75 | InterlockedAdd(counter[1], cube_num_vertices, vertex_addr); 76 | 77 | uint32_t index_addr; 78 | InterlockedAdd(counter[2], cube_num_indices, index_addr); 79 | 80 | vertex_index_offsets[offset] = uint32_t2(vertex_addr, index_addr); 81 | } 82 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanSampler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "Gpu/GpuSampler.hpp" 11 | 12 | #include "../GpuSamplerInternal.hpp" 13 | #include "VulkanImpDefine.hpp" 14 | #include "VulkanUtil.hpp" 15 | 16 | namespace AIHoloImager 17 | { 18 | class GpuSystem; 19 | 20 | class VulkanStaticSampler : public GpuStaticSamplerInternal 21 | { 22 | public: 23 | VulkanStaticSampler(GpuSystem& gpu_system, const GpuSampler::Filters& filters, const GpuSampler::AddressModes& addr_modes); 24 | ~VulkanStaticSampler() override; 25 | 26 | VulkanStaticSampler(VulkanStaticSampler&& other) noexcept; 27 | explicit VulkanStaticSampler(GpuStaticSamplerInternal&& other) noexcept; 28 | 29 | VulkanStaticSampler& operator=(VulkanStaticSampler&& other) noexcept; 30 | GpuStaticSamplerInternal& operator=(GpuStaticSamplerInternal&& other) noexcept override; 31 | 32 | const std::shared_ptr>& Sampler() const noexcept; 33 | 34 | private: 35 | std::shared_ptr> sampler_; 36 | }; 37 | 38 | VULKAN_DEFINE_IMP(StaticSampler) 39 | 40 | class VulkanDynamicSampler : public GpuDynamicSamplerInternal 41 | { 42 | public: 43 | VulkanDynamicSampler(GpuSystem& gpu_system, const GpuSampler::Filters& filters, const GpuSampler::AddressModes& addr_modes); 44 | ~VulkanDynamicSampler() override; 45 | 46 | VulkanDynamicSampler(VulkanDynamicSampler&& other) noexcept; 47 | explicit VulkanDynamicSampler(GpuDynamicSamplerInternal&& other) noexcept; 48 | 49 | VulkanDynamicSampler& operator=(VulkanDynamicSampler&& other) noexcept; 50 | GpuDynamicSamplerInternal& operator=(GpuDynamicSamplerInternal&& other) noexcept override; 51 | 52 | const VkSampler& Sampler() const noexcept; 53 | VkWriteDescriptorSet WriteDescSet() const noexcept; 54 | 55 | private: 56 | VulkanRecyclableObject sampler_; 57 | VkWriteDescriptorSet write_desc_set_; 58 | VkDescriptorImageInfo image_info_; 59 | }; 60 | 61 | VULKAN_DEFINE_IMP(DynamicSampler) 62 | 63 | VkWriteDescriptorSet NullDynamicSamplerWriteDescSet(); 64 | } // namespace AIHoloImager 65 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/D3D12/D3D12Sampler.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/MiniWindows.hpp" 7 | 8 | #include 9 | 10 | #include "Gpu/GpuSampler.hpp" 11 | 12 | #include "../GpuSamplerInternal.hpp" 13 | #include "D3D12DescriptorAllocator.hpp" 14 | #include "D3D12ImpDefine.hpp" 15 | 16 | namespace AIHoloImager 17 | { 18 | class GpuSystem; 19 | 20 | class D3D12StaticSampler : public GpuStaticSamplerInternal 21 | { 22 | public: 23 | D3D12StaticSampler(const GpuSampler::Filters& filters, const GpuSampler::AddressModes& addr_modes); 24 | ~D3D12StaticSampler() override; 25 | 26 | D3D12StaticSampler(D3D12StaticSampler&& other) noexcept; 27 | explicit D3D12StaticSampler(GpuStaticSamplerInternal&& other) noexcept; 28 | 29 | D3D12StaticSampler& operator=(D3D12StaticSampler&& other) noexcept; 30 | GpuStaticSamplerInternal& operator=(GpuStaticSamplerInternal&& other) noexcept override; 31 | 32 | D3D12_STATIC_SAMPLER_DESC SamplerDesc(uint32_t register_index) const noexcept; 33 | 34 | private: 35 | D3D12_STATIC_SAMPLER_DESC sampler_{}; 36 | }; 37 | 38 | D3D12_DEFINE_IMP(StaticSampler) 39 | 40 | class D3D12DynamicSampler : public GpuDynamicSamplerInternal 41 | { 42 | public: 43 | D3D12DynamicSampler(GpuSystem& gpu_system, const GpuSampler::Filters& filters, const GpuSampler::AddressModes& addr_modes); 44 | ~D3D12DynamicSampler() override; 45 | 46 | D3D12DynamicSampler(D3D12DynamicSampler&& other) noexcept; 47 | explicit D3D12DynamicSampler(GpuDynamicSamplerInternal&& other) noexcept; 48 | 49 | D3D12DynamicSampler& operator=(D3D12DynamicSampler&& other) noexcept; 50 | GpuDynamicSamplerInternal& operator=(GpuDynamicSamplerInternal&& other) noexcept override; 51 | 52 | void CopyTo(D3D12_CPU_DESCRIPTOR_HANDLE dst_handle) const noexcept; 53 | 54 | const D3D12_SAMPLER_DESC& SamplerDesc() const noexcept; 55 | 56 | private: 57 | GpuSystem* gpu_system_ = nullptr; 58 | ID3D12Device* d3d12_device_; 59 | 60 | D3D12DescriptorBlock desc_block_; 61 | D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle_{}; 62 | 63 | D3D12_SAMPLER_DESC sampler_{}; 64 | }; 65 | 66 | D3D12_DEFINE_IMP(DynamicSampler) 67 | } // namespace AIHoloImager 68 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/Vulkan/VulkanErrorhandling.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "Base/ErrorHandling.hpp" 12 | 13 | namespace AIHoloImager 14 | { 15 | template 16 | class VulkanErrorException : public std::runtime_error 17 | { 18 | public: 19 | VulkanErrorException(ResultType result, std::string_view file, uint32_t line) 20 | : std::runtime_error(CombineFileLine(result, std::move(file), line)), result_(result) 21 | { 22 | } 23 | 24 | ResultType Result() const noexcept 25 | { 26 | return result_; 27 | } 28 | 29 | private: 30 | const ResultType result_; 31 | }; 32 | } // namespace AIHoloImager 33 | 34 | #define TIFVK(x) \ 35 | { \ 36 | const auto inner_result = (x); \ 37 | if (inner_result != VK_SUCCESS) \ 38 | { \ 39 | throw AIHoloImager::VulkanErrorException(inner_result, __FILE__, __LINE__); \ 40 | } \ 41 | } 42 | 43 | #define TIFSPVRFL(x) \ 44 | { \ 45 | const auto inner_result = (x); \ 46 | if (inner_result != SPV_REFLECT_RESULT_SUCCESS) \ 47 | { \ 48 | throw AIHoloImager::VulkanErrorException(inner_result, __FILE__, __LINE__); \ 49 | } \ 50 | } 51 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/D3D12/D3D12Resource.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | #include "Base/MiniWindows.hpp" 7 | 8 | #include 9 | 10 | #include "Base/ComPtr.hpp" 11 | #include "Base/SmartPtrHelper.hpp" 12 | #include "Gpu/GpuFormat.hpp" 13 | #include "Gpu/GpuResource.hpp" 14 | 15 | #include "D3D12CommandList.hpp" 16 | #include "D3D12ImpDefine.hpp" 17 | #include "D3D12Util.hpp" 18 | 19 | namespace AIHoloImager 20 | { 21 | class D3D12Resource 22 | { 23 | public: 24 | explicit D3D12Resource(GpuSystem& gpu_system); 25 | D3D12Resource(GpuSystem& gpu_system, void* native_resource, std::string_view name); 26 | virtual ~D3D12Resource(); 27 | 28 | D3D12Resource(D3D12Resource&& other) noexcept; 29 | D3D12Resource& operator=(D3D12Resource&& other) noexcept; 30 | 31 | ID3D12Resource* Resource() const noexcept; 32 | 33 | virtual void Transition(D3D12CommandList& cmd_list, uint32_t sub_resource, GpuResourceState target_state) const = 0; 34 | virtual void Transition(D3D12CommandList& cmd_list, GpuResourceState target_state) const = 0; 35 | 36 | protected: 37 | void Name(std::string_view name); 38 | 39 | void Reset(); 40 | 41 | void CreateResource(GpuResourceType type, uint32_t width, uint32_t height, uint32_t depth, uint32_t array_size, uint32_t mip_levels, 42 | GpuFormat format, GpuHeap heap, GpuResourceFlag flags, GpuResourceState init_state, std::string_view name); 43 | 44 | void* SharedHandle() const noexcept; 45 | 46 | GpuResourceType Type() const noexcept; 47 | GpuResourceFlag Flags() const noexcept; 48 | uint32_t AllocationSize() const noexcept; 49 | 50 | uint32_t Width() const noexcept; 51 | uint32_t Height() const noexcept; 52 | uint32_t Depth() const noexcept; 53 | uint32_t ArraySize() const noexcept; 54 | uint32_t MipLevels() const noexcept; 55 | 56 | GpuFormat Format() const noexcept; 57 | 58 | private: 59 | D3D12RecyclableObject> resource_; 60 | GpuResourceType type_ = GpuResourceType::Buffer; 61 | GpuResourceFlag flags_ = GpuResourceFlag::None; 62 | D3D12_RESOURCE_DESC desc_{}; 63 | Win32UniqueHandle shared_handle_; 64 | }; 65 | 66 | D3D12_DEFINE_IMP(Resource) 67 | } // namespace AIHoloImager 68 | -------------------------------------------------------------------------------- /Source/GpuSystem/Source/Internal/GpuResourceViewsInternal.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2025 Minmin Gong 2 | // 3 | 4 | #include "GpuResourceViewsInternal.hpp" 5 | 6 | namespace AIHoloImager 7 | { 8 | GpuConstantBufferViewInternal::GpuConstantBufferViewInternal() noexcept = default; 9 | GpuConstantBufferViewInternal::~GpuConstantBufferViewInternal() = default; 10 | 11 | GpuConstantBufferViewInternal::GpuConstantBufferViewInternal(GpuConstantBufferViewInternal&& other) noexcept = default; 12 | GpuConstantBufferViewInternal& GpuConstantBufferViewInternal::operator=(GpuConstantBufferViewInternal&& other) noexcept = default; 13 | 14 | 15 | GpuShaderResourceViewInternal::GpuShaderResourceViewInternal() noexcept = default; 16 | GpuShaderResourceViewInternal::~GpuShaderResourceViewInternal() = default; 17 | 18 | GpuShaderResourceViewInternal::GpuShaderResourceViewInternal(GpuShaderResourceViewInternal&& other) noexcept = default; 19 | GpuShaderResourceViewInternal& GpuShaderResourceViewInternal::operator=(GpuShaderResourceViewInternal&& other) noexcept = default; 20 | 21 | 22 | GpuRenderTargetViewInternal::GpuRenderTargetViewInternal() noexcept = default; 23 | GpuRenderTargetViewInternal::~GpuRenderTargetViewInternal() = default; 24 | 25 | GpuRenderTargetViewInternal::GpuRenderTargetViewInternal(GpuRenderTargetViewInternal&& other) noexcept = default; 26 | GpuRenderTargetViewInternal& GpuRenderTargetViewInternal::operator=(GpuRenderTargetViewInternal&& other) noexcept = default; 27 | 28 | 29 | GpuDepthStencilViewInternal::GpuDepthStencilViewInternal() noexcept = default; 30 | GpuDepthStencilViewInternal::~GpuDepthStencilViewInternal() = default; 31 | 32 | GpuDepthStencilViewInternal::GpuDepthStencilViewInternal(GpuDepthStencilViewInternal&& other) noexcept = default; 33 | GpuDepthStencilViewInternal& GpuDepthStencilViewInternal::operator=(GpuDepthStencilViewInternal&& other) noexcept = default; 34 | 35 | 36 | GpuUnorderedAccessViewInternal::GpuUnorderedAccessViewInternal() noexcept = default; 37 | GpuUnorderedAccessViewInternal::~GpuUnorderedAccessViewInternal() = default; 38 | 39 | GpuUnorderedAccessViewInternal::GpuUnorderedAccessViewInternal(GpuUnorderedAccessViewInternal&& other) noexcept = default; 40 | GpuUnorderedAccessViewInternal& GpuUnorderedAccessViewInternal::operator=(GpuUnorderedAccessViewInternal&& other) noexcept = default; 41 | } // namespace AIHoloImager 42 | -------------------------------------------------------------------------------- /Source/Lib/Source/Python/PythonSystem.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | from typing import * 5 | 6 | import torch 7 | 8 | def SeedRandom(seed : int): 9 | import random 10 | random.seed(seed) 11 | 12 | import numpy 13 | numpy.random.seed(seed) 14 | 15 | torch.manual_seed(seed) 16 | 17 | compute_device_name = "cpu" 18 | def InitPySys(device : str): 19 | global compute_device_name 20 | torch_device = getattr(torch, device, None) 21 | if (torch_device != None) and hasattr(torch_device, "is_available") and torch_device.is_available(): 22 | compute_device_name = device 23 | 24 | print(f"Pick \"{compute_device_name}\" as the computation device.") 25 | 26 | import os 27 | os.environ["XFORMERS_DISABLED"] = "1" # Disable the usage of xformers in dinov2 28 | 29 | SeedRandom(42) 30 | 31 | if os.name == "nt": 32 | from pathlib import Path 33 | this_py_dir = Path(__file__).parent.resolve() 34 | 35 | general_device = None 36 | def GeneralDevice(): 37 | global general_device 38 | if general_device == None: 39 | general_device = torch.device("cpu") 40 | return general_device 41 | 42 | compute_device = None 43 | def ComputeDevice(): 44 | global compute_device 45 | if compute_device == None: 46 | global compute_device_name 47 | if compute_device_name != "cpu": 48 | compute_device = torch.device(compute_device_name) 49 | else: 50 | compute_device = GeneralDevice() 51 | return compute_device 52 | 53 | def PurgeTorchCache(): 54 | global compute_device_name 55 | torch_device = getattr(torch, compute_device_name, None) 56 | if (torch_device != None) and hasattr(torch_device, "empty_cache"): 57 | torch_device.empty_cache() 58 | 59 | def TensorFromBytes(buffer : bytes, dtype : torch.dtype, count : int, device : Optional[torch.device] = None) -> torch.Tensor: 60 | import warnings 61 | with warnings.catch_warnings(): 62 | warnings.simplefilter("ignore") 63 | tensor = torch.frombuffer(buffer, dtype = dtype, count = count) 64 | if (device is None) or (device == GeneralDevice()): 65 | tensor = tensor.clone() 66 | else: 67 | tensor = tensor.to(device) 68 | return tensor 69 | 70 | def TensorToBytes(tensor : torch.Tensor) -> bytes: 71 | tensor = tensor.to(GeneralDevice()).contiguous() 72 | return tensor.numpy().tobytes() 73 | -------------------------------------------------------------------------------- /Source/Lib/Source/TextureRecon/Shader/ProjectTextureCs.hlsl: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024-2025 Minmin Gong 2 | // 3 | 4 | static const uint32_t BlockDim = 16; 5 | 6 | cbuffer param_cb 7 | { 8 | float4x4 camera_view_proj; 9 | float4x4 camera_view; 10 | float4x4 camera_view_it; 11 | float2 vp_offset; 12 | float2 delighted_offset; 13 | float2 delighted_scale; 14 | uint32_t texture_size; 15 | }; 16 | 17 | Texture2D pos_tex; 18 | Texture2D normal_tex; 19 | Texture2D photo_tex; 20 | Texture2D depth_tex; 21 | 22 | SamplerState point_sampler; 23 | SamplerState bilinear_sampler; 24 | 25 | #ifdef __spirv__ 26 | [[vk::image_format("rgba8")]] 27 | #endif 28 | RWTexture2D accum_color_tex; 29 | 30 | float Sqr(float x) 31 | { 32 | return x * x; 33 | } 34 | 35 | [numthreads(BlockDim, BlockDim, 1)] 36 | void main(uint32_t3 dtid : SV_DispatchThreadID) 37 | { 38 | [branch] 39 | if (any(dtid.xy >= texture_size)) 40 | { 41 | return; 42 | } 43 | 44 | float4 normal_ws = normal_tex.Load(uint32_t3(dtid.xy, 0)); 45 | 46 | [branch] 47 | if (normal_ws.a < 0.5f) 48 | { 49 | return; 50 | } 51 | 52 | float4 pos_ws = pos_tex.Load(uint32_t3(dtid.xy, 0)); 53 | 54 | float4 pos_ss = mul(pos_ws, camera_view_proj); 55 | float4 abs_pos_ss = abs(pos_ss); 56 | if (all(bool4(abs_pos_ss.xyz <= abs_pos_ss.w, pos_ss.z >= 0))) 57 | { 58 | pos_ss /= pos_ss.w; 59 | 60 | float3 normal_es = normalize(mul(normal_ws.xyz * 2 - 1, (float3x3)camera_view_it)); 61 | if (normal_es.z > 0) 62 | { 63 | float2 coord = float2(pos_ss.x, -pos_ss.y) * 0.5f + 0.5f + vp_offset; 64 | if (pos_ss.z < depth_tex.SampleLevel(point_sampler, coord, 0) * 1.02f) 65 | { 66 | float4 pos_es = mul(pos_ws, camera_view); 67 | pos_es /= pos_es.w; 68 | float3 ray_es = normalize(pos_es.xyz); 69 | 70 | float4 color = photo_tex.SampleLevel(bilinear_sampler, (coord - delighted_offset) * delighted_scale, 0); 71 | float confidence = -ray_es.z * normal_es.z * color.a; 72 | float prev_confidence = accum_color_tex[dtid.xy].a; 73 | if (confidence > prev_confidence) 74 | { 75 | accum_color_tex[dtid.xy] = float4(color.rgb, confidence); 76 | } 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Source/Lib/Source/Util/Shader/Nn.hlslh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Minmin Gong 2 | // 3 | 4 | #pragma once 5 | 6 | struct TensorView 7 | { 8 | static TensorView Create(Buffer buff, uint32_t offset, uint32_t2 shape) 9 | { 10 | TensorView view; 11 | view.data = buff; 12 | view.offset = offset; 13 | view.shape = shape; 14 | return view; 15 | } 16 | 17 | float Read(uint32_t x, uint32_t y = 0) 18 | { 19 | return data[offset + y * shape[0] + x]; 20 | } 21 | 22 | uint32_t Shape(uint32_t dim) 23 | { 24 | if (dim < 2) 25 | { 26 | return shape[dim]; 27 | } 28 | else 29 | { 30 | return 1; 31 | } 32 | } 33 | 34 | Buffer data; 35 | uint32_t offset; 36 | uint32_t2 shape; 37 | }; 38 | 39 | template 40 | struct Tensor 41 | { 42 | float Read(uint32_t x) 43 | { 44 | return buffer[x]; 45 | } 46 | 47 | void Write(uint32_t x, float value) 48 | { 49 | buffer[x] = value; 50 | } 51 | 52 | uint32_t Shape(uint32_t dim) 53 | { 54 | if (dim == 0) 55 | { 56 | return Size; 57 | } 58 | else 59 | { 60 | return 1; 61 | } 62 | } 63 | 64 | float buffer[Size]; 65 | }; 66 | 67 | template 68 | void Linear(out OutputType out_tensor, InputType node_tensor, WeightType weight_tensor, BiasType bias_tensor) 69 | { 70 | for (uint32_t i = 0; i < weight_tensor.Shape(1); ++i) 71 | { 72 | float val = bias_tensor.Read(i); 73 | for (uint32_t j = 0; j < weight_tensor.Shape(0); ++j) 74 | { 75 | val += node_tensor.Read(j) * weight_tensor.Read(j, i); 76 | } 77 | out_tensor.Write(i, val); 78 | } 79 | } 80 | 81 | template 82 | void ReLU(out OutputType out_tensor, InputType in_tensor) 83 | { 84 | for (uint32_t i = 0; i < in_tensor.Shape(0); ++i) 85 | { 86 | out_tensor.Write(i, max(in_tensor.Read(i), 0)); 87 | } 88 | } 89 | 90 | template 91 | void Sigmoid(out OutputType out_tensor, InputType in_tensor) 92 | { 93 | for (uint32_t i = 0; i < in_tensor.Shape(0); ++i) 94 | { 95 | out_tensor.Write(i, 1 / (1 + exp(-in_tensor.Read(i)))); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /External/assimp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 Minmin Gong 2 | # 3 | 4 | UpdateExternalLib(NAME "assimp" 5 | URL "https://github.com/assimp/assimp.git" 6 | REV "53b5dba4df171373fddb5ce7f00db6399c0aeeaa" 7 | BRANCH "master" 8 | SHALLOW_EXCLUDE "v5.0.0" 9 | ) 10 | 11 | set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) 12 | set(BUILD_TESTING OFF CACHE BOOL "" FORCE) 13 | set(ASSIMP_OPT_BUILD_PACKAGES OFF CACHE BOOL "" FORCE) 14 | set(ASSIMP_ANDROID_JNIIOSYSTEM OFF CACHE BOOL "" FORCE) 15 | set(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT OFF CACHE BOOL "" FORCE) 16 | set(ASSIMP_BUILD_PLY_IMPORTER OFF CACHE BOOL "" FORCE) 17 | set(ASSIMP_BUILD_GLTF_IMPORTER ON CACHE BOOL "" FORCE) 18 | set(ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT OFF CACHE BOOL "" FORCE) 19 | set(ASSIMP_BUILD_PLY_EXPORTER ON CACHE BOOL "" FORCE) 20 | set(ASSIMP_BUILD_GLTF_EXPORTER ON CACHE BOOL "" FORCE) 21 | set(ASSIMP_BUILD_OBJ_EXPORTER ON CACHE BOOL "" FORCE) 22 | set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE BOOL "" FORCE) 23 | set(ASSIMP_BUILD_ASSIMP_VIEW OFF CACHE BOOL "" FORCE) 24 | set(ASSIMP_BUILD_DOCS OFF CACHE BOOL "" FORCE) 25 | set(ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL "" FORCE) 26 | set(ASSIMP_BUILD_SAMPLES OFF CACHE BOOL "" FORCE) 27 | set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "" FORCE) 28 | set(ASSIMP_BUILD_ZLIB OFF CACHE BOOL "" FORCE) 29 | set(ASSIMP_IGNORE_GIT_HASH ON CACHE BOOL "" FORCE) 30 | set(ASSIMP_INSTALL OFF CACHE BOOL "" FORCE) 31 | set(ASSIMP_INSTALL_PDB OFF CACHE BOOL "" FORCE) 32 | set(ASSIMP_NO_EXPORT OFF CACHE BOOL "" FORCE) 33 | set(ASSIMP_RAPIDJSON_NO_MEMBER_ITERATOR ON CACHE BOOL "" FORCE) 34 | unset(ASSIMP_RUNTIME_OUTPUT_DIRECTORY CACHE) 35 | unset(ASSIMP_LIBRARY_OUTPUT_DIRECTORY CACHE) 36 | unset(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY CACHE) 37 | 38 | add_subdirectory(assimp EXCLUDE_FROM_ALL) 39 | 40 | if(ai_holo_imager_compiler_msvc) 41 | target_compile_options(assimp 42 | PRIVATE 43 | /wd4756 # Ignore the INFINITY constant overflow in some specific Windows SDKs 44 | ) 45 | elseif(ai_holo_imager_compiler_clangcl) 46 | target_compile_options(assimp 47 | PRIVATE 48 | -Wno-unused-function 49 | ) 50 | if (ai_holo_imager_compiler_version GREATER_EQUAL 160) 51 | target_compile_options(assimp 52 | PRIVATE 53 | -Wno-deprecated-copy 54 | ) 55 | endif() 56 | endif() 57 | 58 | set_target_properties(assimp PROPERTIES FOLDER "External") 59 | -------------------------------------------------------------------------------- /External/TRELLIS/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2025 Minmin Gong 2 | # 3 | 4 | if(is_ci_env) 5 | add_custom_target(DeployTrellisModels) 6 | else() 7 | if(DEFINED ENV{GIT_LFS_SKIP_SMUDGE}) 8 | set(lfs_skip "$ENV{GIT_LFS_SKIP_SMUDGE}") 9 | else() 10 | set(lfs_skip 0) 11 | endif() 12 | 13 | set(ENV{GIT_LFS_SKIP_SMUDGE} 1) 14 | UpdateExternalLib(NAME "TRELLIS-image-large" 15 | URL "https://huggingface.co/microsoft/TRELLIS-image-large" 16 | REV "2476b8db9c8484a1bbd16772c24ff88890f2b19a" 17 | NEED_CHECKOUT need_checkout 18 | ) 19 | set(ENV{GIT_LFS_SKIP_SMUDGE} ${lfs_skip}) 20 | 21 | if(need_checkout) 22 | PullLfsFile("TRELLIS-image-large" "ckpts/slat_dec_mesh_swin8_B_64l8m256c_fp16.safetensors") 23 | PullLfsFile("TRELLIS-image-large" "ckpts/slat_flow_img_dit_L_64l8p2_fp16.safetensors") 24 | PullLfsFile("TRELLIS-image-large" "ckpts/ss_dec_conv3d_16l8_fp16.safetensors") 25 | PullLfsFile("TRELLIS-image-large" "ckpts/ss_flow_img_dit_L_16l8_fp16.safetensors") 26 | endif() 27 | 28 | set(deployed_files ) 29 | 30 | set(copy_files 31 | ckpts/slat_dec_mesh_swin8_B_64l8m256c_fp16.json 32 | ckpts/slat_dec_mesh_swin8_B_64l8m256c_fp16.safetensors 33 | ckpts/slat_flow_img_dit_L_64l8p2_fp16.json 34 | ckpts/slat_flow_img_dit_L_64l8p2_fp16.safetensors 35 | ckpts/ss_dec_conv3d_16l8_fp16.json 36 | ckpts/ss_dec_conv3d_16l8_fp16.safetensors 37 | ckpts/ss_flow_img_dit_L_16l8_fp16.json 38 | ckpts/ss_flow_img_dit_L_16l8_fp16.safetensors 39 | pipeline.json 40 | ) 41 | foreach(src_file ${copy_files}) 42 | set(src_file TRELLIS-image-large/${src_file}) 43 | set(output_file ${aihi_output_dir}/Models/${src_file}) 44 | add_custom_command(OUTPUT ${output_file} 45 | COMMAND ${CMAKE_COMMAND} -E create_hardlink ${src_file} ${output_file} 46 | COMMENT "Deploying ${src_file}..." 47 | DEPENDS ${src_file} 48 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 49 | VERBATIM COMMAND_EXPAND_LISTS 50 | ) 51 | 52 | list(APPEND deployed_files ${output_file}) 53 | endforeach() 54 | 55 | add_custom_target(DeployTrellisModels DEPENDS ${deployed_files}) 56 | add_dependencies(DeployTrellisModels DeployDinov2Models) 57 | endif() 58 | 59 | set_target_properties(DeployTrellisModels PROPERTIES FOLDER "External") 60 | --------------------------------------------------------------------------------