> For the complete documentation index, see [llms.txt](https://morningheartgames.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://morningheartgames.gitbook.io/docs/asyncautoexposure/introduction/core-concepts.md).

# Core Concepts

## What The Plugin Does

Async Auto Exposure measures the average brightness of an input texture, calculates an exposure multiplier, and applies that multiplier to produce a corrected output texture.

This helps when content becomes too dark or too bright because of lighting changes, backlit subjects, scene cuts, or inconsistent source video.

## Runtime Pipeline

Each analysis cycle:

1. The input texture is downsampled to a smaller grayscale texture.
2. Unity queues an `AsyncGPUReadback` request.
3. The readback completes later, normally one or more frames after it was requested.
4. The plugin averages the returned luminance bytes.
5. A target exposure multiplier is calculated.
6. `CurrentExposure` smoothly interpolates toward `TargetExposure`.
7. The corrected frame is written to the output `RenderTexture`.

## Why AsyncGPUReadback Matters

Synchronous GPU readback can stall the main thread because the CPU waits for GPU data immediately.

`AsyncGPUReadback` avoids that stall by letting the GPU return data later. The main thread only handles the result when it is ready.

On WebGL builds, Unity does not provide the same native async path, so the plugin uses its synchronous fallback for brightness calculation.

## Target Brightness

`targetBrightness` is the average luminance the plugin tries to reach.

Typical values:

* `0.3`: darker image
* `0.4`: balanced default
* `0.5`: brighter image

## Exposure Formula

When measured brightness is valid, the target multiplier is:

```
targetExposure = clamp(targetBrightness / measuredBrightness, minExposure, maxExposure)
```

If the measured brightness is nearly black, the plugin keeps the previous target instead of applying an unstable value.

## Exposure Limits

`minExposure` and `maxExposure` keep the correction within a safe range.

Use lower `maxExposure` values when you want to avoid noisy or washed-out images. Use higher values when your source can become extremely dark.

## Adaptation Speed

`adjustmentSpeed` controls how quickly `CurrentExposure` moves toward `TargetExposure`.

* Lower values feel smoother and more cinematic.
* Higher values react faster to sudden lighting changes.
* Very high values can make noisy inputs look unstable.

## Readback Cadence

`readbackFrameSkip` controls how often brightness is measured.

| Value | Meaning                              |
| ----: | ------------------------------------ |
|   `0` | Request brightness every frame       |
|   `2` | Request brightness every third frame |
|   `4` | Request brightness every fifth frame |

The exposure multiplier still eases every frame. Only the expensive measurement step is throttled.

## Output Texture Ownership

`ProcessTexture()` and `ProcessTextureWithMask()` return a `RenderTexture` stored on the `AsyncAutoExposure` component. The same output texture is reused while the input size stays the same.

Do not manually release the returned texture. The component releases its internal textures in `OnDestroy()` and recreates them when input dimensions change.

## Masked Metering

`ProcessTextureWithMask()` measures only pixels whose mask value is above the internal threshold. This is useful when the subject should determine exposure and the background should not.

The corrected output is still the full source image. The mask only affects brightness measurement.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://morningheartgames.gitbook.io/docs/asyncautoexposure/introduction/core-concepts.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
