Modified version of Pixal3D that supports a separate texture gen pipeline
Python
0
0 commits
updated Jul 5, 2026
Dong-Yang Li¹ · Wang Zhao²* · Yuxin Chen² · Wenbo Hu² · Meng-Hao Guo¹ · Fang-Lue Zhang³ · Ying Shan² · Shi-Min Hu¹✉
¹Tsinghua University (BNRist) ²Tencent ARC Lab ³Victoria University of Wellington
*Project lead ✉Corresponding author
Pixal3D generates high-fidelity 3D assets from a single image. Instead of loosely injecting image features via attention, it explicitly lifts pixel features into 3D through back-projection, establishing direct pixel-to-3D correspondences.
This is a fork of the original Pixal3D repo that adds texture-only inference with automatic pose alignment: texturing an externally-supplied mesh (e.g. a Hunyuan3D output) from a single photo, even when the photo is not shot from the mesh's canonical front.
Added files
| File | Purpose |
|---|---|
texture_inference.py | CLI entry point: texture an external mesh from a photo. |
pixal3d/pipelines/pixal3d_texturing.py | Texturing pipeline (proj-mode texture DIT on an external mesh). |
pixal3d/utils/pose_utils.py | Confidence-gated photo↔mesh rotation estimation from MoGe-2 point maps. |
visualize_voxels.py | Export a .pt voxel-field dump to .ply for inspection. |
Modified files
| File | Change |
|---|---|
pixal3d/pipelines/__init__.py | Registers Pixal3DTexturingPipeline. |
pixal3d/trainers/flow_matching/mixins/image_conditioned_proj.py | Proj-feature extractor changes supporting the texturing pipeline. |
Everything else is unchanged from upstream.
| Branch | Description |
|---|---|
main | Latest version — improved implementation based on the Trellis.2 backbone. |
paper | Paper version — original Direct3D-S2-based implementation reproducing the SIGGRAPH 2026 paper results. |
First set up the base TRELLIS.2 environment, then:
pip install -r requirements.txt
# Replace xx with your CUDA arch and desired build worker count
NATTEN_CUDA_ARCH="xx" NATTEN_N_WORKERS=xx pip install natten==0.21.0 --no-build-isolation
pip install https://github.com/LDYang694/Storages/releases/download/20260430/utils3d-0.0.2-py3-none-any.whl
If
flash_attnis unavailable, prefix any command withATTN_BACKEND=sdpa.
Image → 3D (generate a GLB from a single image):
python inference.py --image assets/images/0_img.png --output ./output.glb
python inference.py --image assets/images/0_img.png --output ./output.glb --low_vram # ~10-12GB VRAM
python inference.py --image assets/images/0_img.png --output ./output.glb --resolution 1024
Default resolution is 1536 (standard) or 1024 (low-VRAM); override with --resolution.
Texture an external mesh (this fork) — pose-aligned texturing of a supplied mesh from a photo:
python texture_inference.py --mesh mesh.glb --image photo.png --output ./textured.glb --low_vram
python texture_inference.py --mesh mesh.glb --image photo.png --output ./textured.glb --no_pose # skip pose alignment
python texture_inference.py --mesh mesh.glb --image photo.png --output ./textured.glb --debug_proj # dump projection overlays
Key options: --resolution (voxel grid, default 1024), --texture_size (atlas, default 2048), --fov (radians, override MoGe estimate), --bbox_padding (default 1.1).
Web demo (Gradio):
python app.py
python app.py --low_vram # or: LOW_VRAM=1 python app.py
Pixal3D is trained as a three-stage cascade, each stage progressively increasing resolution.
All stages use pixel-aligned projection conditioning and view-aligned latents (2 views by default).
Within a stage, train the lowest resolution first, then fine-tune upward by setting finetune_ckpt in the config to the previous checkpoint.
First prepare data following data_toolkit/README.md, then:
python train.py --config <CONFIG_JSON> --output_dir <OUTPUT_DIR> --data_dir '<DATA_DIR_JSON>'
--data_dir is a JSON string describing the dataset layout. Stages, configs, and required keys:
| Stage | Config prefix | Resolutions | Required data keys |
|---|---|---|---|
| 1 — Sparse Structure | ss_flow_img_dit_*_proj_finetune | 32 → 64 | base, ss_latent, render_cond |
| 2 — Shape | slat_flow_img2shape_*_proj_finetune | 256 → 512 → 1024 | base, shape_latent, render_cond |
| 3 — Texture | slat_flow_imgshape2tex_*_proj_finetune | 256 → 512 → 1024 | base, shape_latent, pbr_latent, render_cond |
Set finetune_ckpt in each higher-resolution config to the previous checkpoint.
# --- Stage 1: Sparse Structure (32 → 64) ---
python train.py --config configs/gen/ss_flow_img_dit_1_3B_32_bf16_proj_finetune.json \
--output_dir results/ss_32 \
--data_dir '{"ObjaverseXL_sketchfab": {"base": "datasets/ObjaverseXL_sketchfab", "ss_latent": "datasets/ObjaverseXL_sketchfab/ss_latents/ss_enc_conv3d_16l8_fp16_64_view", "render_cond": "datasets/ObjaverseXL_sketchfab/renders_cond"}}'
python train.py --config configs/gen/ss_flow_img_dit_1_3B_32_bf16_proj_finetune_ft64.json \
--output_dir results/ss_ft64 \
--data_dir '{"ObjaverseXL_sketchfab": {"base": "datasets/ObjaverseXL_sketchfab", "ss_latent": "datasets/ObjaverseXL_sketchfab/ss_latents/ss_enc_conv3d_16l8_fp16_64_view", "render_cond": "datasets/ObjaverseXL_sketchfab/renders_cond"}}'
# --- Stage 2: Shape (256 → 512 → 1024) ---
python train.py --config configs/gen/slat_flow_img2shape_dit_1_3B_256_bf16_proj_finetune.json \
--output_dir results/shape_256 \
--data_dir '{"ObjaverseXL_sketchfab": {"base": "datasets/ObjaverseXL_sketchfab", "shape_latent": "datasets/ObjaverseXL_sketchfab/shape_latents/shape_enc_next_dc_f16c32_fp16_256_view", "render_cond": "datasets/ObjaverseXL_sketchfab/renders_cond"}}'
# ...then _ft512 (shape_..._512_view) and _ft1024 (shape_..._1024_view) configs.
# --- Stage 3: Texture (256 → 512 → 1024) ---
python train.py --config configs/gen/slat_flow_imgshape2tex_dit_1_3B_256_bf16_proj_finetune.json \
--output_dir results/tex_256 \
--data_dir '{"ObjaverseXL_sketchfab": {"base": "datasets/ObjaverseXL_sketchfab", "shape_latent": "datasets/ObjaverseXL_sketchfab/shape_latents/shape_enc_next_dc_f16c32_fp16_256_view", "pbr_latent": "datasets/ObjaverseXL_sketchfab/pbr_latents/tex_enc_next_dc_f16c32_fp16_256_view", "render_cond": "datasets/ObjaverseXL_sketchfab/renders_cond"}}'
# ...then the _512 and _ft1024 texture configs with matching 512/1024 latent dirs.
train.py flags| Flag | Default | Purpose |
|---|---|---|
--ckpt | latest | Resume from a specific step. |
--load_dir | output_dir | Checkpoint load directory. |
--auto_retry | 3 | Retries on OOM / crash. |
--num_nodes / --node_rank | 1 / 0 | Multi-node distributed. |
--num_gpus | all | GPUs per node. |
--master_addr / --master_port | localhost / 12666 | Distributed rendezvous. |
--use_wandb | false | Enable W&B logging (--wandb_project, --wandb_name, --wandb_id). |
--tryrun | false | Dry run. |
Built upon Trellis.2, Direct3D-S2, and Trellis. Pose alignment uses MoGe-2. We sincerely thank the authors for their outstanding work.
@article{li2026pixal3d,
title={Pixal3D: Pixel-Aligned 3D Generation from Images},
author={Li, Dong-Yang and Zhao, Wang and Chen, Yuxin and Hu, Wenbo and Guo, Meng-Hao and Zhang, Fang-Lue and Shan, Ying and Hu, Shi-Min},
journal={arXiv preprint arXiv:2605.10922},
year={2026}
}
Released under the MIT License. Third-party components remain under their original terms; see NOTICE.
Modified version of Pixal3D that supports a separate texture gen pipeline
Python
0
0 commits
updated Jul 5, 2026
Dong-Yang Li¹ · Wang Zhao²* · Yuxin Chen² · Wenbo Hu² · Meng-Hao Guo¹ · Fang-Lue Zhang³ · Ying Shan² · Shi-Min Hu¹✉
¹Tsinghua University (BNRist) ²Tencent ARC Lab ³Victoria University of Wellington
*Project lead ✉Corresponding author
Pixal3D generates high-fidelity 3D assets from a single image. Instead of loosely injecting image features via attention, it explicitly lifts pixel features into 3D through back-projection, establishing direct pixel-to-3D correspondences.
This is a fork of the original Pixal3D repo that adds texture-only inference with automatic pose alignment: texturing an externally-supplied mesh (e.g. a Hunyuan3D output) from a single photo, even when the photo is not shot from the mesh's canonical front.
Added files
| File | Purpose |
|---|---|
texture_inference.py | CLI entry point: texture an external mesh from a photo. |
pixal3d/pipelines/pixal3d_texturing.py | Texturing pipeline (proj-mode texture DIT on an external mesh). |
pixal3d/utils/pose_utils.py | Confidence-gated photo↔mesh rotation estimation from MoGe-2 point maps. |
visualize_voxels.py | Export a .pt voxel-field dump to .ply for inspection. |
Modified files
| File | Change |
|---|---|
pixal3d/pipelines/__init__.py | Registers Pixal3DTexturingPipeline. |
pixal3d/trainers/flow_matching/mixins/image_conditioned_proj.py | Proj-feature extractor changes supporting the texturing pipeline. |
Everything else is unchanged from upstream.
| Branch | Description |
|---|---|
main | Latest version — improved implementation based on the Trellis.2 backbone. |
paper | Paper version — original Direct3D-S2-based implementation reproducing the SIGGRAPH 2026 paper results. |
First set up the base TRELLIS.2 environment, then:
pip install -r requirements.txt
# Replace xx with your CUDA arch and desired build worker count
NATTEN_CUDA_ARCH="xx" NATTEN_N_WORKERS=xx pip install natten==0.21.0 --no-build-isolation
pip install https://github.com/LDYang694/Storages/releases/download/20260430/utils3d-0.0.2-py3-none-any.whl
If
flash_attnis unavailable, prefix any command withATTN_BACKEND=sdpa.
Image → 3D (generate a GLB from a single image):
python inference.py --image assets/images/0_img.png --output ./output.glb
python inference.py --image assets/images/0_img.png --output ./output.glb --low_vram # ~10-12GB VRAM
python inference.py --image assets/images/0_img.png --output ./output.glb --resolution 1024
Default resolution is 1536 (standard) or 1024 (low-VRAM); override with --resolution.
Texture an external mesh (this fork) — pose-aligned texturing of a supplied mesh from a photo:
python texture_inference.py --mesh mesh.glb --image photo.png --output ./textured.glb --low_vram
python texture_inference.py --mesh mesh.glb --image photo.png --output ./textured.glb --no_pose # skip pose alignment
python texture_inference.py --mesh mesh.glb --image photo.png --output ./textured.glb --debug_proj # dump projection overlays
Key options: --resolution (voxel grid, default 1024), --texture_size (atlas, default 2048), --fov (radians, override MoGe estimate), --bbox_padding (default 1.1).
Web demo (Gradio):
python app.py
python app.py --low_vram # or: LOW_VRAM=1 python app.py
Pixal3D is trained as a three-stage cascade, each stage progressively increasing resolution.
All stages use pixel-aligned projection conditioning and view-aligned latents (2 views by default).
Within a stage, train the lowest resolution first, then fine-tune upward by setting finetune_ckpt in the config to the previous checkpoint.
First prepare data following data_toolkit/README.md, then:
python train.py --config <CONFIG_JSON> --output_dir <OUTPUT_DIR> --data_dir '<DATA_DIR_JSON>'
--data_dir is a JSON string describing the dataset layout. Stages, configs, and required keys:
| Stage | Config prefix | Resolutions | Required data keys |
|---|---|---|---|
| 1 — Sparse Structure | ss_flow_img_dit_*_proj_finetune | 32 → 64 | base, ss_latent, render_cond |
| 2 — Shape | slat_flow_img2shape_*_proj_finetune | 256 → 512 → 1024 | base, shape_latent, render_cond |
| 3 — Texture | slat_flow_imgshape2tex_*_proj_finetune | 256 → 512 → 1024 | base, shape_latent, pbr_latent, render_cond |
Set finetune_ckpt in each higher-resolution config to the previous checkpoint.
# --- Stage 1: Sparse Structure (32 → 64) ---
python train.py --config configs/gen/ss_flow_img_dit_1_3B_32_bf16_proj_finetune.json \
--output_dir results/ss_32 \
--data_dir '{"ObjaverseXL_sketchfab": {"base": "datasets/ObjaverseXL_sketchfab", "ss_latent": "datasets/ObjaverseXL_sketchfab/ss_latents/ss_enc_conv3d_16l8_fp16_64_view", "render_cond": "datasets/ObjaverseXL_sketchfab/renders_cond"}}'
python train.py --config configs/gen/ss_flow_img_dit_1_3B_32_bf16_proj_finetune_ft64.json \
--output_dir results/ss_ft64 \
--data_dir '{"ObjaverseXL_sketchfab": {"base": "datasets/ObjaverseXL_sketchfab", "ss_latent": "datasets/ObjaverseXL_sketchfab/ss_latents/ss_enc_conv3d_16l8_fp16_64_view", "render_cond": "datasets/ObjaverseXL_sketchfab/renders_cond"}}'
# --- Stage 2: Shape (256 → 512 → 1024) ---
python train.py --config configs/gen/slat_flow_img2shape_dit_1_3B_256_bf16_proj_finetune.json \
--output_dir results/shape_256 \
--data_dir '{"ObjaverseXL_sketchfab": {"base": "datasets/ObjaverseXL_sketchfab", "shape_latent": "datasets/ObjaverseXL_sketchfab/shape_latents/shape_enc_next_dc_f16c32_fp16_256_view", "render_cond": "datasets/ObjaverseXL_sketchfab/renders_cond"}}'
# ...then _ft512 (shape_..._512_view) and _ft1024 (shape_..._1024_view) configs.
# --- Stage 3: Texture (256 → 512 → 1024) ---
python train.py --config configs/gen/slat_flow_imgshape2tex_dit_1_3B_256_bf16_proj_finetune.json \
--output_dir results/tex_256 \
--data_dir '{"ObjaverseXL_sketchfab": {"base": "datasets/ObjaverseXL_sketchfab", "shape_latent": "datasets/ObjaverseXL_sketchfab/shape_latents/shape_enc_next_dc_f16c32_fp16_256_view", "pbr_latent": "datasets/ObjaverseXL_sketchfab/pbr_latents/tex_enc_next_dc_f16c32_fp16_256_view", "render_cond": "datasets/ObjaverseXL_sketchfab/renders_cond"}}'
# ...then the _512 and _ft1024 texture configs with matching 512/1024 latent dirs.
train.py flags| Flag | Default | Purpose |
|---|---|---|
--ckpt | latest | Resume from a specific step. |
--load_dir | output_dir | Checkpoint load directory. |
--auto_retry | 3 | Retries on OOM / crash. |
--num_nodes / --node_rank | 1 / 0 | Multi-node distributed. |
--num_gpus | all | GPUs per node. |
--master_addr / --master_port | localhost / 12666 | Distributed rendezvous. |
--use_wandb | false | Enable W&B logging (--wandb_project, --wandb_name, --wandb_id). |
--tryrun | false | Dry run. |
Built upon Trellis.2, Direct3D-S2, and Trellis. Pose alignment uses MoGe-2. We sincerely thank the authors for their outstanding work.
@article{li2026pixal3d,
title={Pixal3D: Pixel-Aligned 3D Generation from Images},
author={Li, Dong-Yang and Zhao, Wang and Chen, Yuxin and Hu, Wenbo and Guo, Meng-Hao and Zhang, Fang-Lue and Shan, Ying and Hu, Shi-Min},
journal={arXiv preprint arXiv:2605.10922},
year={2026}
}
Released under the MIT License. Third-party components remain under their original terms; see NOTICE.