* Render: restore saved shots, progressive images and exports * Render: register existing live and coat command tests * Render: isolate lens saves and retain bounded previews Save only lens parameters on existing CPU/GPU jobs while keeping unrelated draft settings dirty. Retain pinned checkpoints through preview and status, and release host-only snapshots outside the status lock. Use the admitted PNG bound for registered-executor checkpoint slots. Preserve executor work credits, final publication and regrade ownership. Add regression coverage and align help, translations and capability documentation. * Render: preserve live feedback and address review regressions * Preserve saved cameras when applying Render library edits Keep the saved camera when lighting or maps are applied to an existing shot. Fit and centre the measured Render host using the painted picture. Carry forward the upstream CPU and GPU preset and ZoomTool contracts.
9.7 KiB
HDR environment sampling (#1693)
Source implementation and opt-in CPU direct-light consumer are prepared. No executed HDR-lit PNG, test, full gate or delivered HDRI feature is claimed. The existing default preview remains unchanged.
lighting::environment_sampling::EnvironmentPreparation borrows an existing
DecodedHdr. It checks bounded 2:1 dimensions and original pixel allocation
capacity, then validates at most 16,384 pixels per step. The caller supplies a
fallible work/cancellation callback, charged for each inspection. Errors consume
preparation; finish refuses incomplete validation. No decoder, cache, CDF,
pixel clone, worker or pool is added. The existing owner and admission lease must
outlive the borrowed view. retained_pixel_bytes reports capacity, not length;
the host charges the owner for its retained lifetime. Captured image storage is
released before PNG publication; retained capture metadata has its own Record lease.
Coordinates and estimator
Directions point away from the shading point. The map is Z-up: +Z is north,
phi=atan2(y,x), u=wrap(phi/(2*pi)), v=acos(z)/pi. Nearest lookup uses
half-open texel cells centred on ((x+.5)/width,(y+.5)/height). Longitude wraps,
the south pole clamps to the last row, and an exact pole chooses longitude zero
before rotation. Positive rotation turns the environment about +Z toward +Y;
lookup subtracts that rotation. There is no extra orientation inherited from an
external application's conventions.
The first proposal samples uniform z in (-1,1) and phi in (0,2*pi). Since
dOmega=dphi*dz, its PDF is 1/(4*pi) per steradian everywhere. The PDF remains
normalized for black maps, without a division by total image brightness. Constant
maps preserve their radiance. This is not importance sampling; small bright
sources can have high variance. Nearest lookup is intentionally not bilinear
filtering or a claim of antialiasing. Floating-point boundary rounding can still
produce a pole, whose lookup is defined.
direct_sample_linear_srgb returns an unoccluded BRDF*cos*Li/pdf estimate.
The geometric normal excludes incident and view directions crossing the original surface;
the shading normal affects the BRDF and cosine. The consumer owns visibility and
averages exactly once over the requested environment sample count. The helper
does not apply exposure, mapping, sRGB encoding or a sample-count division.
Colour policy
Decoded HDR is linear RGB in its SOURCE space. RGBE decoding has already divided
by the file's exposure and colour correction; sampling never repeats either.
Source-space lookup is explicitly named radiance_source_rgb.
The initial lighting adapter admits only explicit PRIMARIES values matching
sRGB/D65: 0.64 0.33 0.30 0.60 0.15 0.06 0.3127 0.3290. It uses these linear
channels directly, without applying the sRGB transfer curve. Missing primaries
and all other primaries refuse illumination; default Radiance RGB is not silently
relabeled sRGB. Supporting other primaries requires a separately validated gamut
and white-point conversion. No clipping or invented conversion is used here.
CPU consumer and remaining qualification
At the original source handoff, the separately qualified RT2 source was not an executed validation result for this module. Integration required real prerequisite history or a recorded source overlay, without copied build outputs. Subsequent combined CPU renderer checks have executed for environment sampling and the actual image consumer; current combined workflow/native gates remain separate.
- Capture the admitted existing HDR source and preserve its original encoded allocation. Include encoded/decoded retained capacities, request clones and state in the existing 384 MiB job and 512 MiB shared admission. Capture metadata keeps its Record-owned lease after frame eviction. Refuse unsupported primaries before publication.
- Incremental preparation calls the SAME cumulative job work budget and cancel
token. The implemented owned adapter moves
EnvironmentInputthrough host work into one existingHdrDecodeTask. The image task owns its completedDecodedHdrand creates short-lived borrowed views, without a self-referential borrow or a second decoded copy. Decoding validates corrected texels incrementally; internal views check shape and capacity without rescanning every texel for each sample. Renderer decode/ownership/cancellation checks have executed; native visual acceptance remains pending. - At an opaque hit, each environment direct sample creates one positive-minimum secondary visibility ray from the shared geometric offset. Reuse the existing resumable traversal cursor, charging every sample and traversal unit. Add visible estimates in linear space and divide by environment sample count once.
- Primary misses remain equal to the requested display background. The
radiance_linear_srgbAPI is available for later secondary-miss transport; reflection continuation is not connected in this consumer. Combining environment next-event estimates and rough-specular paths that miss requires matched MIS or a documented partition of the two terms; until implemented, refuse that combination. Do not count the same environment specular energy twice. - Add environment illumination to existing direct lights without adding another ambient term. Exposure, Reinhard and sRGB transfer remain a single final step. Image/task/host cancellation must publish no partial successful frame.
Original analytic tests generate RGBE bytes at runtime: constant map and PDF, single bright cell solid angle, black map, axes/rotation/seam/poles, cancellation and shared-budget failure, decoder corrections, unsupported primaries, hostile options/directions and an independent white-conductor hemispherical integral. The renderer analytic/input cases have executed. Engine source-removal and metadata contracts still need current combined qualification. This sampling helper itself adds no external assets, dependencies or persistence fields.
Mathematical references only; no code or figures copied: PBRT, Infinite Area Lights for radiance and solid-angle estimators (its image mapping is different), and W3C CSS Color 4, sRGB for the sRGB/D65 primary coordinates and the distinction from encoded sRGB.
Opt-in request
render.preflight / render.start accept an environment object alongside
integrator:"raytrace", for example:
{"integrator":"raytrace","raytrace":{"lights":[]},"environment":{"path":"original-srgb.hdr","rotation_radians":0,"intensity":1,"samples":64}}
The input path uses the existing scoped, bounded VFS reader and HdrSource.
The captured source is passed separately to CpuHost::submit_with_environment,
never serialized or cloned into job status. A separate fixed-size EnvironmentInfo
records the SHA-256 digest, numerical header, controls and explicit colour policy in
preflight and status, without the source path or pixels. Encoded capacity, exact decoded storage,
scanline storage and bounded state are added before the shared reservation;
allocators that exceed admitted scanline/decoded capacities refuse. Direct-light
visibility uses the existing positive-minimum ray and resumable cursor. Primary
misses retain the exact requested background. Samples use deterministic z/phi
stratum centres (one sample uses a fixed interior point); finite-count quadrature
can be biased and is not a convergence or unbiased-rendering claim.
The standalone HDR checkpoint has no reflection continuation. This isolated combined source connects secondary environment misses and explicitly selected metallic rough reflectors or ideal mirrors; see the integration contract. Mixed/diffuse rough HDR combinations and unknown optics fields refuse on that legacy route. This direct/reflection estimator itself adds no MIS or texture consumer. Saved CPU HDR references use the existing resource contract. Optional opaque path lighting adds matched light/BSDF MIS and BSDF-sampled mesh emission; certified dielectric transport remains a separate CPU route. These do not establish mixed glass/GI or general material-map support.
Seven consumer source regressions complement the nine analytic/input regressions: an image-task PNG oracle and deterministic/background checks, decode/visibility cancellation and work exhaustion, native captured-source ownership, four-unit quanta, all traversal-to-shading transitions, engine rendering after source-file removal compared with unlit geometry, and capture-metadata lease release after PNG eviction. Renderer cases have executed; current combined engine contract and native workflow qualification remain separate.
Consumer review repairs: environment cursor continuation charges traversal without
an additional shading debit; each pixel quantum remains at most four shared work
units. Both request resolvers require Hdri when a source is captured. Only the
native feature-on raytrace descriptor advertises this narrow environment path.
Preflight and job status retain fixed-size SHA-256 bytes, bounded header numbers,
controls and explicit colour policy; neither the input path nor image bytes are
retained there. Fixed metadata is charged to the Record-owned lease independently
of the PNG, while captured image storage stays under the work lease. Preflight
includes retained request metadata in its combined per-job estimate. A regression
withdraws the actual HDR file and compares lit geometry against the same unlit job.
The renderer ownership and bounded-work cases have executed; the engine file-removal regression still needs current combined qualification.