You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-12 13:20:55 +00:00
Merge pull request #50883 from BastiaanOlij/mobile_hdr
Scale color output in the mobile renderer to provide HDR support
This commit is contained in:
@@ -38,6 +38,8 @@ layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
// We do not apply our color scale for our mobile renderer here, we'll leave our colors at half brightness and apply scale in the tonemap raster.
|
||||
|
||||
#ifdef MODE_MIPMAP
|
||||
|
||||
vec2 pix_size = blur.pixel_size;
|
||||
|
||||
@@ -6,6 +6,6 @@ layout(push_constant, binding = 1, std430) uniform PushConstant {
|
||||
float exposure_adjust;
|
||||
float min_luminance;
|
||||
float max_luminance;
|
||||
float pad;
|
||||
uint pad1;
|
||||
}
|
||||
settings;
|
||||
|
||||
@@ -374,6 +374,9 @@ layout(constant_id = 9) const uint sc_directional_penumbra_shadow_samples = 4;
|
||||
layout(constant_id = 10) const bool sc_decal_use_mipmaps = true;
|
||||
layout(constant_id = 11) const bool sc_projector_use_mipmaps = true;
|
||||
|
||||
// not used in clustered renderer but we share some code with the mobile renderer that requires this.
|
||||
const float sc_luminance_multiplier = 1.0;
|
||||
|
||||
#include "scene_forward_clustered_inc.glsl"
|
||||
|
||||
/* Varyings */
|
||||
|
||||
@@ -969,7 +969,7 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes
|
||||
|
||||
vec4 reflection;
|
||||
|
||||
reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, reflections.data[ref_index].index), roughness * MAX_ROUGHNESS_LOD).rgb;
|
||||
reflection.rgb = textureLod(samplerCubeArray(reflection_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(local_ref_vec, reflections.data[ref_index].index), roughness * MAX_ROUGHNESS_LOD).rgb * sc_luminance_multiplier;
|
||||
|
||||
if (reflections.data[ref_index].exterior) {
|
||||
reflection.rgb = mix(specular_light, reflection.rgb, blend);
|
||||
|
||||
@@ -401,6 +401,8 @@ layout(constant_id = 14) const bool sc_disable_fog = false;
|
||||
|
||||
#endif //!MODE_RENDER_DEPTH
|
||||
|
||||
layout(constant_id = 15) const float sc_luminance_multiplier = 2.0;
|
||||
|
||||
/* Include our forward mobile UBOs definitions etc. */
|
||||
#include "scene_forward_mobile_inc.glsl"
|
||||
|
||||
@@ -1551,12 +1553,15 @@ void main() {
|
||||
frag_color = vec4(albedo, alpha);
|
||||
#else // MODE_UNSHADED
|
||||
frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha);
|
||||
//frag_color = vec4(1.0);
|
||||
#endif // MODE_UNSHADED
|
||||
|
||||
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
|
||||
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
|
||||
|
||||
// On mobile we use a UNORM buffer with 10bpp which results in a range from 0.0 - 1.0 resulting in HDR breaking
|
||||
// We divide by sc_luminance_multiplier to support a range from 0.0 - 2.0 both increasing precision on bright and darker images
|
||||
frag_color.rgb = frag_color.rgb / sc_luminance_multiplier;
|
||||
|
||||
#endif //MODE_MULTIPLE_RENDER_TARGETS
|
||||
|
||||
#endif //MODE_RENDER_DEPTH
|
||||
|
||||
@@ -17,6 +17,8 @@ layout(push_constant, binding = 1, std430) uniform Params {
|
||||
vec4 projections[MAX_VIEWS];
|
||||
vec4 position_multiplier;
|
||||
float time;
|
||||
float luminance_multiplier;
|
||||
float pad[2];
|
||||
}
|
||||
params;
|
||||
|
||||
@@ -55,6 +57,8 @@ layout(push_constant, binding = 1, std430) uniform Params {
|
||||
vec4 projections[MAX_VIEWS];
|
||||
vec4 position_multiplier;
|
||||
float time;
|
||||
float luminance_multiplier;
|
||||
float pad[2];
|
||||
}
|
||||
params;
|
||||
|
||||
@@ -199,17 +203,17 @@ void main() {
|
||||
vec3 inverted_cube_normal = cube_normal;
|
||||
inverted_cube_normal.z *= -1.0;
|
||||
#ifdef USES_HALF_RES_COLOR
|
||||
half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal);
|
||||
half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier;
|
||||
#endif
|
||||
#ifdef USES_QUARTER_RES_COLOR
|
||||
quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal);
|
||||
quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier;
|
||||
#endif
|
||||
#else
|
||||
#ifdef USES_HALF_RES_COLOR
|
||||
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
|
||||
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) * params.luminance_multiplier;
|
||||
#endif
|
||||
#ifdef USES_QUARTER_RES_COLOR
|
||||
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
|
||||
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) * params.luminance_multiplier;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -246,4 +250,7 @@ void main() {
|
||||
if (!AT_CUBEMAP_PASS && !AT_HALF_RES_PASS && !AT_QUARTER_RES_PASS) {
|
||||
frag_color.a = 0.0;
|
||||
}
|
||||
|
||||
// For mobile renderer we're dividing by 2.0 as we're using a UNORM buffer
|
||||
frag_color.rgb = frag_color.rgb / params.luminance_multiplier;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ layout(push_constant, binding = 1, std430) uniform Params {
|
||||
float exposure;
|
||||
float white;
|
||||
float auto_exposure_grey;
|
||||
uint pad2;
|
||||
float luminance_multiplier;
|
||||
|
||||
vec2 pixel_size;
|
||||
bool use_fxaa;
|
||||
@@ -298,15 +298,15 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
|
||||
const float FXAA_SPAN_MAX = 8.0;
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
|
||||
vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
|
||||
vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
|
||||
vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
|
||||
vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
#else
|
||||
vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
|
||||
vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
|
||||
vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
|
||||
vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
|
||||
vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
|
||||
#endif
|
||||
vec3 rgbM = color;
|
||||
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||
@@ -333,11 +333,11 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
|
||||
params.pixel_size;
|
||||
|
||||
#ifdef MULTIVIEW
|
||||
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, vec3(uv_interp + dir * (1.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * (2.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, vec3(uv_interp + dir * -0.5, ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * 0.5, ViewIndex), 0.0).xyz);
|
||||
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, vec3(uv_interp + dir * (1.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * (2.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz) * params.luminance_multiplier;
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, vec3(uv_interp + dir * -0.5, ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * 0.5, ViewIndex), 0.0).xyz) * params.luminance_multiplier;
|
||||
#else
|
||||
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz);
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz + textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz);
|
||||
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz) * params.luminance_multiplier;
|
||||
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz + textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz) * params.luminance_multiplier;
|
||||
#endif
|
||||
|
||||
float lumaB = dot(rgbB, luma);
|
||||
@@ -364,11 +364,11 @@ vec3 screen_space_dither(vec2 frag_coord) {
|
||||
void main() {
|
||||
#ifdef SUBPASS
|
||||
// SUBPASS and MULTIVIEW can be combined but in that case we're already reading from the correct layer
|
||||
vec3 color = subpassLoad(input_color).rgb;
|
||||
vec3 color = subpassLoad(input_color).rgb * params.luminance_multiplier;
|
||||
#elif defined(MULTIVIEW)
|
||||
vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb;
|
||||
vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb * params.luminance_multiplier;
|
||||
#else
|
||||
vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb;
|
||||
vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb * params.luminance_multiplier;
|
||||
#endif
|
||||
|
||||
// Exposure
|
||||
@@ -377,7 +377,7 @@ void main() {
|
||||
|
||||
#ifndef SUBPASS
|
||||
if (params.use_auto_exposure) {
|
||||
exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.auto_exposure_grey);
|
||||
exposure *= 1.0 / (texelFetch(source_auto_exposure, ivec2(0, 0), 0).r * params.luminance_multiplier / params.auto_exposure_grey);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -386,7 +386,7 @@ void main() {
|
||||
// Early Tonemap & SRGB Conversion
|
||||
#ifndef SUBPASS
|
||||
if (params.use_glow && params.glow_mode == GLOW_MODE_MIX) {
|
||||
vec3 glow = gather_glow(source_glow, uv_interp);
|
||||
vec3 glow = gather_glow(source_glow, uv_interp) * params.luminance_multiplier;
|
||||
color.rgb = mix(color.rgb, glow, params.glow_intensity);
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ void main() {
|
||||
// Glow
|
||||
|
||||
if (params.use_glow && params.glow_mode != GLOW_MODE_MIX) {
|
||||
vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity;
|
||||
vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity * params.luminance_multiplier;
|
||||
|
||||
// high dynamic range -> SRGB
|
||||
glow = apply_tonemapping(glow, params.white);
|
||||
|
||||
Reference in New Issue
Block a user