brdf_microfacet — SPECULAR reflectance op

데이터 종류: normalmapimage2d

호출: import specularity; specularity.brdf_microfacet(normals, light=(0.0, 0.0, 1.0), view=(0.0, 0.0, 1.0), roughness=0.3, f0=0.04)(또는 opsspecular.get("brdf_microfacet"))

사용법

GGX / Trowbridge-Reitz 미세면 정반사 BRDF. → (H, W), 단위 1/sr.

> 아래 상세 설명은 원문입니다 —— 요약과 제목은 번역되어 있습니다.

`f_s = D * G * F / (4 (n.l) (n.v))` with

• `D` the Trowbridge-Reitz (1975) / GGX normal distribution,

`a^2 / (pi * ((n.h)^2 (a^2 - 1) + 1)^2) for a = roughness^2`, which

integrates to 1 against `(n.h) dw` over the hemisphere — measured by

20000-point midpoint quadrature in `tests/test_specularity.py` at

relative errors 3.2e-07, 6.3e-08 and 4.0e-09 for roughness 0.2, 0.3 and

0.6, all of it quadrature error (the 200000-point rule gives 3.2e-09,

6.3e-10, 4.0e-11, exactly the 100x a midpoint rule predicts);

• `G` the separable Smith (1967) masking-shadowing term with the GGX

lambda;

• `F` Schlick's (1994) Fresnel approximation,

`f0 + (1 - f0) (1 - v.h)^5`. *f0* is the normal-incidence reflectance:

about 0.04 for common dielectrics, 0.5 to 1.0 for metals. When the exact

Fresnel curve matters, use `match3d.fresnel_reflectance` instead — this

is the approximation the microfacet literature specifies, and it is named

rather than hidden.

Exact ground truth it reproduces: at normal incidence with light, view and

normal aligned, every geometric factor is 1 and the value collapses to

`f0 / (4 pi roughness^4)` in closed form — reproduced bit for bit at

roughness 0.3, 0.5 and 1.0 and to 3.3e-16 relative at roughness 0.1, which

took rewriting the GGX denominator to avoid a cancellation (see the comment

at the code; the textbook arrangement was off by 2.2e-13 relative at the

peak). The lobe is reciprocal in light and view to machine precision

(measured 1.7e-16), and its maximum sits at the half-vector.

`roughness` is the perceptual parameter, squared once to reach the GGX

`alpha` — the convention that makes a linear slider feel linear. A

perfectly smooth surface (`roughness = 0`) is a delta function, not a

finite BRDF, so it is refused rather than returned as an infinity.

Raises `ValueError`: geometry problems as in

:func:brdf_blinn_phong; *roughness* outside `(0, 1]`; *f0* outside

`[0, 1]`.

자세한 사용 가이드

specular_photometric 패밀리 가이드

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

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

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

• 알고리즘의 정전(저자·연도)과 용도는 위의 패밀리 사용 가이드에 적혀 있습니다.

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

specular_photometricpy -3.11 examples/specular_photometric.py

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

polarization_render

같은 카테고리(reflectance)

brdf_blinn_phong · dichromatic_render


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

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