Skip to content

Commit 3d7e059

Browse files
committed
fixed hdr auto exposure
1 parent dc3354e commit 3d7e059

File tree

4 files changed

+47
-34
lines changed

4 files changed

+47
-34
lines changed

fyrox-graphics-gl/src/shaders/shared.glsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,12 +416,12 @@ vec3 S_ConvertYxyToXyz(vec3 Yxy)
416416
return xyz;
417417
}
418418

419-
vec3 convertRGB2Yxy(vec3 rgb)
419+
vec3 S_ConvertRgbToYxy(vec3 rgb)
420420
{
421421
return S_ConvertXyzToYxy(S_ConvertRgbToXyz(rgb));
422422
}
423423

424-
vec3 convertYxy2RGB(vec3 Yxy)
424+
vec3 S_ConvertYxyToRgb(vec3 Yxy)
425425
{
426426
return S_ConvertXyzToRgb(S_ConvertYxyToXyz(Yxy));
427427
}

fyrox-impl/src/renderer/hdr/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,20 +310,18 @@ impl HighDynamicRangeRenderer {
310310
})
311311
.unwrap_or((&self.stub_lut, &renderer_resources.nearest_clamp_sampler));
312312

313-
let (is_auto, key_value, min_luminance, max_luminance, fixed_exposure) = match exposure {
313+
let (is_auto, min_luminance, max_luminance, fixed_exposure) = match exposure {
314314
Exposure::Auto {
315-
key_value,
316315
min_luminance,
317316
max_luminance,
318-
} => (true, key_value, min_luminance, max_luminance, 0.0),
319-
Exposure::Manual(fixed_exposure) => (false, 0.0, 0.0, 0.0, fixed_exposure),
317+
} => (true, min_luminance, max_luminance, 0.0),
318+
Exposure::Manual(fixed_exposure) => (false, 0.0, 0.0, fixed_exposure),
320319
};
321320

322321
let color_grading_enabled = use_color_grading && color_grading_lut.is_some();
323322
let properties = PropertyGroup::from([
324323
property("worldViewProjection", &frame_matrix),
325324
property("useColorGrading", &color_grading_enabled),
326-
property("keyValue", &key_value),
327325
property("minLuminance", &min_luminance),
328326
property("maxLuminance", &max_luminance),
329327
property("autoExposure", &is_auto),

fyrox-impl/src/renderer/shaders/hdr_map.shader

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
kind: PropertyGroup([
2727
(name: "worldViewProjection", kind: Matrix4()),
2828
(name: "useColorGrading", kind: Bool()),
29-
(name: "keyValue", kind: Float()),
3029
(name: "minLuminance", kind: Float()),
3130
(name: "maxLuminance", kind: Float()),
3231
(name: "autoExposure", kind: Bool()),
@@ -89,21 +88,33 @@
8988
return texture(colorMapSampler, scale * color + offset).rgb;
9089
}
9190

92-
void main() {
93-
vec4 hdrColor = texture(hdrSampler, texCoord);
91+
// Narkowicz 2015, "ACES Filmic Tone Mapping Curve"
92+
float TonemapACES(float x) {
93+
const float a = 2.51;
94+
const float b = 0.03;
95+
const float c = 2.43;
96+
const float d = 0.59;
97+
const float e = 0.14;
98+
return (x * (a * x + b)) / (x * (c * x + d) + e);
99+
}
94100

95-
hdrColor += texture(bloomSampler, texCoord);
101+
void main() {
102+
vec4 hdrColor = texture(hdrSampler, texCoord) + texture(bloomSampler, texCoord);
96103

97-
float luminance = texture(lumSampler, vec2(0.5, 0.5)).r;
104+
vec3 Yxy = S_ConvertRgbToYxy(hdrColor.rgb);
98105

99-
float exposure;
106+
float lp;
100107
if (properties.autoExposure) {
101-
exposure = properties.keyValue / clamp(luminance, properties.minLuminance, properties.maxLuminance);
108+
float avgLum = texture(lumSampler, vec2(0.5, 0.5)).r;
109+
float clampedAvgLum = clamp(avgLum, properties.minLuminance, properties.maxLuminance);
110+
lp = Yxy.x / (9.6 * clampedAvgLum + 0.0001);
102111
} else {
103-
exposure = properties.fixedExposure;
112+
lp = Yxy.x * properties.fixedExposure;
104113
}
105114

106-
vec4 ldrColor = vec4(vec3(1.0) - exp(-hdrColor.rgb * exposure), hdrColor.a);
115+
Yxy.x = TonemapACES(lp);
116+
117+
vec4 ldrColor = vec4(S_ConvertYxyToRgb(Yxy), hdrColor.a);
107118

108119
if (properties.useColorGrading) {
109120
outLdrColor = vec4(ColorGrading(S_LinearToSRGB(ldrColor).rgb), ldrColor.a);

fyrox-impl/src/scene/camera.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -290,39 +290,43 @@ impl Default for Projection {
290290

291291
/// Exposure is a parameter that describes how many light should be collected for one
292292
/// frame. The higher the value, the more brighter the final frame will be and vice versa.
293-
#[derive(Visit, Copy, Clone, PartialEq, Debug, Reflect, AsRefStr, EnumString, VariantNames)]
293+
#[derive(
294+
Visit,
295+
Copy,
296+
Clone,
297+
PartialEq,
298+
Debug,
299+
Reflect,
300+
AsRefStr,
301+
EnumString,
302+
VariantNames,
303+
Serialize,
304+
Deserialize,
305+
)]
294306
pub enum Exposure {
295307
/// Automatic exposure based on the frame luminance. High luminance values will result
296-
/// in lower exposure levels and vice versa. This is default option.
297-
///
298-
/// # Equation
299-
///
300-
/// `exposure = key_value / clamp(avg_luminance, min_luminance, max_luminance)`
308+
/// in lower exposure levels and vice versa.
301309
Auto {
302-
/// A key value in the formula above. Default is 0.01556.
303-
#[reflect(min_value = 0.0, step = 0.1)]
304-
key_value: f32,
305-
/// A min luminance value in the formula above. Default is 0.00778.
310+
/// A min luminance value. The lower the value, the higher exposure values will be used for
311+
/// dark images. The default value is 0.035.
306312
#[reflect(min_value = 0.0, step = 0.1)]
307313
min_luminance: f32,
308-
/// A max luminance value in the formula above. Default is 64.0.
314+
/// A max luminance value. The higher the value, the lower exposure values will be used for
315+
/// bright images. The default value is 10.0.
309316
#[reflect(min_value = 0.0, step = 0.1)]
310317
max_luminance: f32,
311318
},
312319

313-
/// Specific exposure level. To "disable" any HDR effects use [`std::f32::consts::E`] as a value.
320+
/// Specific exposure level. To "disable" any HDR effects use 1.0 as a value. This is the default
321+
/// option.
314322
Manual(f32),
315323
}
316324

317325
uuid_provider!(Exposure = "0e35ee3d-8baa-4b0c-b3dd-6c31a08c121e");
318326

319327
impl Default for Exposure {
320328
fn default() -> Self {
321-
Self::Auto {
322-
key_value: 0.18,
323-
min_luminance: 0.001,
324-
max_luminance: 24.0,
325-
}
329+
Self::Manual(1.0)
326330
}
327331
}
328332

@@ -1040,7 +1044,7 @@ impl CameraBuilder {
10401044
z_far: 2048.0,
10411045
viewport: Rect::new(0.0, 0.0, 1.0, 1.0),
10421046
environment: None,
1043-
exposure: Exposure::Manual(std::f32::consts::E),
1047+
exposure: Default::default(),
10441048
color_grading_lut: None,
10451049
color_grading_enabled: false,
10461050
projection: Projection::default(),

0 commit comments

Comments
 (0)