PhyCo-Sim

June 8, 2026 · View on GitHub

Simulation data generation pipeline for PhyCo: Learning Controllable Physical Priors for Generative Motion (CVPR 2026).

PhyCo-Sim generates annotated physics simulation videos with precise control over physical properties — friction, restitution, deformation, and applied forces. It extends Kubric with soft body simulation, force application, texture randomization, and rich per-frame metadata export.

Example simulation outputs showing friction, restitution, deformation, and force scenarios

The released PhyCo-Sim dataset on HuggingFace contains ~27.5 GB of videos generated with this pipeline.


Table of Contents


What's New Over Kubric

Kubric was designed primarily for rigid body scenes. We extend it with:

  • Soft body simulation — deformable objects with mass-spring and Neo-Hookean material models
  • Force application — apply forces, torques, and impulses at any simulation frame
  • Fine-grained physics control — friction, restitution, stiffness, force magnitude all exposed as CLI arguments
  • Texture randomization — PBR textures (wood, concrete, brick, etc.) randomly sampled for visual diversity
  • HDRI environment lighting — realistic ambient lighting and backgrounds
  • Rich metadata export — per-object physics, camera parameters, forces, and per-frame states as JSON
  • Scalable execution — multi-GPU parallel runners and SLURM orchestrator

For a detailed breakdown, see docs/WHATS_NEW_OVER_KUBRIC.md.


Released Scenarios

Each row is one entry in the PhyCo-Sim HuggingFace dataset.

ScenarioDescriptionVaried PropertyLaunch Script
ball_drop_v2Rigid ball falling onto a platform and bouncingBounciness (restitution)ball_drop_v2_parallel.sh
ball_drop_v3Multiple rigid balls (3–5) dropping simultaneouslyBounciness (restitution)ball_drop_v3_parallel.sh
ball_drop_soft_v4Deformable elastic ball falling onto a surfaceDeformation stiffnessball_drop_soft_v4_parallel.sh
ball_wall_collisionBall rolling into a wall and bouncing backBounciness (restitution)ball_wall_collision_parallel.sh
cube_deform_soft_v2_noeffRigid ball impacting a soft elastic cubeDeformation stiffnesscube_deform_soft_v2_parallel.sh
friction_slide_flat_v2Rectangular brick sliding on a flat surfaceFriction, slide directionfriction_slide_flat_parallel.sh
friction_slide_flat_force_v3Brick sliding under an applied forceForce magnitude, directionfriction_slide_flat_force_parallel.sh
jenga_forceForce applied to a single block in a Jenga towerPush directionjenga_force_parallel.sh
pool_table_forceForce applied to a ball on a billiards tableForce, direction, friction, bouncinesspool_table_force_parallel.sh

Each launcher invokes the corresponding src/run_*.py scenario through src/run_parallel_*.py, which manages a ThreadPoolExecutor and per-worker GPU assignment.


Installation

See docs/INSTALLATION.md for the full guide. Quick version, from the repo root:

bash setup_scripts/setup_kubric_no_docker.sh

This downloads Blender 3.4 next to the repo and installs all deps into Blender's bundled Python 3.10. Use the printed Python path as --python_path for every launcher.


Texture Assets

Scenarios randomize ground/object PBR materials sampled from four texture categories. The textures are not included in this repository — download them yourself from Poly Haven, which is CC0-licensed and uses the exact filename convention the loaders expect.

Pick any number of assets from each Poly Haven category (more = more visual diversity):

CategoryPoly Haven pageLives under
Woodhttps://polyhaven.com/textures/wood$SIM_ASSETS_DIR/wood_textures/
Concretehttps://polyhaven.com/textures/concrete$SIM_ASSETS_DIR/concrete_textures/
Brickhttps://polyhaven.com/textures/brick$SIM_ASSETS_DIR/brick_textures/
Groundhttps://polyhaven.com/textures/floor$SIM_ASSETS_DIR/ground_textures/

Download settings: choose 4K resolution and the default .zip package — the loader looks for files matching *_diff_4k.jpg, *_nor_gl_4k.exr, *_rough_4k.{jpg,exr}, and *_disp_4k.{jpg,png}, which is exactly Poly Haven's naming convention.

Required directory layout — each asset's folder name must end in .blend (the loader filters on that suffix). Unzip the Poly Haven download into <asset_name>.blend/textures/:

$SIM_ASSETS_DIR/
  wood_textures/
    wood_planks_4k.blend/
      textures/
        wood_planks_diff_4k.jpg
        wood_planks_nor_gl_4k.exr
        wood_planks_rough_4k.jpg
        wood_planks_disp_4k.png
    weathered_planks_4k.blend/
      textures/
        ...
  concrete_textures/
    rough_concrete_4k.blend/
      textures/
        ...
  brick_textures/
    ...
  ground_textures/
    ...

If you already downloaded plain Poly Haven zips into folders like wood_planks_4k/, rename them with one line:

cd "$SIM_ASSETS_DIR/wood_textures"
for d in */; do mv "${d%/}" "${d%/}.blend"; done
# repeat for concrete_textures/, brick_textures/, ground_textures/

Then point the run scripts at the directory:

export SIM_ASSETS_DIR="$PWD/sim_assets"

HDRIs for environment lighting are fetched at runtime from gs://kubric-public/assets/HDRI_haven/ (also Poly Haven, mirrored by the Kubric team) — no manual download needed.

Tetrahedral soft-body meshes are included in objs/; see the Soft Body Guide for regenerating them.


Running Simulations

Set PYTHON_PATH to the Blender Python printed by the setup script:

PYTHON_PATH=../blender-3.4.0-linux-x64/3.4/python/bin/python3.10

Single video

Each src/run_*.py is self-contained:

"$PYTHON_PATH" src/run_ball_drop_v2.py --help

Parallel multi-GPU

Use the per-scenario launcher:

bash scripts/launch/ball_drop_v3_parallel.sh \
  --python_path "$PYTHON_PATH" \
  --num_workers 8 \
  --num_videos 500 \
  --output_dir ./output/ball_drop_v3

SLURM cluster

Wrap any launcher with the orchestrator:

bash scripts/launch/generic_slurm_orchestrator_v2.sh \
  --script scripts/launch/friction_slide_flat_force_parallel.sh \
  --total_num_videos 15000 \
  --partition gpu \
  --script_args "--python_path $PYTHON_PATH"

See docs/SLURM.md for orchestrator options.


Output Format

Each simulation produces a directory containing:

output/<scenario>/<uuid>/
  rgba_00001.png          # RGB frames
  ...
  segmentation_00001.png  # Instance segmentation masks
  ...
  depth_00001.tiff        # Depth maps
  ...
  metadata.json           # Full scene metadata (see below)
  rgb_video.mp4
  segmentation_video.mp4
  depth_video.mp4

Metadata JSON

{
  "scene": { "resolution": [768, 432], "frame_start": 1, "frame_end": 97, "fps": 24 },
  "camera": {
    "position": [x, y, z],
    "quaternion": [w, x, y, z],
    "intrinsics": [[...], [...], [...]],
    "focal_length": 35.0
  },
  "objects": [
    {
      "asset_id": "ball",
      "position": [x, y, z],
      "mass": 1.0, "friction": 0.5, "restitution": 0.8,
      "segmentation_id": 1,
      "neo_hookean_mu": null,
      "spring_elastic_stiffness": null
    }
  ],
  "forces": [
    { "magnitude": 5.0, "direction": [fx, fy, fz],
      "application_point": [px, py, pz], "frame": 10 }
  ]
}

Project Structure

vidgensim/
  src/
    run_*.py                  # 9 scenario scripts
    run_parallel_*.py         # parallel execution wrappers
    config.py                 # ScenarioConfig / DominoConfig
    kubric_utils.py           # camera, metadata, video helpers
  kubric/                     # vendored, modified Kubric framework
    kubric/core/objects.py        # + SoftBody class
    kubric/simulator/pybullet.py  # + soft body loading, force API
    kubric/renderer/blender.py    # + soft body rendering, HDRI support
  scripts/
    launch/                   # 9 scenario launchers + generic_slurm_orchestrator_v2.sh
    create_urdf_for_obj.py    # URDF generator for custom meshes
    tetgen_processor.py       # tet mesh processing for soft bodies
  objs/                       # mesh assets (OBJ, URDF, VTK)
  setup_scripts/
    setup_kubric_no_docker.sh
  docs/                       # all guides

Soft Body Guide

Soft body simulations require tetrahedral meshes (.vtk) for PyBullet and surface meshes (.obj) for Blender rendering.

Material modelBest forKey parameters
Mass-SpringGeneral deformables, cloth-likespring_elastic_stiffness, spring_damping_stiffness, spring_bending_stiffness
Neo-HookeanRubber, elasticneo_hookean_mu, neo_hookean_lambda, neo_hookean_damping

To regenerate tet meshes from surface OBJs, use scripts/tetgen_processor.py. Full details in docs/SOFT_BODY_GUIDE.md and the OBJ↔VTK mapping in docs/TRI_TO_TET_MAPPING.md.


GPU Rendering

Set KUBRIC_USE_GPU=true (the launchers already do). Persist the Cycles kernel cache at ~/.cache/cycles/kernels to avoid recompilation across runs. See docs/EFFICIENT_RENDERING.md for the motion-detect frame-reuse optimization.


Citation

If you find PhyCo-Sim useful in your research, please cite:

@inproceedings{narayanan2026phyco,
    title={PhyCo: Learning Controllable Physical Priors for Generative Motion},
    author={Narayanan, Sriram and Jiang, Ziyu and Narasimhan, Srinivasa G. and Chandraker, Manmohan},
    booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
    year={2026}
}

Acknowledgements

This project builds on Kubric by Google Research which is released under the Apache License 2.0.


License

PhyCo-Sim is released under the Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0) license — see LICENSE.