[Rendering] SuGaR 3D mesh load, Phong Shading, Rendering
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 ๋ฉ์์ ํ๋ฉด์ ์์์ ์ ์ฉํ์ฌ ์๊ฐ์ ์ผ๋ก ๋ ํ์ค๊ฐ ์๋ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ๋ ๊ณผ์ ์ ๋๋ค. ์ด ๊ณผ์ ์ ๋ค์ ๋จ๊ณ๋ก ๋๋ ์ ์์ต๋๋ค:
- ๋ฉ์ ๋ก๋: 3D ๋ชจ๋ธ์ ํ์ผ์์ ๋ถ๋ฌ์ต๋๋ค. ์๋ฅผ ๋ค์ด,
load_objs_as_meshes
ํจ์๋ฅผ ์ฌ์ฉํ์ฌ.obj
ํ์ผ ํ์์ ๋ฉ์๋ฅผ ๋ก๋ํฉ๋๋ค. - ํ ์ค์ฒ ๋งคํ: ๋ก๋๋ ๋ฉ์์ ์์ ์ ๋ณด๋ฅผ ๋งคํํฉ๋๋ค. ํ ์ค์ฒ ๋งคํ์ ๋ฉ์์ ๊ฐ ํด๋ฆฌ๊ณค์ ์์์ ํ ๋นํ์ฌ ๋ฉ์์ ํ๋ฉด์ ๊ทธ๋ฆผ์ด๋ ํจํด์ ์ ํ๋ ๊ณผ์ ์ ๋๋ค.
- ๋ ๋ ์ค์ : ๋ ๋๋ง ์ค์ ์ ์ ์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์นด๋ฉ๋ผ ์์น, ์กฐ๋ช ์ค์ , ๋ ์คํฐ ์ค์ ๋ฑ์ ํฌํจํฉ๋๋ค.
- ๋ ๋๋ง: ์ค์ ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐํ์ผ๋ก ๋ฉ์๋ฅผ ๋ ๋๋งํฉ๋๋ค. ์ด ๊ณผ์ ์์ ๋ฉ์์ ํ๋ฉด์ ์ ์ฉ๋ ํ ์ค์ฒ๊ฐ ๊ณ ๋ ค๋์ด ์ต์ข ์ด๋ฏธ์ง๋ฅผ ์์ฑํฉ๋๋ค.
- ์๊ฐํ: ๋ ๋๋ง๋ ์ด๋ฏธ์ง๋ฅผ ํ๋ฉด์ ํ์ํฉ๋๋ค.
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()
ํด์
- ์นด๋ฉ๋ผ ์ธ๋ฑ์ค ์ค์
cameras_to_use
๋ชฉ๋ก์์ ๋ฌด์์๋ก ํ๋์ ์นด๋ฉ๋ผ ์ธ๋ฑ์ค๋ฅผ ์ ํํฉ๋๋ค. ์ด๋ ๋ ๋๋ง ์ ์ฌ์ฉํ ์นด๋ฉ๋ผ๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
- ๋ ์คํฐํ ์ค์
RasterizationSettings
๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ ์คํฐํ ์ค์ ์ ์ ์ํฉ๋๋ค.faces_per_pixel
: ํฝ์ ๋น ์ต๋ ๋ ๋๋งํ ํด๋ฆฌ๊ณค์ ์๋ฅผ ์ค์ ํฉ๋๋ค. ์ฌ๊ธฐ์๋ 1๋ก ์ค์ ๋์ด ์์ต๋๋ค.image_size
: ๋ ๋๋งํ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค.blur_radius
: ๋ธ๋ฌ๋ง ๋ฐ๊ฒฝ์ ์ค์ ํฉ๋๋ค. ์ฌ๊ธฐ์๋ 0์ผ๋ก ์ค์ ๋์ด ์์ต๋๋ค.
- ์กฐ๋ช
์ค์
AmbientLights
๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๊ธฐ๋ณธ ํ๊ฒฝ ์กฐ๋ช ์ ์ค์ ํฉ๋๋ค. ์ด๋ ๋ฉ์์ ๋ชจ๋ ๋ฉด์ ๊ท ์ผํ๊ฒ ๋น์ถ๋ ์กฐ๋ช ์ ๋๋ค.
- Rasterizer ๋ฐ Render ์ค์
MeshRasterizer
: ์ ํ๋ ์นด๋ฉ๋ผ ์ค์ ๊ณผ ๋ ์คํฐํ ์ค์ ์ ์ฌ์ฉํ์ฌ ๋ฉ์๋ฅผ ๋ ์คํฐํํฉ๋๋ค.MeshRenderer
: ๋ ์คํฐํ๋ ๋ฉ์๋ฅผSoftPhongShader
๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๋๋งํฉ๋๋ค.SoftPhongShader
: Phong shading ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ๋ ๋๋งํ๋ฉฐ,blend_params
๋ฅผ ํตํด ๋ฐฐ๊ฒฝ ์์์ ํฐ์(background_color=(1.0, 1.0, 1.0))์ผ๋ก ์ค์ ํฉ๋๋ค.
- Mesh Rendering
torch.no_grad()
: ๊ทธ๋๋์ธํธ ๊ณ์ฐ์ ๋นํ์ฑํํ์ฌ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ค์ ๋๋ค.- ์ ํ๋ ์นด๋ฉ๋ผ ์ธ๋ฑ์ค๋ฅผ ์ถ๋ ฅํ๊ณ , ํด๋น ์นด๋ฉ๋ผ๋ก ๋ฉ์๋ฅผ ๋ ๋๋งํ์ฌ RGB ์ด๋ฏธ์ง๋ฅผ ์์ฑํฉ๋๋ค.
์ข ํฉ ํด์
์ด ๊ณผ์ ์์ ์ฌ์ฉ๋ ์ค์ ๊ณผ ๋งค๊ฐ๋ณ์๋ค์ ๋ ๋๋ง๋ ์ด๋ฏธ์ง์ ํ์ง๊ณผ ์ฑ๋ฅ์ ์ง์ ์ ์ธ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. ์๋ฅผ ๋ค์ด, faces_per_pixel ๊ฐ์ ๋์ด๋ฉด ๋ ๋ง์ ํด๋ฆฌ๊ณค์ ์ฒ๋ฆฌํ์ฌ ์ธ๋ฐํ ๋ ๋๋ง์ ํ ์ ์์ง๋ง, ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค. ๋ฐฐ๊ฒฝ ์์์ ํฐ์์ผ๋ก ์ค์ ํจ์ผ๋ก์จ ๊ฒฐ๊ณผ ์ด๋ฏธ์ง๊ฐ ๊น๋ํ๊ณ ๋ช ํํ๊ฒ ๋ณด์ผ ์ ์์ต๋๋ค.
Leave a comment