Translucent Image

com.zalinteractive.translucent-image

1 Zal Translucent Image quick start

1.1 Built-in Render Pipeline

  1. Add TranslucentImageSource to the scene camera. While Built-in is active, the editor creates the visible TranslucentImageBuiltInRenderer bridge and repairs existing enabled sources after a switch from URP. The bridge remains available for image-effect ordering.
  2. Create GameObject > UI > Translucent Image, or convert an existing UGUI Image from its component context menu.
  3. Assign the source to the new panel.
  4. Use a Screen Space Overlay Canvas for the simplest acyclic setup.
  5. If the inspector reports missing Canvas channels, run Tools > Translucent Image > Fix Canvas Channels.

1.2 Universal Render Pipeline

  1. Add TranslucentImageSource to the scene camera.
  2. Run Tools > Translucent Image > URP Setup and select each renderer data asset that will render a source.
  3. Create or convert a TranslucentImage and assign the source.
  4. Use Screen Space Overlay for the simplest setup. Camera-space and World Space UI require an earlier Base/source camera and a later Overlay/UI camera.
  5. Renderer2D supports Screen Space Overlay consumers only.

The source camera must never render a consumer of its own capture before capture occurs. See the full manual below for camera ordering, target textures, XR scope, leases, and troubleshooting.

2 Zal Translucent Image

Zal Translucent Image is a UGUI component that presents a live, blurred view of an earlier camera result behind ordinary sprite or texture foreground content. Many panels can share one source, while multiple independently configured sources can share one camera capture stage.

2.1 Compatibility at a glance

This is the 0.1 release target. Supported labels become release-qualified only after the corresponding compile, graphics, platform, and XR device gates pass.

Unity stream Expected URP stream Built-in URP Render Graph URP Compatibility Mode
Unity 6000.0.x URP 17.0.x Required Required Required
Unity 6000.3.x URP 17.3.x Required Required Not supported
Unity 6000.5.x URP 17.5.x Required Required Removed by Unity

The package manifest requires Unity 6000.0. Other Unity streams are not release-qualified, but the package does not reject or warn solely because an unqualified stream is installed. HDRP and UI Toolkit are unsupported in 0.1.

2.1.1 Unity and URP execution paths

Environment Execution path
Built-in, all qualified streams One visible TranslucentImageBuiltInRenderer bridge per source camera
URP 17.0 Universal Renderer ScriptableRendererFeature, Render Graph or Unity 6000.0 Compatibility Mode
URP 17.3 Universal Renderer ScriptableRendererFeature, Render Graph only
URP 17.5 Universal Renderer ScriptableRendererFeature, Render Graph only
URP 17.0 Renderer2D Ordinary renderer feature/pass, Render Graph or Unity 6000.0 Compatibility Mode
URP 17.3 Renderer2D Ordinary renderer feature/pass, Render Graph only
URP 17.5 Renderer2D Dedicated 2D feature/pass API, Render Graph only

2.1.2 Canvas and renderer matrix

Pipeline / renderer Screen Space Overlay Screen Space Camera World Space
Built-in Render Pipeline Supported Supported with an earlier source camera and later UI camera Supported with an earlier source camera and later UI camera
URP Universal Renderer Supported Supported with an earlier Base/source camera and later Overlay/UI camera Supported with an earlier Base/source camera and later Overlay/UI camera
URP 2D Renderer Supported Unsupported in 0.1 Unsupported in 0.1

2.2 Acyclic source-to-consumer rule

A TranslucentImage is supported only when the camera producing its TranslucentImageSource does not render that image’s effective canvas before source capture. The source-to-consumer graph must be acyclic: source camera, capture and blur submission, then consuming canvas. A rate-limited panel may intentionally use the last valid result from an earlier frame.

Screen Space Overlay works because it is not part of the scene camera color. Screen Space Camera and World Space require an earlier camera that excludes the consumer layer and a later aligned UI camera. A same-camera panel is recursive and unsupported.

2.3 XR scope

Version 0.1 implements Single Pass Instanced and Multiview only. The supported rows below are awaiting the required real-device qualification and must not be treated as release-qualified until that gate passes.

Combination Status
Built-in Forward + SPI/multiview + later stereo Screen Space Camera canvas Implemented; device qualification pending
Built-in Forward + SPI/multiview + later stereo World Space canvas Implemented; device qualification pending
URP Universal + SPI/multiview + later Overlay/UI Screen Space Camera canvas Implemented; device qualification pending
URP Universal + SPI/multiview + later Overlay/UI World Space canvas Implemented; device qualification pending
Built-in Deferred SPI, XR multipass, Renderer2D XR, or XR Screen Space Overlay Unsupported or not qualified

Linear-raster VRS foveation is supported where screen coordinates remain linear. Non-uniform-raster VRR, URP on-tile rendering, per-eye culling, and Multiview Render Regions for package passes are unsupported. See the XR section below.

2.4 Five-minute Built-in setup

  1. Add TranslucentImageSource to the scene camera. In its inspector, choose Add Built-in Camera Bridge to create the visible, persistent bridge with Undo.
  2. Create a panel with GameObject > UI > Translucent Image, or convert an existing Image from its context menu.
  3. Assign the source explicitly in the panel inspector. No scene-wide source search is performed.
  4. For the common setup, keep the Canvas in Screen Space Overlay. For camera or world canvases, use the two-camera arrangement described in the Built-in Render Pipeline setup section below.
  5. If an existing Canvas reports missing channels, select one or more TranslucentImage objects and run Tools > Translucent Image > Fix Canvas Channels, or use the component context/inspector action.

The bridge position among other OnRenderImage components is the shared capture stage for all sources on that camera. Move the bridge deliberately if other image effects must occur before or after capture.

2.5 Five-minute URP setup

  1. Add TranslucentImageSource to the scene camera.
  2. Open Tools > Translucent Image > URP Setup.
  3. Select every Universal or 2D renderer data asset that should render a source, then apply the setup. The tool adds the correct feature type without replacing the pipeline asset or changing Graphics/Quality settings.
  4. Create or convert a TranslucentImage, assign its source, and fix Canvas channels if prompted.
  5. Use Screen Space Overlay for the simple setup. Universal Renderer camera/world canvases require a Base source camera and later Overlay UI camera. Renderer2D supports Overlay consumers only.

The feature defaults to After Post Processing and can instead capture Before Post Processing. See the URP and Renderer2D setup sections below.

2.6 Guides and samples

The sections below cover multi-camera ordering, active regions, materials and UI effects, procedural foregrounds, external output, target textures, performance, and API ownership.

Package Manager exposes seven independent samples: Minimal Setup, Feature Demo, Procedural Foregrounds, Advanced Camera Setups — Built-in, Advanced Camera Setups — URP Universal, URP Setup — Universal Renderer, and URP Setup — 2D Renderer. Each includes its own scene assets and README and does not reference another optional sample. Sample qualification remains a release gate until the clean-fixture import/open/Play suite passes. URP setup never replaces the active pipeline asset.

2.7 Performance summary

  • Stable configurations allocate zero package-owned managed bytes per rendered frame after warm-up.
  • A source with no graphics, Preview, or lease demand performs no blur work.
  • Active-region processing allocates exact cropped transient levels and keeps one persistent high-water internal output.
  • Dynamic-resolution decreases do not shrink or churn that output. A larger structural requirement stages an atomic replacement.
  • Many consumers share source capture, output, and material generations. An exact-size external copy exists only while a lease is active.

2.8 Known limitations

  • Same-camera recursive capture is unsupported.
  • Renderer2D Screen Space Camera and World Space consumers are unsupported.
  • Arbitrary target-texture presentation transforms, letterboxing, portals, minimaps, and custom compositor mappings are not inferred.
  • Stencil shape, foreground alpha, UI occlusion, shader discard, and scene depth do not reduce the conservative active region.
  • UV1 and UV2 are reserved by the package shader contract; effects using them need a dedicated integration.
  • A material modifier that replaces the package shader contract falls back to foreground-only rendering.
  • Texture alpha raycasts never read back RenderTextures or external/video textures.
  • The internal high-water output is not public. Independent consumers must acquire an output lease.

See the Troubleshooting section below for diagnostics and corrective actions.

3 Built-in Render Pipeline setup

3.1 Screen Space Overlay

  1. Add TranslucentImageSource to the scene camera.
  2. In the source inspector, choose Add Built-in Camera Bridge. This creates one enabled, visible TranslucentImageBuiltInRenderer with Undo so its image-effect order can be authored before Play Mode.
  3. Create a panel with GameObject > UI > Translucent Image.
  4. Assign the source explicitly and use a Screen Space Overlay Canvas.
  5. Select the TranslucentImage and run Tools > Translucent Image > Fix Canvas Channels if its effective Canvas does not serialize TexCoord1 and TexCoord2.

Overlay UI is not part of the source camera image. A panel can blur the scene, but it cannot blur other Screen Space Overlay graphics.

3.2 Bridge ordering and multiple sources

The visible bridge owns the camera’s single OnRenderImage callback. Its component position among other image effects defines the capture stage shared by every enabled source on that camera. Source component order controls processing and Preview priority, not separate capture stages.

Every source samples the same unmodified incoming bridge texture. One source output is never fed into another source merely because both components share a camera. When the last source is disabled, the bridge disables itself but remains on the GameObject so authored image-effect order is preserved.

3.3 Screen Space Camera

Use two cameras:

  1. Camera A renders the scene or lower UI, owns the source, and excludes the translucent Canvas layer.
  2. Camera B has greater Camera.depth, renders that Canvas later, and is assigned as Canvas.worldCamera.
  3. Use Clear Flags = Nothing to preserve earlier depth for occlusion, or Clear Flags = Depth for always-on-top UI.
  4. Align viewport, target, transform, projection, stereo state, and physical-camera settings.

A canvas assigned to the same camera that owns its source is unsupported.

3.4 World Space

Camera A excludes the UI layer. A later aligned Camera B renders only that layer. Canvas.worldCamera is used for events and raycasts, but camera culling masks and depth determine which camera actually renders the Canvas.

If a world-space bound crosses the source near plane and a tight projection cannot be proven, the package requests the full source viewport to prevent under-capture.

3.5 Image-effect failures

If allocation or drawing fails, the bridge forwards the original image and leaves the structural capture generation pending. Preview replaces only BlurRegion; outside that region the original camera image is retained.

4 Universal Render Pipeline setup

4.1 Install the renderer feature

Open Tools > Translucent Image > URP Setup. The window discovers renderer data referenced by the active Graphics and Quality URP assets. Select the assets to modify and apply the setup.

The tool uses Undo, creates a renderer-owned sub-asset, avoids duplicates, and never replaces a pipeline asset or changes Graphics/Quality settings. It assigns renderer identity so unsupported Renderer2D XR cannot be mistaken for Universal Renderer XR.

4.2 Execution paths

Unity / URP Universal Renderer Renderer2D
6000.0 / 17.0 Render Graph; Compatibility Mode also supported Ordinary feature/pass, Render Graph or Compatibility Mode
6000.3 / 17.3 Render Graph Ordinary feature/pass, Render Graph
6000.5 / 17.5 Render Graph Dedicated 2D feature/pass, Render Graph

Unity 6000.0 Compatibility Mode is deliberately compile-time isolated. Later qualified streams use Render Graph only.

4.3 Capture event

The feature exposes Before Post Processing and After Post Processing, defaulting to After. All sources rendered through a renderer share this capture stage. Duplicate features are diagnosed, and a per-camera/frame token prevents duplicate blur submission.

Render Graph imports source-owned persistent and external outputs, creates graph-owned exact-region transients, and declares camera color, preview, export, and output dependencies. The final imported output write is the capture submission point.

4.4 Camera arrangements

Screen Space Overlay is the simplest supported consumer. For Screen Space Camera or World Space:

  1. Use a Base camera as the earlier source camera.
  2. Exclude the consuming Canvas layer from the Base camera.
  3. Add a later Overlay/UI camera to the same stack and render the Canvas there.
  4. Preserve world depth with Clear Depth disabled, or render always on top with Clear Depth enabled.
  5. Align projection, viewport, target, stereo state, and physical camera settings.

The package does not support a canvas sampling a source on its own effective camera.

4.5 Failure behavior

A failed source pass is skipped without corrupting camera color. The previous complete binding remains published when safe; a staged uninitialized texture is never exposed. Missing resources and incompatible layouts remain pending and produce an actionable, rate-limited diagnostic.

5 URP Renderer2D

Renderer2D supports Screen Space Overlay consumers only in version 0.1. Screen Space Camera, World Space, and XR Renderer2D consumers are unsupported.

Run Tools > Translucent Image > URP Setup on each Renderer2DData asset. URP 17.0 receives the ordinary renderer feature/pass for Render Graph and Unity 6000.0 Compatibility Mode. URP 17.3 uses that ordinary adapter with Render Graph only. URP 17.5 receives the dedicated ScriptableRendererFeature2D, ScriptableRenderPass2D, and RenderPassEvent2D implementation.

When a project moves to URP 17.5, the setup tool detects an older ordinary 2D feature and offers an explicit replacement while preserving the capture-event setting. Shared samples contain no version-specific renderer data, so the same imported content works after running the installed stream’s setup action.

The 2D adapter delegates scheduling, active-region planning, allocation, blur, material binding, Preview, and external export to the same runtime core as the Universal Renderer.

6 Multi-camera ordering and feedback prevention

6.1 The support rule

A consumer is supported only when its source camera does not render that consumer’s effective Canvas before source capture. Direct and indirect cycles are unsupported.

source camera renders scene/lower UI
→ source capture and blur are submitted
→ later camera or Overlay Canvas renders the consumer

Rate limiting may retain an earlier valid output, but it does not make a cyclic camera arrangement valid.

6.2 Overlay Canvas

A scene camera can feed a Screen Space Overlay panel because Overlay graphics render after camera output. That source cannot include other Overlay UI because Overlay is absent from the camera color.

6.3 Camera and World Space Canvas

Put the consuming UI on its own layer. The source camera excludes it; a later aligned camera includes it. In Built-in, order by Camera.depth. In URP, use Base then Overlay in one stack.

For World Space, keep transforms, view/projection matrices, viewport, target, physical-camera properties, and stereo layout aligned. Assign the later camera as Canvas.worldCamera for event/raycast behavior, but remember that culling masks decide rendering ownership.

6.4 Multiple sources

Multiple source components on one camera are independent in blur settings, demand, rate, region, output, and leases. They share a single capture stage and all sample the same incoming camera color. Component order chooses processing order and the first enabled Preview winner.

6.5 Diagnostics

Current inspectors detect same-camera Screen Space Camera assignments, World Space consumer layers included by the source camera, determinable Built-in camera-depth and clear-state mistakes, incorrect URP Base/Overlay stack order, unsupported Renderer2D canvas modes, XR Overlay use, and known source-to-source or UI cycles. Diagnostics are conservative and never rewrite camera or canvas settings automatically.

7 Target textures and camera viewports

A source camera with targetTexture is supported only when the consumer is rendered into the same target and normalized presentation space, or when the complete source target is presented one-to-one across the consumer’s effective viewport.

The backend uses the actual rendered target descriptor and physical viewport. It does not assume Screen.width, nor does it derive target extent solely from serialized Camera.rect.

Supported mapping is axis-aligned and covers non-fullscreen camera viewports, aligned later-camera presentation, aligned World Space projection, and one-to-one target presentation. The package does not infer arbitrary rotation, perspective, portal transforms, minimap rectangles, picture-in-picture placement, letterbox bars, or aspect-fit/fill behavior.

The material binding atomically composes target pixel/full-target UV, source viewport, BlurRegion, last submitted content UV, and high-water allocation UV. If the presentation transform is not one-to-one, provide a separate integration rather than relying on accidental screen coordinates.

8 XR

8.1 Qualified combinations

Version 0.1 implements Single Pass Instanced and Multiview only. The supported rows are awaiting the required real-device matrix and are not release-qualified until that gate passes.

Pipeline and consumer Status
Built-in Forward + later stereo Screen Space Camera Implemented; device qualification pending
Built-in Forward + later stereo World Space Implemented; device qualification pending
URP Universal Base/source + later Overlay/UI Screen Space Camera Implemented; device qualification pending
URP Universal Base/source + later Overlay/UI World Space Implemented; device qualification pending
Built-in Deferred SPI Unsupported
Built-in or URP multipass Not qualified / unsupported
Screen Space Overlay XR Unsupported
Renderer2D XR Unsupported

XR-specific C# is gated by ENABLE_VR && ENABLE_XR_MODULE. Each rendered camera is classified independently. A mono spectator, recording, reflection, or offscreen camera remains mono even when global XR is enabled. URP uses the active XR pass to distinguish multipass from Unity’s actual single-pass instancing or multiview path; diagnostics expose the observed mode.

8.2 Camera arrangement

Built-in uses a Forward stereo source camera and a later aligned stereo UI camera. URP uses a Base source camera and later compatible Overlay/UI camera. Both cameras must agree on target, projection, viewport, physical-camera settings, and stereo layout, while the source camera excludes the consuming layer.

Screen Space Overlay is unsupported in XR. Use Screen Space Camera or World Space on the later stereo UI camera.

8.3 Textures and active region

Camera descriptor dimension, slices/view count, VR usage, and active viewport are preserved while graphics format, MSAA, depth, mips, random write, and dynamic-scale flags are normalized for blur storage. A qualified stereo source with demand processes the complete BlurRegion; per-eye culling is not implemented.

Every crop, filter, fill, output, export, Preview, and UGUI pass carries stereo instance/eye state and samples texture arrays through the appropriate Built-in or URP screen-space abstraction.

8.4 Foveation and URP restrictions

Linear-raster VRS foveation is supported when screen coordinates remain linear. Non-uniform-raster VRR paths that require density or coordinate remapping are unsupported, including the version 0.1 visionOS non-uniform-raster path.

URP on-tile rendering/post-processing is unsupported because the package requires persistent off-tile outputs and transient blur textures. Package passes do not opt into Multiview Render Regions.

Device qualification must confirm that the requested SPI or multiview test did not fall back to multipass and that distinct left/right patterns survive every stage. Editor emulation alone is insufficient.

9 Active regions and rate limiting

9.1 Demand

A source captures only while at least one active graphic/custom provider contributes a nonempty region, an external lease exists, or Preview is enabled. SkipCulling does not create demand; it expands existing graphic demand to the full BlurRegion.

ConsumerRegion describes conservative graphic/provider demand. RequestedValidRegion expands that demand by CullPadding, then clips it to BlurRegion and the source viewport. Preview, leases, and qualified stereo demand request the full BlurRegion without changing ConsumerRegion.

The internal processing region is larger than the valid region. It is calculated by backward-propagating the exact tap support through each selected pyramid level, then adding a one-base-texel bilinear presentation guard. Minimum pixel edges use floor and maximum edges use ceiling.

9.2 What contributes to bounds

The package bounds the final modified FullComposite mesh, intersects nested RectMask2D rectangles through public UGUI clipping APIs, projects into source viewport space, and clips to the viewport. Standard Shadow/Outline effect geometry is ForegroundOnly and does not increase blur work.

The region intentionally does not shrink for stencil geometry, sprite/texture alpha, shader discard, material/Canvas alpha, UI occlusion, scene depth, or arbitrary custom-mask pixels. These omissions keep demand conservative and deterministic.

9.3 Strict validity

After successful submission, LastSubmittedValidRegion records the requested region satisfied and the internal processing region records the larger written area. Skipped, limited, empty, and failed frames do not change either value.

The UGUI shader samples blur only inside the last valid region and clamps texture lookup to the last processing region. It never samples historical pixels outside current validity. With no source fill, uncovered main geometry draws foreground only. With Solid Color fill, the opaque fill remains a valid background.

Fast UI motion can temporarily leave new demand outside a rate-limited valid region. Increase CullPadding, increase MaxUpdateRate, enable SkipCulling, or use a solid fill if foreground-only fallback is visually distracting.

9.4 Scheduling

  • MaxUpdateRate > 0 limits normal periodic submission to one capture per interval using unscaled/render time.
  • MaxUpdateRate == 0 captures once for each structural invalidation, then freezes.
  • A structural invalidation bypasses one finite-rate interval so a first or replacement output becomes valid promptly.
  • Preview requests a full-region capture on every rendered frame and bypasses rate limiting.
  • At most one capture is submitted per source per source-camera render.

Pending generations survive absent demand, an empty intersection, allocation/recording failure, a camera that does not render, and event-driven freeze. Capture and external-export generations complete independently, so an export retry does not rerun a current full-region blur.

9.5 Blur strength and resolution

Strength matching uses the full physical source viewport divided by 2^Downsample, then logarithmically interpolates width and height scale relative to ReferenceResolution. Cropping and integer output rounding therefore do not change apparent authored strength.

Downsample primarily changes cost and detail. Zero strength means no additional filter beyond required crop/resampling and configured downsampling; downsampling may still soften the image.

10 Materials, masks, and UI effects

10.1 Standard UGUI behavior

Sprite mode delegates base geometry to Image, retaining Simple, Sliced, Tiled, Filled, preserve-aspect, sprite border, pixels-per-unit, override-sprite, layout, and explicit native-size behavior. Texture mode generates a RawImage-style quad with negative, flipped, or repeated UV rectangles.

The package supports stencil Mask, nested RectMask2D, clip softness, standard Shadow, and standard Outline. Foreground-only effects use texture alpha for their silhouette, never sample blur, and ignore panel appearance controls.

10.2 Reserved vertex channels

The effective Canvas must serialize TexCoord1 and TexCoord2. UV1 stores appearance controls; UV2 stores geometry role, alpha/background modes, split-alpha state, Canvas color-space state, and a validity signature. Run Tools > Translucent Image > Fix Canvas Channels when prompted.

Third-party effects that use UV1 or UV2 for unrelated data need a dedicated integration. A modifier that clears or corrupts reserved data receives a development diagnostic; overlapping roles are restored where safe and unknown generated geometry defaults to FullComposite.

Implement ITranslucentImageMeshModifierClassifier on the modifier or another component on the same GameObject to classify generated vertex ranges or indices as ForegroundOnly. The adapter sees vertices and roles but does not own package UV packing.

10.3 Material modifier contract

The component evaluates each IMaterialModifier once in actual component order, including normal MaskableGraphic stencil generation. It binds source state to package-owned clones and terminal snapshots; user assets and third-party-owned materials are never mutated.

A compatible shader exposes the package property/tag contract for blur texture, mapping, valid/processing regions, fill, blue noise, UGUI main/alpha textures, and stencil properties. A downstream modifier that replaces this contract is diagnosed by component/shader and renders the package foreground-only fallback rather than magenta or stale blur.

Runtime changes to an authored/upstream material are detected by a once-per-frame shared CRC. A new generation receives fresh stencil and downstream results; ordinary output/mapping changes update package-owned bindings without recreating materials.

10.4 Alpha modes

In Transparency mode, foreground texture alpha cuts the whole panel coverage. In Foreground Opacity mode, texture alpha affects only foreground contribution and the blurred panel remains rectangular. When no valid blur or fill exists, both modes reduce to foreground-only coverage.

For effective texture alpha At, UGUI alpha Au, rectangular clip factor Am, and foreground opacity P:

Transparency:      foregroundWeight = P,      coverage = saturate(Au × At × Am)
ForegroundOpacity: foregroundWeight = P × At, coverage = saturate(Au × Am)

Package shaders return premultiplied RGB and use Blend One OneMinusSrcAlpha for RGB and alpha. RGB is multiplied by final alpha exactly once.

Android ETC1 RGB+A atlases use the effective sprite’s associated split-alpha texture through CanvasRenderer.SetAlphaTexture; the package never substitutes Unity’s UI/DefaultETC1 shader.

10.5 Appearance controls

All appearance math runs in linear light. Brightness maps -1, 0, and +1 to 0.25×, 1×, and 4× exposure. Vibrancy maps -1 to complementary chroma, 0 to grayscale, 1 to original chroma, and 2 to doubled chroma. Flatten moves luminance toward linear sRGB 0.5 (0.21404114) while reducing chroma.

Normal mode adjusts background luminance/chroma, applies exposure, then interpolates toward the foreground by foreground weight. Colorful mode uses the foreground as a tint multiplier, moves luminance toward exposed mid-gray by foreground weight, and analytically fits signed chroma while preserving luminance and nonnegative channels. HDR luminance above one remains allowed; negative luminance remains negative grayscale.

Y = dot(background, (0.2126, 0.7152, 0.0722))
C = background - Y
Yflat = lerp(Y, 0.21404114, Flatten)
Cflat = C × (1 - Flatten)
exposure = 2^(2 × Brightness)

Normal:
adjusted = (Yflat + Cflat × Vibrancy) × exposure
result = lerp(adjusted, foreground, foregroundWeight)

Colorful:
base = (Yflat + Cflat) × exposure
tinted = base × lerp(1, foreground, foregroundWeight)
outputY = lerp(luminance(base), 0.21404114 × exposure, foregroundWeight)
result = FitChromaToLuminance(outputY, chroma(tinted) × Vibrancy)

The analytic fit chooses the largest scale in [0,1] that preserves outputY while keeping channels nonnegative and, for luminance up to one, no greater than one. Normal mode performs no final clamp.

Only final FullComposite UGUI color is dithered. The deterministic 64×64 R8 blue-noise texture adds one peak-to-peak perceptual 8-bit code value to bounded interior RGB before premultiplication and never changes alpha.

10.6 Camera color, storage, and fill

Internal storage is normalized rather than copied from arbitrary camera formats:

Capture Storage
LDR in a Linear project R8G8B8A8_SRGB
LDR in a Gamma project R8G8B8A8_UNorm
HDR R16G16B16A16_SFloat

The actual rendered frame descriptor decides HDR. A format must support render-target use, shader sampling, linear filtering, and four-channel alpha. Unsupported HDR16 falls back once to project-appropriate LDR8; if no suitable LDR RGBA format exists, capture stays pending and consumers use deterministic fallback.

Captured RGB is treated as already composited, associated/additive-compatible color. It is never multiplied by camera alpha before filtering or divided by alpha afterward, so RGB in alpha-zero glow pixels survives.

Solid source fill is applied only in the final persistent-output write:

a = saturate(blurred.a)
output.rgb = blurred.rgb + fill.rgb × (1 - a)
output.a = 1

Fill alpha is ignored. A camera path with opaque or meaningless alpha still supports ordinary opaque blur, but transparent-background passthrough and fill semantics receive an actionable diagnostic.

11 Procedural foregrounds

Add TranslucentImageProceduralTexture beside a TranslucentImage to render a user material into a package-owned foreground texture. The generator claims the image’s single owner-controlled texture override; authored sprite, texture, content mode, and UV state remain unchanged underneath it.

11.1 Precision and size

  • Ldr8 uses sRGB RGBA8 in Linear projects and UNorm RGBA8 in Gamma projects.
  • Hdr16 requests RGBA16 float and falls back to Ldr8 with one warning when unsupported.

The generated size follows the graphic’s pixel-adjusted dimensions, effective Canvas scale, and positive resolution scale. It is at least one pixel for nonempty graphics. Allocation changes never call SetNativeSize automatically.

While an owner-controlled texture override is active, preferred layout dimensions retain the panel’s current width and height in Canvas units. A ContentSizeFitter therefore preserves that size instead of using the generated texture’s pixel dimensions. Resolution scale and Canvas scale affect rendering resolution without feeding back into layout. Set the panel size or use a LayoutElement to choose a different layout size.

Targets have no depth, MSAA, mips, random write, or dynamic scaling, and use bilinear/clamp sampling. The resolved format must be renderable, filterable, sampleable, and alpha-capable.

11.2 Updates and ownership

UpdateEveryFrame supports time-driven shaders. When disabled, enable, material assignment, allocation/precision changes, relevant validation changes, and RequestRender() mark the output dirty.

The package draws fullscreen without mutating the user material. Replacement textures are published to the override before the old texture is retired. Disable, destruction, allocation failure, and assembly reload clear the override before destroying owned resources, so the latest authored foreground becomes visible immediately.

Generated output is a RenderTexture. AlphaIfReadable raycasts therefore fall back to rectangular hit testing; no GPU readback is performed.

Only one texture-override owner may be active. A competing owner is rejected with one actionable warning.

12 External output leases

Package UGUI consumers sample the source-owned internal high-water output directly. Independent third-party or non-UGUI consumers must call:

var leaseResult = source.AcquireOutput(owner);
if (leaseResult.IsFailure)
{
    // React to leaseResult.Error.
    return;
}

var lease = leaseResult.Value;

owner must be a live, non-null UnityEngine.Object. Keep the returned TranslucentImageOutputLease, subscribe to Changed if texture identity matters, and call Dispose() when finished.

12.1 Ownership contract

The source owns the lease, texture, allocation, publication, resize, release, and invalidation. A consumer must not destroy, release, resize, reconfigure, or retain the texture after the lease becomes invalid. Dispose is idempotent. Destroyed owners are pruned on the main thread.

Source disable/destruction invalidates leases before resource release. The lease object may outlive invalidation, but Texture becomes null, Size becomes zero, and IsValid becomes false.

12.2 Cost and scheduling

Any lease requests the full BlurRegion. While at least one lease exists, the source follows normal MaxUpdateRate rules; an event-driven source captures once per structural invalidation and freezes.

After a successful full-region capture, one shared exact-size texture is staged and one raster copy maps the internal content rectangle to UV [0,1]. All leases share it. With zero leases, no external texture, wrapper, binding, or copy pass exists.

Capture and export generations are independent. If blur submission succeeds but export allocation/copy fails, the internal capture completes and export remains pending. A later frame retries only the export when the full internal result is still current.

12.3 Ordering

A consumer needing this frame’s export must render after capture/export. In URP Render Graph, record the consumer after the Translucent Image renderer feature and call TranslucentImageUrpOutput.GetTexture(renderGraph, lease). Check the result and its optional value, then declare a present texture handle as a read dependency on the consumer pass. Importing lease.Texture independently does not express a dependency on the package’s export copy and is unsupported for current-frame use.

The method returns a successful empty optional until the package has recorded a valid export in that camera graph. An earlier consumer sees the previous successful export; a consumer rendered into the source camera before capture creates feedback and is unsupported.

13 API and ownership

All public members include XML documentation in the runtime assembly. This guide summarizes lifecycle and ownership rules that are easy to miss when integrating.

Assemblies that consume the typed failure APIs through a custom .asmdef must reference both Zal.TranslucentImage and Zal.Common; Unity assembly references are not transitive.

13.1 TranslucentImageSource

Attach to a Camera. Multiple components are allowed. Set blur, resolution matching, region, rate, culling, Preview, and fill properties, then assign the source explicitly to each graphic.

ForceRefresh() increments structural capture demand. The request remains pending until a complete plan is successfully submitted; it is not lost when the camera does not render or allocation fails.

ConsumerRegion and RequestedValidRegion describe current CPU demand. LastSubmittedValidRegion, output size/pixel/UV rectangles, format, HDR state, and completed generations describe the last successfully submitted publication. They are intentionally not interchangeable.

The source owns its internal high-water texture, external texture, transient execution state, material generations, registry entries, and provider registrations. The internal texture is deliberately not public.

13.2 TranslucentImage

Sprite mode retains Image behavior. Texture mode uses RawTexture and UvRect. EffectiveContentMode, EffectiveForegroundTexture, EffectiveUvRect, HasTextureOverride, and TextureOverrideOwner reveal the rendered state without modifying authored fields.

Appearance values travel per vertex, allowing many graphics to share source/material generations. The component owns neither its authored sprite/texture nor authored material.

13.3 Active-region providers

Register an IActiveRegionProvider with a separate non-null owner object. Registration and removal return Optional<TranslucentImageActiveRegionRegistrationError>; an empty optional means success. The provider returns Result<Optional<Rect>, TranslucentImageActiveRegionError> so no demand and provider failure remain distinct. It must return only conservative normalized source-viewport demand and must not add padding, filter support, culling/fill/Preview/export policy, or XR expansion; the source planner owns those steps. Unregister the provider when no longer needed. Destroyed owners are pruned.

13.4 External leases

AcquireOutput(owner) returns Result<TranslucentImageOutputLease, TranslucentImageOutputAcquireError>. On success, the value is a source-owned, reference-counted lease. Until publication, or after invalidation, IsValid is false and Texture is null. Changed fires after publication, replacement, or invalidation and is safe for reentrant disposal/acquisition.

Never destroy or reconfigure the leased RenderTexture. Dispose the lease; the source retires GPU resources after recorded work can no longer reference them.

For a later URP Render Graph pass, call TranslucentImageUrpOutput.GetTexture(renderGraph, lease) while recording after the package feature, check the returned result and optional value, and declare a present texture handle as a read dependency. An empty optional means the export has not yet been recorded in that graph. This reuses the package’s logical import; importing lease.Texture again does not establish current-frame export ordering.

13.5 Procedural foregrounds

TranslucentImageProceduralTexture.GeneratedTexture is package-owned and nonpersistent. Do not destroy it. RequestRender() marks an event-driven generator dirty and returns Optional<TranslucentImageProceduralRenderError>; an empty optional means the request succeeded or was safely deferred while disabled. Disabling the generator clears its override before texture retirement, revealing the current authored image state.

13.6 Mesh classifier adapters

ITranslucentImageMeshModifierClassifier assigns FullComposite or ForegroundOnly roles to modifier output through ITranslucentImageVertexRoleWriter. Classification and role writes return typed optional errors. The context provides read-only input/output information and typed vertex-access results; package UV packing remains private.

13.7 Disable and destruction

Source disable unregisters it, invalidates leases, disposes package material clones, retires owned outputs, and clears submitted state. Graphics then use foreground-only or solid-fill fallback. Static registries and coordinators reset at subsystem registration for domain-reload-disabled Play Mode.

14 Performance and memory

14.1 CPU and allocations

After warm-up, package-owned runtime code allocates zero managed bytes per rendered frame for a stable hierarchy and configuration. Registries, mask traversal, mesh streams, role metadata, material modifiers, capture plans, blur levels, and descriptors reuse storage. Allocations inside third-party modifiers are outside this guarantee.

Profiler markers are compiled only with ENABLE_PROFILER and cover source preparation, active-region calculation, blur planning, persistent allocation, Built-in execution, URP graph recording, every blur stage, external export, mesh generation/classification, material evaluation/cache maintenance, and procedural rendering.

14.2 GPU work

A no-demand source allocates no scratch textures and issues no blur draw. A Built-in bridge disables when no enabled source remains. Every due source captures at most once per source-camera render, and multiple sources sample the same original camera input.

Transient texture dimensions match exact integer processing rectangles at each pyramid level. Active-region culling therefore reduces both attachment dimensions and shaded pixels. Preview, external leases, and qualified stereo intentionally process the full BlurRegion.

14.3 Persistent memory estimate

The internal output grows to the largest required dimensions for its current structural descriptor and does not shrink with dynamic-resolution decreases. Approximate mono storage is:

allocation width × allocation height × bytes per pixel

RGBA8 uses 4 bytes/pixel; RGBA16 float uses 8. Texture arrays multiply by view/slice count. Temporary pyramid memory depends on the exact cropped regions submitted that frame. An active external lease adds one exact-current-size output of the same normalized format/layout.

14.4 Material scaling

Appearance values are per-vertex. Material count scales with unique source, upstream material state, stencil state, downstream modifier result, and material generation—not automatically with graphic count.

14.5 Practical tuning

Use active culling for localized panels, choose Performance taps when quality permits, increase Downsample for lower detail/cost, lower MaxUpdateRate for slowly changing content, and avoid Preview outside diagnostics. Profile both shaded area and transient attachment size; iteration count affects the complete down/up pyramid.

15 Troubleshooting

15.1 The panel shows foreground only

  • Assign an enabled source explicitly.
  • Confirm the source camera actually renders.
  • In URP, run Tools > Translucent Image > URP Setup for the active renderer data.
  • Check the source’s last failure, requested region, valid region, format, and backend diagnostics.
  • In URP, open Window > Analysis > Rendering Debugger and select Zal Translucent Image. The panel retains the latest package error and its live Unity object context for the current Play Mode session; clear it after resolving the underlying configuration.
  • Verify the consumer is inside BlurRegion and the latest rate-limited valid region.
  • Confirm the final material shader implements the package contract.

Foreground-only output is the deterministic no-fill fallback, not a black error panel.

15.2 Missing Canvas channels

Run Tools > Translucent Image > Fix Canvas Channels or the component context action. The command ORs TexCoord1 and TexCoord2 into the effective Canvas with Undo and preserves unrelated flags. Runtime repair is temporary; serialize the Canvas setup before building.

15.3 Same-camera or feedback warning

Move the consumer to Screen Space Overlay, or create a later UI camera. Exclude the consumer layer from the source camera. In URP use Base then Overlay; in Built-in give the UI camera greater depth. See the Multi-camera ordering and feedback prevention section below.

15.4 Moving panels reveal an unblurred area

The current demand moved outside LastSubmittedValidRegion before the next rate-limited capture. Increase CullPadding or update rate, enable SkipCulling, or configure solid fill. The shader deliberately refuses stale samples.

15.5 Transparent camera background or fill looks wrong

Inspect Source Alpha diagnostics. Some camera paths expose opaque or meaningless alpha even when the normalized output has four channels. Fill and passthrough semantics require meaningful source alpha; storage alpha alone is not proof.

15.6 Material modifier warning

Do not mutate a shared incoming material or replace the shader with one that lacks package texture, mapping, fill, blue-noise, main/alpha, and stencil properties. Ensure modifiers call SetMaterialDirty after state changes. Add a dedicated shader integration when replacement is intentional.

15.7 Mesh modifier warning

The modifier cleared UV1/UV2 or rebuilt/reordered geometry without preserving role data. Preserve complete UIVertex data or implement ITranslucentImageMeshModifierClassifier. Unknown vertices default to blur-compositing geometry for safety.

15.8 Texture alpha raycast stays rectangular

Positive alpha thresholds require readable, CPU-sampleable Texture2D content in Transparency mode. Split-alpha/unreadable atlases, RenderTextures, video/external textures, and unsupported compressed formats fall back to a rectangle. The package never reads pixels back from the GPU.

15.9 XR is rejected

Active SPI and multiview passes are implemented but still await the required device qualification. Built-in must use Forward; URP must use Universal Renderer; the consumer must use a later stereo Screen Space Camera or World Space camera. Renderer2D XR, multipass, and XR Overlay Canvas are unsupported. Run URP Setup if renderer identity is unconfigured.

15.10 Validate before build

Run Tools > Translucent Image > Validate Project Setup. It checks resources and shaders, serialized Canvas channels, URP features, known canvas/renderer/XR conflicts, and alpha-dependent source settings. It does not reject a build solely for using an unqualified Unity stream.

Sample guides