render_beauty — 3D render op

• Datenarten: mesh → rgbimage

• Aufruf: 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' (die Implementierung direkt: 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'; aus dem Register: ops3d.get("render_beauty"))

Verwendung

Rendert ein Mesh mit allen Qualitätsschichten zu einem „ansehnlichen 3-D-Standbild“ → RGB (size, size, 3) float [0,1].

Argumente:

• V, F Vertices (N,3) und Dreiecke (M,3).

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

• intrinsics 3x3-Lochkamera K (für die Ziel-size, intern mit ss skaliert).

• size Seitenlänge der Ausgabe (quadratisch). ss Supersampling-Faktor (ganze Zahl >= 1).

• light Lichtrichtung in Weltkoordinaten (Szene→Lichtquelle). Gemeinsam für Schattierung und Bodenschatten.

• albedo Reflexionsfarbe RGB des Objekts. material 'plastic' | 'metal' | 'matcap'.

• matcap Lit-Sphere-Textur (h,w[,C]), erforderlich bei material='matcap'.

• ambient Umgebungslicht-Koeffizient. ao ob Ambient Occlusion angewendet wird.

• ground_shadow ob eine Bodenebene + Bodenschatten eingebrannt wird.

• tonemap 'reinhard' | 'aces' | 'none'. background Hintergrundfarbe RGB.

• exposure Belichtung vor dem Tone Mapping. shininess Glanz (None = Materialstandard).

• ao_samples / shadow_res / penumbra / shadow_samples Abstimmung von Qualität und Geschwindigkeit (Weichheit des Bodenschattens usw.). penumbra ist der Winkelradius der Lichtquelle [Grad], und die Halbschattenbreite beträgt etwa "Höhe des Verdeckers × tan(penumbra)". Mit dem Standard von 2.5 Grad ergibt ein Objekt in 1 Einheit Höhe über dem Boden einen Halbschatten von nur 1 bis 2 Pixeln (gemessen 2026-09-02: in einem 320px-Bild umfasst der Halbschatten 283/102400 Pixel, und es gibt nur 7 Stufen an Werten = shadow_samples+1). Für weiche Schatten auf etwa 10 Grad erhöhen und, damit keine Stufen sichtbar werden, shadow_samples mit erhöhen.

• shadow_pcf Nachbarschaftsradius [texel], der beim Abtasten der Shadow Map gemischt wird (Standard 1 = 3x3). Bei Abfrage von nur 1 Punkt wird die Schattengrenze auf Texel quantisiert und treppenförmig. Gemessen (größte Änderung zwischen benachbarten Pixeln, nur auf dem Boden gemessen):

Standard 2.5 Grad, 12 Strahlen, entsprechend pcf=0: 0.667;

12 Grad, 24 Strahlen, pcf=1: 0.176 (Stufen über 1/6: 123→2).

• brdf Reflexionsgesetz des Objekts. 'phong' (Standard = wie bisher Lambert-diffus + cos^n-Spiegelanteil) / 'lambert' / 'lommel_seeliger' / 'hapke' (planetare Photometrie, render_shade.brdf_shade). Außer bei phong ist der Spiegelanteil aus, und albedo wird als auf Mittelwert 1 normierte Farbtönung multipliziert (die Helligkeit bestimmt die Einfachstreu-Albedo w von brdf_params; sie wird nicht doppelt angewendet).

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

• shadow_method 'map' (Standard = Shadow Map + PCF) / 'raycast' (render_shadow.shadow_raycast, ohne Treppen und ohne Acne).

• sun_angular_diameter_deg scheinbarer Durchmesser der Lichtquelle bei raycast (Sonne 0.53°). Die Halbschattenbreite ist "Abstand zum Verdecker × tan(Durchmesser/2)" = auf einem Asteroiden einige cm (harter Schatten).

• self_illumination Koeffizient der Näherung für eine einfache Reflexion vom Gelände (Standard 0). bounce = Koeffizient × albedo-Farbe × (1 − AO) × mittlere Strahldichte der beleuchteten Flächen -- eine Näherung, nach der über den verdeckten Teil der Hemisphäre benachbartes Gelände sichtbar ist, das mit durchschnittlicher Helligkeit leuchtet (keine exakte Lösung der Interreflexion; erfordert ao=True). Im Weltraum gibt es kein Umgebungslicht, daher bestimmen ambient=0 und dies allein den Boden der Schatten.

• bump dict(wavelengths, amplitudes[, seed, nyquist, fade, complement_edges]) → stört die Schattierungsnormalen der Objektpixel mit render3d.bump_normals_fbm (Gradient eines Value-Noise-Höhenfelds). Die Geometrie (depth/Schatten/AO) bleibt unverändert. Mit complement_edges=True wird die lokale Mesh-Kantenlänge unter jedem Pixel per Schwerpunktinterpolation übergeben, und nur das Komplement des Band-Gates der Verschiebung geht in den Bump ein (dieselbe Wellenlänge wird nicht doppelt addiert).

fail-closed: ungültige Form, nicht endlich, leer, ss<1, ungültiges material/tonemap, ungültige Farbe/Licht/Belichtung lösen ValueError aus. Deterministisch (kein Zufall).

Hintergrundwissen (Physik und Konventionen hinter diesem Operator)

• blender_interop — Zusammen mit Blender — Form bauen, mit fullseye messen (Fallstricke: Achsen, Einheiten, Referenzdaten)

Referenzen (Beispieldaten, Literatur)

• Katalog der Beispieldaten (Download-URLs / Lizenzen) — 2-D nutzt skimage.data (BSD/Public Domain) plus synthetische Bilder, 3-D nennt Download-URLs echter Datenquellen (Stanford, PDS, …).

• Herkunft und Literatur der Operatoren — die Quellen der Forschung/Verfahren, auf denen diese Operatorfamilie beruht.

Ausführbare Beispiele (verifizierte Samples, die diesen Operator wirklich aufrufen)

• anatomical_hand — py -3.11 examples_3d/anatomical_hand.py

• render_beauty — py -3.11 examples_3d/render_beauty.py

Typkompatible Folge-Operatoren (nehmen rgbimage als Eingabe)

fuse_to_voxel

Gleiche Kategorie (render)

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


*Provenance: render_beauty.py — 3D Operator-Registry. Diese Notiz wird von tools/opdocs.py md erzeugt (nicht von Hand bearbeiten).*

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