render_optscene_gi — OPTICS radiosity op

• Data kinds: table × table × table → table

• Call: import fullseye as fs; fs.ledger.render_optscene_gi(scene, camera, lights, bounces=None, patch_mm=2.0, outer_mm=None, tol=1e-06, n_quad=3, supersample=1, study_bounces=8, study_tol=0.01) (implementation को सीधे call करना हो तो import radiosity3d; radiosity3d.render_optscene_gi(scene, camera, lights, bounces=None, patch_mm=2.0, outer_mm=None, tol=1e-06, n_quad=3, supersample=1, study_bounces=8, study_tol=0.01), registry से लेना हो तो opsoptics.get("render_optscene_gi"))

उपयोग

अंतर-परावर्तन सहित निरीक्षण render: render_optscene की photometry में Lambert patches के बीच n परावर्तन (या अभिसरित योग)।

> नीचे का विस्तृत विवरण मूल text में है — सारांश और headings का अनुवाद हो चुका है।

The same scene (optscene.scene_*), camera (optical_camera) and lights (illumdesign.light_source results) as optscene.render_optscene. The direct part is computed with the very same irradiance function, so bounces=0 reproduces render_optscene exactly (a test gate). On top of it the surfaces are cut into patches (radiosity_patches, at most *patch_mm* inside pockets and *outer_mm* (default *patch_mm*) elsewhere on a side), their view factors computed with occlusion (form_factor_matrix), and the light reflected between them added:

• bounces=None — converged, by progressive shooting (radiosity_progressive_3d, stop at residual energy tol);

• bounces=k — the Neumann partial sum: light that bounced at most k times between surfaces before reaching the camera (0 = direct only, 1 = one interreflection).

Each pixel's interreflected irradiance is gathered from the patch radiosities with the point-to-polygon closed form at the pixel's own surface point (final gather, one visibility ray per patch), so it is smooth inside a patch. Pixel radiance = ρ/π (E_direct + E_interreflected) in the same linear units as render_optscene. Light intensity enters linearly (the geometry is cached by a SHA-256 of the scene's shapes, camera and patch size — materials and light intensity are read on every call, so a calibration loop that varies albedo or intensity re-solves only the radiosity).

*study_bounces* K > 0 adds a bounce study: the images after 0..K bounces, the increment of each (max abs change / image peak), the observed ratio of successive increments g (the geometric analogue of an observed order of convergence), a GCI-style estimate 1.25 · Δ_k g/(1 − g) of what the remaining bounces still add, whether k is in the asymptotic range (g moved by at most 5 % at k and at k − 1; before it the estimate can be optimistic), the actual error against the converged image, and bounces_needed = the first k in the asymptotic range whose GCI estimate is below *study_tol*.

Returns a dict (table) with kind = "gi_render", image (H, W, 3), direct (H, W, 3, identical to render_optscene), difference (H, W, 3) = image − direct (the interreflection map), indirect_share (H, W), bounces, converged, n_shots, unshot_history, n_patches, patch_radiosity (N, 3), bounce_study (list of rows, or None), bounces_needed and notes.

Raises ValueError: an empty scene, or an unsupported one (see radiosity_patches:

Lambertian boxes, box-minus-box pockets, finite planes; an infinite plane only black); no lights; *bounces* not None or an integer in [0, 1000]; bad *patch_mm*, *tol*, *n_quad*, *supersample*, *study_bounces* or *study_tol*; an all-zero image (as render_optscene).

पूरी family का input contract (fail-closed)

optics के सभी ops गणना से पहले input की जाँच करते हैं (कुछ भी चुपचाप पास नहीं होता):

• Unit argument के नाम में ही लिखी होती है — _mm / _um / _deg / _mrad। mm और µm की गड़बड़ी crash नहीं करती, बल्कि "सही दिखने वाला पर गलत उत्तर" देती है, इसलिए नाम से इसे रोका जाता है। मान के आकार से unit का अनुमान बिल्कुल नहीं लगाया जाता।

• String से ValueError — float('50') सफल हो जाता है, इसलिए बिना parse किया config value length के रूप में निकल जाता (मापा गया: thin_lens('50', '200') सही दिखने वाला 66.667 mm लौटा रहा था)। bool को भी True == 1 वाले implicit promotion के रूप में अस्वीकार किया जाता है।

• complex / masked array से ValueError (केवल real-valued slots; imaginary part को चुपचाप छोड़ना या mask हटाना अस्वीकार)। हर input पर NaN/Inf से ValueError।

• शून्य से भाग और उससे जुड़े मामलों को नाम लेकर अस्वीकार किया जाता है: focal length 0, radius of curvature 0, refractive index <= 0, पूरी तरह opaque aperture (सब 0, इसलिए normalisation 0/0), ऐसा PSF जिसका योग <= 0 हो, S0 = 0 वाला Stokes vector, और front focal point पर रखा object (image अनंत पर)।

• केवल 2 ops non-finite value लौटाते हैं, और वह भी contract के रूप में लिखा हुआ: depth_of_field hyperfocal distance से आगे far_mm = inf (hyperfocal distance की परिभाषा यही है) और gaussian_beam waist पर wavefront_radius_mm = inf (plane wavefront की radius of curvature)। दोनों साथ में एक finite साथी (far_is_infinite / curvature_per_mm) भी लौटाते हैं। इसके अलावा कोई भी चुपचाप आया NaN/Inf अंदर ही पकड़ा जाता है और ValueError देता है — "float64 overflow हुआ" और "उत्तर अनंत है" अलग-अलग दावे हैं, इसलिए पहले को दूसरे का चेहरा पहनाकर नहीं लौटाया जाता।

• Size की सीमा: generate होने वाले grid के लिए optics.MAX_GRID (4096), दिए गए field/PSF/aperture के लिए optics.MAX_FIELD_ELEMENTS (2^24), ABCD element chain के लिए optics.MAX_SYSTEM_ELEMENTS (1024), Zernike के लिए MAX_ZERNIKE_TERMS (512) / MAX_ZERNIKE_ORDER (40) / MAX_ZERNIKE_BASIS (2^25)। छोटे argument से बहुत बड़ा internal allocation होने वाले रास्तों (मापा गया: n_max=40 × 4096² पर 108 GB) को fail-closed ढंग से बंद किया गया है।

• भौतिक रूप से असंभव states भी अस्वीकार: degree of polarisation > 1 वाला Stokes vector, ऋणात्मक transmittance, ऋणात्मक intensity, और n-|m| odd जैसे अमान्य Zernike indices।

उपयोग की विस्तृत guide

• optics_imaging family guide

संदर्भ (sample data, साहित्य)

• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।

• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।

• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।

चलाए जा सकने वाले उदाहरण (verified samples जो सच में यह op call करते हैं)

• poc_pocket_interreflection — py -3.11 examples/poc_pocket_interreflection.py

वे अगले ops जिनसे type जुड़ता है (table को input के रूप में लेते हैं)

abcd_matrix · wavefront_stats · sfr_from_edge · paraxial_trace · seidel_coefficients · spot_stats · tolerance_analysis · wavefront_from_opd

इसी category के (radiosity)

form_factor_parallel_rects · form_factor_perpendicular_rects · form_factor_polygons · radiosity_patches · form_factor_matrix · radiosity_progressive_3d


*Provenance: radiosity3d.py — OPTICS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*

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