@@ -77,19 +77,18 @@ void main_cs(uint3 thread_id : SV_DispatchThreadID)
7777 avg_nits = exp2 (weighted_log_sum / max (weight_sum, 0.000001f ));
7878 }
7979
80- // 2. auto exposure works on top of the manual camera exposure, so the target is in post-camera scene-linear space
80+ // 2. keep the existing camera-relative metering so artistic exposure choices remain intact
8181 float camera_exposure = max (buffer_frame.camera_exposure, 0.000001f );
8282 float current_brightness = avg_nits * camera_exposure;
8383
84- // 3. target middle gray so auto exposure refines the camera settings
85- // instead of pushing every scene toward a bright daytime look .
84+ // 3. target middle gray using the final exposure value that the renderer applies.
85+ // storing the resolved exposure keeps temporal upscalers in sync with output .
8686 const float target_luminance = 0.18f ;
8787
88- // 4. compute the ae multiplier needed to bring the current average toward middle gray
88+ // 4. compute the camera-relative auto exposure trim
8989 float desired_exposure = target_luminance / max (current_brightness, 0.000001f );
9090
91- // 5. keep auto exposure as a trim around the physical camera settings.
92- // this preserves intentionally dark scenes such as night shots.
91+ // 5. clamp the auto exposure trim to a practical range
9392 const float min_ev = -4.0f ;
9493 const float max_ev = 3.0f ;
9594
@@ -98,19 +97,20 @@ void main_cs(uint3 thread_id : SV_DispatchThreadID)
9897
9998 desired_exposure = clamp (desired_exposure, min_exposure, max_exposure);
10099
101- // 6. temporal adaptation in ev space so large changes remain stable
100+ // 6. resolve the final exposure and adapt it in ev space so large changes remain stable
101+ float desired_total_exposure = camera_exposure * desired_exposure;
102102 float prev_exposure = tex2.Load (int3 (0 , 0 , 0 )).r;
103103 float adaptation_speed = pass_get_f3_value ().x;
104104
105105 // start from the current target to avoid a first-frame flash
106106 if (isnan (prev_exposure) || prev_exposure <= 0.0f )
107107 {
108- prev_exposure = desired_exposure ;
108+ prev_exposure = desired_total_exposure ;
109109 }
110110
111111 // higher values should adapt faster, so the response scales with the user-controlled speed directly
112112 float prev_ev = log2 (max (prev_exposure, 0.000001f ));
113- float desired_ev = log2 (max (desired_exposure , 0.000001f ));
113+ float desired_ev = log2 (max (desired_total_exposure , 0.000001f ));
114114 float adaptation_alpha = 1.0f - exp (-max (adaptation_speed, 0.0f ) * 4.0f * buffer_frame.delta_time);
115115 float exposure = exp2 (lerp (prev_ev, desired_ev, adaptation_alpha));
116116
0 commit comments