code: def render_hybrid_nerf_multi_persons(
      bkg_model,
      cap,
      human_models,
      posed_verts,
      faces,
      Ts,
      rays_per_batch=32768,
      samples_per_ray=64,
      importance_samples_per_ray=128,
      white_bkg=True,
      geo_threshold=DEFAULT_GEO_THRESH,
      return_depth=False,
  ):
      device = next(bkg_model.parameters()).device
  
      def build_batch(origins, dirs, near, far):
          if isinstance(origins, torch.Tensor):
              ray_batch = {
                  "origin": (origins).float().to(device),
                  "direction": (dirs).float().to(device),
                  "near": (near[..., None]).float().to(device),
                  "far": (far[..., None]).float().to(device),
              }
          else:
              ray_batch = {
                  "origin": torch.from_numpy(origins)
                  .float()
                  .to(device),
                  "direction": torch.from_numpy(dirs)
                  .float()
                  .to(device),
                  "near": torch.from_numpy(near[..., None])
                  .float()
                  .to(device),
                  "far": torch.from_numpy(far[..., None])
                  .float()
                  .to(device),
              }
          return ray_batch
  
      with torch.set_grad_enabled(False):
          coords = np.argwhere(np.ones(cap.shape))[:, ::-1]
          origins, dirs = ray_utils.shot_rays(cap, coords)
          total_rays = origins.shape[0]
          total_rgb_map = []
          total_depth_map = []
          for i in range(0, total_rays, rays_per_batch):
              print(f"{i} / {total_rays}")
              bkg_ray_batch = build_batch(
                  origins[i : i + rays_per_batch],
                  dirs[i : i + rays_per_batch],
                  np.array(
                      [cap.near["bkg"]]
                      * origins[i : i + rays_per_batch].shape[0]
                  ),
                  np.array(
                      [cap.far["bkg"]]
                      * origins[i : i + rays_per_batch].shape[0]
                  ),
              )
              bkg_pts, bkg_dirs, bkg_z_vals = ray_utils.ray_to_samples(
                  bkg_ray_batch, samples_per_ray, device=device
              )
              bkg_out = bkg_model.coarse_bkg_net(bkg_pts, bkg_dirs)
              if bkg_model.fine_bkg_net is not None:
                  _, _, _, bkg_weights, _ = raw2outputs(
                      bkg_out,
                      bkg_z_vals,
                      bkg_dirs[:, 0, :],
                      white_bkg=white_bkg,
                  )
                  (
                      bkg_pts,
                      bkg_dirs,
                      bkg_z_vals,
                  ) = ray_utils.ray_to_importance_samples(
                      bkg_ray_batch,
                      bkg_z_vals,
                      bkg_weights,
                      importance_samples_per_ray,
                      device=device,
                  )
                  bkg_out = bkg_model.fine_bkg_net(bkg_pts, bkg_dirs)
              human_out_dict = {
                  "out": [],
                  "z_val": [],
              }
              for _net, _posed_verts, _faces, _Ts in zip(
                  human_models, posed_verts, faces, Ts
              ):
                  (
                      temp_near,
                      temp_far,
                  ) = ray_utils.geometry_guided_near_far(
                      origins[i : i + rays_per_batch],
                      dirs[i : i + rays_per_batch],
                      _posed_verts,
                      geo_threshold,
                  )
                  # generate ray samples
                  num_empty_rays = bkg_pts.shape[0]
                  empty_human_out = torch.zeros(
                      [num_empty_rays, samples_per_ray, 4],
                      device=device,
                  )
                  empty_human_z_vals = torch.stack(
                      [
                          torch.linspace(
                              cap.far["bkg"] * 2,
                              cap.far["bkg"] * 3,
                              samples_per_ray,
                          )
                      ]
                      * num_empty_rays
                  ).to(device)
                  if (temp_near < temp_far).any():
                      human_ray_batch = build_batch(
                          origins[i : i + rays_per_batch][
                              temp_near < temp_far
                          ],
                          dirs[i : i + rays_per_batch][
                              temp_near < temp_far
                          ],
                          temp_near[temp_near < temp_far],
                          temp_far[temp_near < temp_far],
                      )
                      (
                          human_pts,
                          human_dirs,
                          human_z_vals,
                      ) = ray_utils.ray_to_samples(
                          human_ray_batch,
                          samples_per_ray,
                          device=device,
                      )
                      (
                          can_pts,
                          can_dirs,
                          _,
                      ) = ray_utils.warp_samples_to_canonical(
                          human_pts.cpu().numpy(),
                          _posed_verts,
                          _faces,
                          _Ts,
                      )
                      can_pts = (
                          torch.from_numpy(can_pts).to(device).float()
                      )
                      can_dirs = (
                          torch.from_numpy(can_dirs).to(device).float()
                      )
                      human_out = _net.coarse_human_net(
                          can_pts, can_dirs
                      )
                      empty_human_out[temp_near < temp_far] = human_out
                      empty_human_z_vals[
                          temp_near < temp_far
                      ] = human_z_vals
                  human_out_dict["out"].append(empty_human_out)
                  human_out_dict["z_val"].append(empty_human_z_vals)
              coarse_total_zvals, coarse_order = torch.sort(
                  torch.cat(
                      [
                          bkg_z_vals,
                          torch.cat(human_out_dict["z_val"], 1),
                      ],
                      -1,
                  ),
                  -1,
              )
              coarse_total_out = torch.cat(
                  [bkg_out, torch.cat(human_out_dict["out"], 1)], 1
              )
              _b, _n, _c = coarse_total_out.shape
              coarse_total_out = coarse_total_out[
                  torch.arange(_b).view(_b, 1, 1).repeat(1, _n, _c),
                  coarse_order.view(_b, _n, 1).repeat(1, 1, _c),
                  torch.arange(_c).view(1, 1, _c).repeat(_b, _n, 1),
              ]
              rgb_map, _, _, _, depth_map = raw2outputs(
                  coarse_total_out,
                  coarse_total_zvals,
                  bkg_dirs[:, 0, :],
                  white_bkg=white_bkg,
              )
              total_rgb_map.append(rgb_map)
              total_depth_map.append(depth_map)
          total_rgb_map = (
              torch.cat(total_rgb_map)
              .reshape(*cap.shape, -1)
              .detach()
              .cpu()
              .numpy()
          )
          total_depth_map = (
              torch.cat(total_depth_map)
              .reshape(*cap.shape)
              .detach()
              .cpu()
              .numpy()
          )
          if return_depth:
              return total_rgb_map, total_depth_map
          return total_rgb_map
  
file_path: ml-neuman/utils/render_utils.py
imports: import random
  import numpy
  import torch
  import torch.nn.functional
  from pytorch3d.structures import Meshes
  from pytorch3d.renderer import RasterizationSettings, MeshRenderer, MeshRasterizer, HardPhongShader, PointLights, TexturesVertex, PerspectiveCameras
  from PIL import Image
  from cameras.camera_pose import CameraPose
  from utils import ray_utils
  from utils.constant import DEFAULT_GEO_THRESH
  from geometry import transformations
label_desc: Use image node_id 7 for calling a global function with example usage: render_hybrid_nerf_multi_persons(bkg_model, cap, human_models, posed_verts, faces, Ts, rays_per_batch, samples_per_ray, importance_samples_per_ray, white_bkg, geo_threshold, return_depth) and returns: ray_batch, total_rgb_map, total_rgb_map,  total_depth_map