render_beauty — 3D render op

• 데이터 종류: mesh → rgbimage

• 호출: import fullseye as fs; fs.ledger.render_beauty(V, F, *, pose=None, intrinsics=None, size: 'int' = 512, ss: 'int' = 2, light: 'Sequence[float]' = (0.3, 0.4, 1.0), albedo: 'Sequence[float]' = (0.8, 0.8, 0.85), material: 'str' = 'plastic', matcap=None, ambient: 'float' = 0.12, ao: 'bool' = True, ground_shadow: 'bool' = True, tonemap: 'str' = 'reinhard', background: 'Sequence[float]' = (0.1, 0.11, 0.13), exposure: 'float' = 1.0, shininess: 'Optional[float]' = None, ao_samples: 'int' = 32, shadow_res: 'int' = 512, penumbra: 'float' = 2.5, shadow_samples: 'int' = 12, shadow_pcf: 'int' = 1, brdf: 'str' = 'phong', brdf_params=None, shadow_method: 'str' = 'map', sun_angular_diameter_deg: 'float' = 0.0, self_illumination: 'float' = 0.0, albedo_variation: 'float' = 0.0, albedo_scale=None, seed: 'int' = 0, smooth_normals: 'bool' = False, bump=None, vertex_normals=None, vertex_albedo=None, surface: 'str' = 'none', surface_params=None) -> 'np.ndarray'(구현을 직접 호출하려면 import render_beauty; render_beauty.render_beauty(V, F, *, pose=None, intrinsics=None, size: 'int' = 512, ss: 'int' = 2, light: 'Sequence[float]' = (0.3, 0.4, 1.0), albedo: 'Sequence[float]' = (0.8, 0.8, 0.85), material: 'str' = 'plastic', matcap=None, ambient: 'float' = 0.12, ao: 'bool' = True, ground_shadow: 'bool' = True, tonemap: 'str' = 'reinhard', background: 'Sequence[float]' = (0.1, 0.11, 0.13), exposure: 'float' = 1.0, shininess: 'Optional[float]' = None, ao_samples: 'int' = 32, shadow_res: 'int' = 512, penumbra: 'float' = 2.5, shadow_samples: 'int' = 12, shadow_pcf: 'int' = 1, brdf: 'str' = 'phong', brdf_params=None, shadow_method: 'str' = 'map', sun_angular_diameter_deg: 'float' = 0.0, self_illumination: 'float' = 0.0, albedo_variation: 'float' = 0.0, albedo_scale=None, seed: 'int' = 0, smooth_normals: 'bool' = False, bump=None, vertex_normals=None, vertex_albedo=None, surface: 'str' = 'none', surface_params=None) -> 'np.ndarray', 원장에서 가져오려면 ops3d.get("render_beauty"))

사용법

메시를 모든 품질 층을 합성해 「보기 좋은 정지 3D」 한 장으로 → RGB (size, size, 3) float [0,1].

인수:

• V, F 정점 (N,3)과 삼각형 (M,3).

• pose 4x4 object->camera(render3d.look_at). None이면 auto_view.

• intrinsics 3x3 핀홀 K(목표 size 용, 내부에서 ss 배로 스케일).

• size 출력의 한 변의 길이(정사각형). ss 슈퍼샘플링 배율(정수 >= 1).

• light 월드 좌표의 광원 방향(장면→광원). 음영과 접지 그림자에서 공유.

• albedo 물체의 반사색 RGB. material 'plastic' | 'metal' | 'matcap'.

• matcap material='matcap'일 때 필수인 lit-sphere 텍스처 (h,w[,C]).

• ambient 환경광 계수. ao 앰비언트 오클루전을 적용할지 여부.

• ground_shadow 지면 평면 + 접지 그림자를 베이크할지 여부.

• tonemap 'reinhard' | 'aces' | 'none'. background 배경색 RGB.

• exposure 톤 매핑 전의 노출. shininess 광택(None이면 머티리얼 기본값).

• ao_samples / shadow_res / penumbra / shadow_samples 품질·속도 튜닝(접지 그림자의 부드러움 등). penumbra는 광원의 각반경 [도] 이며, 반그림자의 폭은 대략 "차폐물의 높이 × tan(penumbra)". 기본값 2.5 도에서는 지면에서 1 단위 높이의 물체라도 반그림자가 1〜2 화소 에 불과하다(2026-09-02 실측: 320px 그림에서 반그림자는 283/102400 화소, 값의 종류는 shadow_samples+1 의 7 단계뿐). 부드러운 그림자가필요하면 10 도 전후까지 올리고, 단계가 보이지 않도록 shadow_samples도 함께 늘린다.

• shadow_pcf shadow map을 참조할 때 섞는 근방 반경 [texel] (기본값 1 = 3x3). 1 점만 참조하면 그림자 경계가 texel 단위로 양자화되어 계단이 된다. 실측(지면 위에서만 잰 인접 화소의 최대 변화):

기본값 2.5 도·12 개·pcf=0 상당에서 0.667,

12 도·24 개·pcf=1 에서 0.176(1/6을 넘는 단계는 123→2).

• brdf 물체의 반사 법칙. 'phong'(기본값 = 기존대로 Lambert 확산 + cos^n 경면)/ 'lambert' / 'lommel_seeliger' / 'hapke'(행성 측광, render_shade.brdf_shade). phong 이외에서는 경면을 끄고, albedo는평균 1로 정규화한 색조 로 곱한다(밝기는 brdf_params의단일 산란 알베도 w가 결정한다. 이중으로 곱하지 않는다).

• brdf_params dict(w, g, B0, h, roughness_deg, multiple_scattering).

• shadow_method 'map'(기본값 = shadow map + PCF)/ 'raycast' (render_shadow.shadow_raycast, 계단·acne 없음).

• sun_angular_diameter_deg raycast 시 광원의 시직경(태양 0.53°). 반그림자의 폭은 "차폐물까지의 거리 × tan(시직경/2)" = 소행성에서는 수 cm(딱딱한 그림자).

• self_illumination 지형으로부터의 1회 반사 근사 계수(기본값 0). bounce = 계수 × albedo색 × (1 − AO) × 비춰진 면의 평균 방사 휘도 ―― 차폐된 반구만큼 이웃 지형이 보이고, 그 지형이 평균적인밝기로 빛난다는 근사(상호 반사의 엄밀해가 아니며, ao=True 필요). 우주에는 환경광이 없으므로 ambient=0과 이것으로 그림자의 바닥 밝기가 정해진다.

• bump dict(wavelengths, amplitudes[, seed, nyquist, fade, complement_edges]) → 물체 화소의 음영 법선을 render3d.bump_normals_fbm(값 잡음 높이장의기울기)로 섭동한다. 기하(depth/그림자/AO)는 불변. complement_edges=True 이면 화소 바로 아래 메시의 국소 변 길이를 무게중심 보간하여 넘기고, 변위의 대역 게이트의 여집합 만 bump로 만든다(같은 파장을 이중으로 더하지 않는다).

fail-closed: 형상 불량·비유한·빈 입력·ss<1·잘못된 material/tonemap·잘못된 색/광/노출은 ValueError. 결정적(난수 없음).

배경 지식 가이드(이 연산자 앞에 있는 물리·규약)

• blender_interop — Blender와 함께 쓰기 — 형상을 만들고 fullseye로 측정(축·단위·정답 데이터의 함정)

참고(샘플 데이터·문헌)

• 샘플 데이터 카탈로그(DL URL / 라이선스) —— 2-D 는 skimage.data(BSD/public)+ 합성, 3-D 는 실데이터 소스(Stanford/PDS 등)의 DL URL.

• 연산자의 내력·참고문헌 —— 이 연산자 족의 바탕이 된 연구/기법의 출처.

실행 가능한 예제(이 연산자를 실제로 호출하는 검증된 샘플)

• anatomical_hand — py -3.11 examples_3d/anatomical_hand.py

• render_beauty — py -3.11 examples_3d/render_beauty.py

타입이 이어지는 다음 연산자(rgbimage 를 입력으로 받는 것)

fuse_to_voxel

같은 카테고리(render)

project_points · render_point_depth · render_volume_projection · render_shaded · ambient_occlusion · cast_shadow · phong_shade · matcap_shade


*Provenance: render_beauty.py — 3D 연산자 레지스트리. 이 op 노트는 tools/opdocs.py md 가 자동 생성합니다(직접 편집하지 마세요).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.