6 minute read

https://github.com/Anttwo/SuGaR/blob/main/view_sugar_results.ipynb

SuGaR์—์„œ mesh๋ฅผ loadํ•˜๊ณ  Phong Shading์„ ์‚ฌ์šฉํ•˜์—ฌ Renderingํ•˜๋Š” ์ „์ฒด ํ”„๋กœ์„ธ์Šค๋ฅผ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค.

๋ณธ ipynb ์ฝ”๋“œ์—์„œ๋Š” pytorch3d๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

import os
import torch
import numpy as np
import matplotlib.pyplot as plt
import open3d as o3d
from pytorch3d.io import load_objs_as_meshes
from pytorch3d.renderer import (
    AmbientLights,
    RasterizationSettings, 
    MeshRenderer, 
    MeshRasterizer,  
    SoftPhongShader,
    )
from pytorch3d.renderer.blending import BlendParams
from sugar_scene.gs_model import GaussianSplattingWrapper
from sugar_scene.sugar_model import SuGaR, load_refined_model
from sugar_utils.spherical_harmonics import SH2RGB

๋จผ์ € ๊ฐ pytorch3d์˜ ๊ตฌ์„ฑ์š”์†Œ์˜ ์˜๋ฏธ๋ฅผ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค.

Pytorch3D ๊ตฌ์„ฑ ์š”์†Œ ํ•ด์„

AmbientLights

3D ์”ฌ์— ๋Œ€ํ•œ ์ฃผ๋ณ€ ์กฐ๋ช…์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์”ฌ ์ „์ฒด์— ๊ท ์ผํ•œ ์กฐ๋ช…์„ ์ ์šฉํ•˜์—ฌ ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ์ผ์ •ํ•œ ๋ฐ๊ธฐ๋กœ ๋ Œ๋”๋ง๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

from pytorch3d.renderer import AmbientLights

# 3D ์”ฌ์— ๋Œ€ํ•œ ์ฃผ๋ณ€ ์กฐ๋ช…์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
# ๊ธฐ๋ณธ์ ์œผ๋กœ ์”ฌ ์ „์ฒด์— ๊ท ์ผํ•œ ์กฐ๋ช…์„ ์ ์šฉํ•˜์—ฌ ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ์ผ์ •ํ•œ ๋ฐ๊ธฐ๋กœ ๋ Œ๋”๋ง๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
lights = AmbientLights()

RasterizationSettings

๋ฉ”์‰ฌ๋ฅผ ๋ž˜์Šคํ„ฐํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์„ค์ •์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ์ด๋ฏธ์ง€ ํฌ๊ธฐ, ํ”ฝ์…€ ํฌ๊ธฐ, ์•ˆํ‹ฐ์•จ๋ฆฌ์–ด์‹ฑ ๋“ฑ์„ ํฌํ•จํ•œ ๋‹ค์–‘ํ•œ ์„ค์ •์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

from pytorch3d.renderer import RasterizationSettings

# ๋ฉ”์‰ฌ๋ฅผ ๋ž˜์Šคํ„ฐํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์„ค์ •์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
# ์—ฌ๊ธฐ์—๋Š” ์ด๋ฏธ์ง€ ํฌ๊ธฐ, ํ”ฝ์…€ ํฌ๊ธฐ, ์•ˆํ‹ฐ์•จ๋ฆฌ์–ด์‹ฑ ๋“ฑ์„ ํฌํ•จํ•œ ๋‹ค์–‘ํ•œ ์„ค์ •์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
mesh_raster_settings = RasterizationSettings(
    image_size=(refined_sugar.image_height, refined_sugar.image_width),
    blur_radius=0.0, 
    faces_per_pixel=faces_per_pixel,
    # max_faces_per_bin=max_faces_per_bin
)

MeshRenderer, MeshRasterizer, SoftPhongShader

๋ฉ”์‰ฌ๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•œ ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค.

  • MeshRenderer: ๋ฉ”์‰ฌ๋ฅผ ๋ž˜์Šคํ„ฐํ™”ํ•˜๊ณ  ์…ฐ์ด๋”ฉ์„ ์ ์šฉํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ „์ฒด ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์ž…๋‹ˆ๋‹ค.
  • MeshRasterizer: ๋ฉ”์‰ฌ๋ฅผ ๋ž˜์Šคํ„ฐํ™”ํ•˜์—ฌ 2D ์ด๋ฏธ์ง€์— ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.
  • SoftPhongShader: Phong ์…ฐ์ด๋”ฉ ๋ชจ๋ธ์„ ์ ์šฉํ•˜์—ฌ ๋งค๋„๋Ÿฌ์šด ํ‘œ๋ฉด์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
from pytorch3d.renderer import MeshRenderer, MeshRasterizer, SoftPhongShader

# ๋ฉ”์‰ฌ๋ฅผ ๋ Œ๋”๋งํ•˜๊ธฐ ์œ„ํ•œ ๊ตฌ์„ฑ ์š”์†Œ์ž…๋‹ˆ๋‹ค.
# MeshRenderer: ๋ฉ”์‰ฌ๋ฅผ ๋ž˜์Šคํ„ฐํ™”ํ•˜๊ณ  ์…ฐ์ด๋”ฉ์„ ์ ์šฉํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ „์ฒด ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์ž…๋‹ˆ๋‹ค.
# MeshRasterizer: ๋ฉ”์‰ฌ๋ฅผ ๋ž˜์Šคํ„ฐํ™”ํ•˜์—ฌ 2D ์ด๋ฏธ์ง€์— ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.
# SoftPhongShader: Phong ์…ฐ์ด๋”ฉ ๋ชจ๋ธ์„ ์ ์šฉํ•˜์—ฌ ๋งค๋„๋Ÿฌ์šด ํ‘œ๋ฉด์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
rasterizer = MeshRasterizer(raster_settings=raster_settings)
shader = SoftPhongShader(device=device, lights=lights)

renderer = MeshRenderer(rasterizer=rasterizer, shader=shader)

BlendParams

3D ๊ฐ์ฒด๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ์˜ ํ˜ผํ•ฉ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๋กœ ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ๊ณผ ๊ด€๋ จ๋œ ์„ค์ •์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

from pytorch3d.renderer.blending import BlendParams

# 3D ๊ฐ์ฒด๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ์˜ ํ˜ผํ•ฉ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
# ์ฃผ๋กœ ์•ŒํŒŒ ๋ธ”๋ Œ๋”ฉ๊ณผ ๊ด€๋ จ๋œ ์„ค์ •์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
blend_params=BlendParams(background_color=(1.0, 1.0, 1.0))

BlendParams ํ•ด์„

  • background_color: (1.0, 1.0, 1.0)๋กœ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ด๋Š” ๋ Œ๋”๋ง๋œ ์ด๋ฏธ์ง€์˜ ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ์„ ํฐ์ƒ‰์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  • sigma (๊ธฐ๋ณธ๊ฐ’: 1e-4): ํด๋ฆฌ๊ณค์˜ ๊ฒฝ๊ณ„ ๊ฐ€์‹œ์„ฑ์„ ์ œ์–ดํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ์ž…๋‹ˆ๋‹ค. ๊ฐ’์ด ์ž‘์„์ˆ˜๋ก ๊ฒฝ๊ณ„๊ฐ€ ๋” ๋šœ๋ ทํ•ด์ง‘๋‹ˆ๋‹ค.
  • gamma (๊ธฐ๋ณธ๊ฐ’: 1e-4): ๋ธ”๋ Œ๋”ฉ์—์„œ ํด๋ฆฌ๊ณค์˜ ๊ฐ€์žฅ์ž๋ฆฌ ํˆฌ๋ช…๋„๋ฅผ ์ œ์–ดํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ์ž…๋‹ˆ๋‹ค. ๊ฐ’์ด ํด์ˆ˜๋ก ๊ฒฝ๊ณ„๊ฐ€ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋ธ”๋ Œ๋”ฉ๋ฉ๋‹ˆ๋‹ค.

๊ธฐํƒ€ ๋ชจ๋“ˆ

  • GaussianSplattingWrapper: ์ด๋Š” sugar_scene.gs_model ๋ชจ๋“ˆ์—์„œ ๊ฐ€์ ธ์˜จ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. Gaussian splatting ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ 3D ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ž˜ํผ๋กœ ์ถ”์ •๋ฉ๋‹ˆ๋‹ค.
  • SuGaR ๋ฐ load_refined_model: sugar_scene.sugar_model ๋ชจ๋“ˆ์—์„œ ๊ฐ€์ ธ์˜จ SuGaR ํด๋ž˜์Šค์™€ load_refined_model ํ•จ์ˆ˜๋Š” SuGaR ๋ชจ๋ธ์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ํ•™์Šต๋œ ๋ชจ๋ธ์„ ๋กœ๋“œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  • SH2RGB: sugar_utils.spherical_harmonics ๋ชจ๋“ˆ์—์„œ ๊ฐ€์ ธ์˜จ ํ•จ์ˆ˜๋กœ, ๊ตฌ๋ฉด ์กฐํ™” ํ•จ์ˆ˜(Spherical Harmonics)๋ฅผ RGB ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ SuGaR์—์„œ 3D mesh๋ฅผ loadํ•˜๊ณ  Phong Shading์„ ์‚ฌ์šฉํ•˜์—ฌ Renderingํ•˜๋Š” ์ „์ฒด ํ”„๋กœ์„ธ์Šค๋ฅผ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค.

์ „์ฒด ์ฝ”๋“œ๋Š” ๊ฑด๋„ˆ๋›ฐ๊ณ , Traditional Color Texture๋ฅผ ์‚ฌ์šฉํ•œ Rendering ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ ์ดํ•ดํ•ด๋ด…์‹œ๋‹ค.

์ „ํ†ต์ ์ธ ์ปฌ๋Ÿฌ ํ…์Šค์ฒ˜๋ฅผ ์‚ฌ์šฉํ•œ ๋ Œ๋”๋ง

์ „ํ†ต์ ์ธ ์ปฌ๋Ÿฌ ํ…์Šค์ฒ˜๋ฅผ ์‚ฌ์šฉํ•œ ๋ Œ๋”๋ง์€ 3D ๋ฉ”์‹œ์˜ ํ‘œ๋ฉด์— ์ƒ‰์ƒ์„ ์ ์šฉํ•˜์—ฌ ์‹œ๊ฐ์ ์œผ๋กœ ๋” ํ˜„์‹ค๊ฐ ์žˆ๋Š” ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์€ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  1. ๋ฉ”์‹œ ๋กœ๋“œ: 3D ๋ชจ๋ธ์„ ํŒŒ์ผ์—์„œ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, load_objs_as_meshes ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ .obj ํŒŒ์ผ ํ˜•์‹์˜ ๋ฉ”์‹œ๋ฅผ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.
  2. ํ…์Šค์ฒ˜ ๋งคํ•‘: ๋กœ๋“œ๋œ ๋ฉ”์‹œ์— ์ƒ‰์ƒ ์ •๋ณด๋ฅผ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค. ํ…์Šค์ฒ˜ ๋งคํ•‘์€ ๋ฉ”์‹œ์˜ ๊ฐ ํด๋ฆฌ๊ณค์— ์ƒ‰์ƒ์„ ํ• ๋‹นํ•˜์—ฌ ๋ฉ”์‹œ์˜ ํ‘œ๋ฉด์— ๊ทธ๋ฆผ์ด๋‚˜ ํŒจํ„ด์„ ์ž…ํžˆ๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค.
  3. ๋ Œ๋” ์„ค์ •: ๋ Œ๋”๋ง ์„ค์ •์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์นด๋ฉ”๋ผ ์œ„์น˜, ์กฐ๋ช… ์„ค์ •, ๋ ˆ์Šคํ„ฐ ์„ค์ • ๋“ฑ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  4. ๋ Œ๋”๋ง: ์„ค์ •๋œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฉ”์‹œ๋ฅผ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ๋ฉ”์‹œ์˜ ํ‘œ๋ฉด์— ์ ์šฉ๋œ ํ…์Šค์ฒ˜๊ฐ€ ๊ณ ๋ ค๋˜์–ด ์ตœ์ข… ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  5. ์‹œ๊ฐํ™”: ๋ Œ๋”๋ง๋œ ์ด๋ฏธ์ง€๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. matplotlib ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€๋ฅผ ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • faces_per_pixel์€ ํ”ฝ์…€๋‹น ๋ Œ๋”๋งํ•  ํด๋ฆฌ๊ณค์˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋ Œ๋”๋ง ์‹œ๊ฐํ™”์˜ ์ •๋ฐ€๋„์™€ ์ง์ ‘์ ์œผ๋กœ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋†’์€ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ํ”ฝ์…€๋‹น ๋” ๋งŽ์€ ํด๋ฆฌ๊ณค์„ ๊ณ ๋ คํ•˜์—ฌ ๋ Œ๋”๋งํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ด๋Š” ๋” ์„ธ๋ฐ€ํ•œ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋Œ€๋กœ, ๋‚ฎ์€ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ํ”ฝ์…€๋‹น ๊ณ ๋ ค๋˜๋Š” ํด๋ฆฌ๊ณค์˜ ์ˆ˜๊ฐ€ ์ค„์–ด๋“ค์–ด ๋ Œ๋”๋ง ์†๋„๋Š” ๋นจ๋ผ์ง€์ง€๋งŒ ์ •๋ฐ€๋„๊ฐ€ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • max_faces_per_bin์€ ๋ ˆ์Šคํ„ฐํ™” ๊ณผ์ •์—์„œ ๊ฐ โ€œbinโ€์— ํฌํ•จ๋  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ํด๋ฆฌ๊ณค ์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. โ€œBinโ€์€ ๋ Œ๋”๋ง ๊ณต๊ฐ„์„ ์ž‘์€ ์˜์—ญ์œผ๋กœ ๋‚˜๋ˆˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋ Œ๋”๋ง ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰๊ณผ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ๋†’์€ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๋” ๋งŽ์€ ํด๋ฆฌ๊ณค์ด ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌ๋˜์–ด ๋ Œ๋”๋ง ์ •ํ™•๋„๊ฐ€ ๋†’์•„์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
refined_mesh_path = None

if refined_mesh_path is None:
    post_processed = False
    if post_processed:
        post_processed_str = '_postprocessed'
    else:
        post_processed_str = ''

    scene_name = refined_sugar_path.split('/')[-3]
    refined_mesh_dir = './output/refined_mesh'
    refined_mesh_path = os.path.join(
        refined_mesh_dir, scene_name,
        refined_sugar_path.split('/')[-2].split('.')[0] + '.obj'
    )

print(f"Loading refined mesh from {refined_mesh_path}, this could take a minute...")
textured_mesh = load_objs_as_meshes([refined_mesh_path]).to(nerfmodel.device)
print(f"Loaded textured mesh with {len(textured_mesh.verts_list()[0])} vertices and {len(textured_mesh.faces_list()[0])} faces.")

### textured_mesh ์ •๋ณด ํ™•์ธ
print("Vertices list length:", len(textured_mesh.verts_list()))
print("Faces list length:", len(textured_mesh.faces_list()))

# ์ฒซ ๋ฒˆ์งธ ๋ฉ”์‹œ์˜ ์ •์ ๊ณผ ๋ฉด ํ™•์ธ
print("First mesh vertices shape:", textured_mesh.verts_list()[0].shape)
print("First mesh faces shape:", textured_mesh.faces_list()[0].shape)

# ์ •์  ์ขŒํ‘œ ์ถœ๋ ฅ (์ฒ˜์Œ ๋ช‡ ๊ฐœ๋งŒ)
print("First few vertices:", textured_mesh.verts_list()[0][:5])

# ๋ฉด ์ธ๋ฑ์Šค ์ถœ๋ ฅ (์ฒ˜์Œ ๋ช‡ ๊ฐœ๋งŒ)
print("First few faces:", textured_mesh.faces_list()[0][:5])

# ํ…์Šค์ฒ˜ ์ •๋ณด ํ™•์ธ
if textured_mesh.textures is not None:
    print("Texture maps available.")
    print("Texture maps shape:", textured_mesh.textures.maps_padded().shape)
else:
    print("No texture maps available.")

์ถœ๋ ฅ๊ฒฐ๊ณผ

Loading refined mesh from ./output/refined_mesh/bicycle/sugarfine_3Dgs7000_sdfestim02_sdfnorm02_level03_decim1000000_normalconsistency01_gaussperface1.obj, this could take a minute...
Loaded textured mesh with 1051626 vertices and 1996616 faces.
Vertices list length: 1
Faces list length: 1
First mesh vertices shape: torch.Size([1051626, 3])
First mesh faces shape: torch.Size([1996616, 3])
First few vertices: tensor([[-0.7875,  2.8858, -4.9428],
        [-1.1828,  2.8120, -4.9368],
        [-1.3978,  2.6690, -4.9410],
        [ 2.2472,  2.8223, -4.9400],
        [ 0.6677,  2.8504, -4.9427]], device='cuda:0')
First few faces: tensor([[126,  37, 144],
        [126,  48,  37],
        [ 37,  55, 144],
        [175, 310, 158],
        [212,  68, 213]], device='cuda:0')
Texture maps available.
Texture maps shape: torch.Size([1, 10000, 10000, 3])

ํ•ด์„

  • Vertices list length: 1 โ€“> ๋ฉ”์‹œ ๊ฐ์ฒด๋Š” ํ•˜๋‚˜์˜ 3D ๋ฉ”์‹œ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • Faces list length: 1 โ€“> ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋ฉด ๋ฆฌ์ŠคํŠธ๋„ ํ•˜๋‚˜์˜ 3D ๋ฉ”์‹œ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • First mesh vertices shape: torch.Size([1051626, 3]) โ€“> ์ฒซ ๋ฒˆ์งธ ๋ฉ”์‹œ์˜ ์ •์ ์€ ์ด 1,051,626๊ฐœ์ด๋ฉฐ, ๊ฐ ์ •์ ์€ 3D ๊ณต๊ฐ„์˜ ์ขŒํ‘œ (x, y, z)๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” 3๊ฐœ์˜ ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  • First mesh faces shape: torch.Size([1996616, 3]) โ€“> ์ฒซ ๋ฒˆ์งธ ๋ฉ”์‹œ์˜ ๋ฉด์€ ์ด 1,996,616๊ฐœ์ด๋ฉฐ, ๊ฐ ๋ฉด์€ 3๊ฐœ์˜ ์ •์  ์ธ๋ฑ์Šค๋กœ ๊ตฌ์„ฑ๋œ ์‚ผ๊ฐํ˜•์ž…๋‹ˆ๋‹ค.
  • First few vertices:
    • [-0.7875, 2.8858, -4.9428]
    • [-1.1828, 2.8120, -4.9368]
    • [-1.3978, 2.6690, -4.9410]
    • [ 2.2472, 2.8223, -4.9400]
    • [ 0.6677, 2.8504, -4.9427]
    • ์œ„ ์ •์  ์ขŒํ‘œ๋Š” 3D ๊ณต๊ฐ„์—์„œ์˜ ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๊ฐ๊ฐ์˜ ์ขŒํ‘œ๋Š” x, y, z ๊ฐ’์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
  • First few faces:
    • [126, 37, 144]
    • [126, 48, 37]
    • [ 37, 55, 144]
    • [175, 310, 158]
    • [212, 68, 213]
    • ๊ฐ ๋ฉด ์ธ๋ฑ์Šค๋Š” ์ •์  ๋ฆฌ์ŠคํŠธ์—์„œ ์ •์ ์˜ ์œ„์น˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ์‚ผ๊ฐํ˜• ๋ฉด์„ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, [126, 37, 144]๋Š” 126๋ฒˆ, 37๋ฒˆ, 144๋ฒˆ ์ •์ ์„ ์—ฐ๊ฒฐํ•˜์—ฌ ํ•˜๋‚˜์˜ ์‚ผ๊ฐํ˜• ๋ฉด์„ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ํ…์Šค์ฒ˜ ๋งต ์ •๋ณด ํ™•์ธ
    • Texture maps available. โ€“> ๋ฉ”์‹œ์—๋Š” ํ…์Šค์ฒ˜ ๋งต์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
    • Texture maps shape: torch.Size([1, 10000, 10000, 3])
    • ํ…์Šค์ฒ˜ ๋งต์˜ ํฌ๊ธฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
    • ๋ฐฐ์น˜ ํฌ๊ธฐ: 1 (๋‹จ์ผ ํ…์Šค์ฒ˜ ๋งต)
    • ํ…์Šค์ฒ˜ ํ•ด์ƒ๋„: 10,000 x 10,000 ํ”ฝ์…€
    • ์ฑ„๋„ ์ˆ˜: 3 (RGB ์ƒ‰์ƒ ๊ฐ’)

์ข…ํ•ฉ ํ•ด์„

์ด ๋ฉ”์‹œ ๊ฐ์ฒด๋Š” ๋งค์šฐ ์„ธ๋ฐ€ํ•œ 3D ๋ชจ๋ธ๋กœ, 1,051,626๊ฐœ์˜ ์ •์ ๊ณผ 1,996,616๊ฐœ์˜ ์‚ผ๊ฐํ˜• ๋ฉด์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ •์ ์€ 3D ๊ณต๊ฐ„์—์„œ์˜ ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , ๋ฉด์€ ์ด ์ •์ ์„ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ฉ”์‹œ์˜ ํ‘œ๋ฉด์„ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ด ๋ฉ”์‹œ์—๋Š” 10,000 x 10,000 ํ•ด์ƒ๋„์˜ ๊ณ ํ•ด์ƒ๋„ ํ…์Šค์ฒ˜ ๋งต์ด ํฌํ•จ๋˜์–ด ์žˆ์–ด, ์‹œ๊ฐ์ ์œผ๋กœ ๋งค์šฐ ์ •๊ตํ•œ ๋ Œ๋”๋ง์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ „์ฒด ๋ฉ”์‹œ์™€ ํ…์Šค์ฒ˜ ๋ฐ์ดํ„ฐ๋Š” GPU ๋””๋ฐ”์ด์Šค์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

Mesh Rendering

cam_idx = np.random.randint(0, len(cameras_to_use))

faces_per_pixel = 1
max_faces_per_bin = 50_000

mesh_raster_settings = RasterizationSettings(
    image_size=(refined_sugar.image_height, refined_sugar.image_width),
    blur_radius=0.0, 
    faces_per_pixel=faces_per_pixel,
)
lights = AmbientLights(device=nerfmodel.device)
rasterizer = MeshRasterizer(
        cameras=cameras_to_use.p3d_cameras[cam_idx], 
        raster_settings=mesh_raster_settings,
    )
renderer = MeshRenderer(
    rasterizer=rasterizer,
    shader=SoftPhongShader(
        device=refined_sugar.device, 
        cameras=cameras_to_use.p3d_cameras[cam_idx],
        lights=lights,
        blend_params=BlendParams(background_color=(1.0, 1.0, 1.0)),
    )
)

with torch.no_grad():
    print("Rendering image", cam_idx)
    print("Image ID:", cameras_to_use.gs_cameras[cam_idx].image_name)

    p3d_cameras = cameras_to_use.p3d_cameras[cam_idx]
    rgb_img = renderer(textured_mesh, cameras=p3d_cameras)[0, ..., :3]

plot_ratio = 2.
plt.figure(figsize=(10 * plot_ratio, 10 * plot_ratio))
plt.axis("off")
plt.title("Refined SuGaR mesh with a traditional color UV texture")
plt.imshow(rgb_img.cpu().numpy())
plt.show()

ํ•ด์„

  1. ์นด๋ฉ”๋ผ ์ธ๋ฑ์Šค ์„ค์ •
    • cameras_to_use ๋ชฉ๋ก์—์„œ ๋ฌด์ž‘์œ„๋กœ ํ•˜๋‚˜์˜ ์นด๋ฉ”๋ผ ์ธ๋ฑ์Šค๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ Œ๋”๋ง ์‹œ ์‚ฌ์šฉํ•  ์นด๋ฉ”๋ผ๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ ˆ์Šคํ„ฐํ™” ์„ค์ •
    • RasterizationSettings ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ ˆ์Šคํ„ฐํ™” ์„ค์ •์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
    • faces_per_pixel: ํ”ฝ์…€๋‹น ์ตœ๋Œ€ ๋ Œ๋”๋งํ•  ํด๋ฆฌ๊ณค์˜ ์ˆ˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” 1๋กœ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
    • image_size: ๋ Œ๋”๋งํ•  ์ด๋ฏธ์ง€์˜ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
    • blur_radius: ๋ธ”๋Ÿฌ๋ง ๋ฐ˜๊ฒฝ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” 0์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ์กฐ๋ช… ์„ค์ •
    • AmbientLights ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๊ธฐ๋ณธ ํ™˜๊ฒฝ ์กฐ๋ช…์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๋ฉ”์‹œ์˜ ๋ชจ๋“  ๋ฉด์„ ๊ท ์ผํ•˜๊ฒŒ ๋น„์ถ”๋Š” ์กฐ๋ช…์ž…๋‹ˆ๋‹ค.
  4. Rasterizer ๋ฐ Render ์„ค์ •
    • MeshRasterizer: ์„ ํƒ๋œ ์นด๋ฉ”๋ผ ์„ค์ •๊ณผ ๋ ˆ์Šคํ„ฐํ™” ์„ค์ •์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”์‹œ๋ฅผ ๋ ˆ์Šคํ„ฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
    • MeshRenderer: ๋ ˆ์Šคํ„ฐํ™”๋œ ๋ฉ”์‹œ๋ฅผ SoftPhongShader๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
    • SoftPhongShader: Phong shading ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ Œ๋”๋งํ•˜๋ฉฐ, blend_params๋ฅผ ํ†ตํ•ด ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ์„ ํฐ์ƒ‰(background_color=(1.0, 1.0, 1.0))์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
  5. Mesh Rendering
    • torch.no_grad(): ๊ทธ๋ž˜๋””์–ธํŠธ ๊ณ„์‚ฐ์„ ๋น„ํ™œ์„ฑํ™”ํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ค„์ž…๋‹ˆ๋‹ค.
    • ์„ ํƒ๋œ ์นด๋ฉ”๋ผ ์ธ๋ฑ์Šค๋ฅผ ์ถœ๋ ฅํ•˜๊ณ , ํ•ด๋‹น ์นด๋ฉ”๋ผ๋กœ ๋ฉ”์‹œ๋ฅผ ๋ Œ๋”๋งํ•˜์—ฌ RGB ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ข…ํ•ฉ ํ•ด์„

์ด ๊ณผ์ •์—์„œ ์‚ฌ์šฉ๋œ ์„ค์ •๊ณผ ๋งค๊ฐœ๋ณ€์ˆ˜๋“ค์€ ๋ Œ๋”๋ง๋œ ์ด๋ฏธ์ง€์˜ ํ’ˆ์งˆ๊ณผ ์„ฑ๋Šฅ์— ์ง์ ‘์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, faces_per_pixel ๊ฐ’์„ ๋†’์ด๋ฉด ๋” ๋งŽ์€ ํด๋ฆฌ๊ณค์„ ์ฒ˜๋ฆฌํ•˜์—ฌ ์„ธ๋ฐ€ํ•œ ๋ Œ๋”๋ง์„ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐ๊ฒฝ ์ƒ‰์ƒ์„ ํฐ์ƒ‰์œผ๋กœ ์„ค์ •ํ•จ์œผ๋กœ์จ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€๊ฐ€ ๊น”๋”ํ•˜๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๋งŒ์•ฝ Rasterization์ด differentiableํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด edge๋ฅผ blur ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

image

image

PyTorch3D ์œ ํŠœ๋ธŒ ์„ค๋ช…

Leave a comment