diff options
Diffstat (limited to 'servers/rendering/renderer_rd/shaders')
3 files changed, 34 insertions, 18 deletions
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index edbe1031b7..8cb56fbc83 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -903,6 +903,7 @@ void main() {  	if (scene_data.use_reflection_cubemap) {  		vec3 ref_vec = reflect(-view, normal); +		float horizon = min(1.0 + dot(ref_vec, normal), 1.0);  		ref_vec = scene_data.radiance_inverse_xform * ref_vec;  #ifdef USE_RADIANCE_CUBEMAP_ARRAY @@ -915,7 +916,6 @@ void main() {  		specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;  #endif //USE_RADIANCE_CUBEMAP_ARRAY -		float horizon = min(1.0 + dot(ref_vec, normal), 1.0);  		specular_light *= horizon * horizon;  		specular_light *= scene_data.ambient_light_color_energy.a;  	} diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 518b0a6c7f..c3c4139450 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -868,6 +868,7 @@ void main() {  	if (scene_data.use_reflection_cubemap) {  		vec3 ref_vec = reflect(-view, normal); +		float horizon = min(1.0 + dot(ref_vec, normal), 1.0);  		ref_vec = scene_data.radiance_inverse_xform * ref_vec;  #ifdef USE_RADIANCE_CUBEMAP_ARRAY @@ -880,7 +881,6 @@ void main() {  		specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb;  #endif //USE_RADIANCE_CUBEMAP_ARRAY -		float horizon = min(1.0 + dot(ref_vec, normal), 1.0);  		specular_light *= horizon * horizon;  		specular_light *= scene_data.ambient_light_color_energy.a;  	} diff --git a/servers/rendering/renderer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl index 4411587116..1ce3e04421 100644 --- a/servers/rendering/renderer_rd/shaders/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl @@ -169,16 +169,33 @@ vec3 tonemap_filmic(vec3 color, float white) {  	return color_tonemapped / white_tonemapped;  } +// Adapted from https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl +// (MIT License).  vec3 tonemap_aces(vec3 color, float white) { -	const float exposure_bias = 0.85f; -	const float A = 2.51f * exposure_bias * exposure_bias; -	const float B = 0.03f * exposure_bias; -	const float C = 2.43f * exposure_bias * exposure_bias; -	const float D = 0.59f * exposure_bias; -	const float E = 0.14f; - -	vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E); -	float white_tonemapped = (white * (A * white + B)) / (white * (C * white + D) + E); +	const float exposure_bias = 1.8f; +	const float A = 0.0245786f; +	const float B = 0.000090537f; +	const float C = 0.983729f; +	const float D = 0.432951f; +	const float E = 0.238081f; + +	// Exposure bias baked into transform to save shader instructions. Equivalent to `color *= exposure_bias` +	const mat3 rgb_to_rrt = mat3( +			vec3(0.59719f * exposure_bias, 0.35458f * exposure_bias, 0.04823f * exposure_bias), +			vec3(0.07600f * exposure_bias, 0.90834f * exposure_bias, 0.01566f * exposure_bias), +			vec3(0.02840f * exposure_bias, 0.13383f * exposure_bias, 0.83777f * exposure_bias)); + +	const mat3 odt_to_rgb = mat3( +			vec3(1.60475f, -0.53108f, -0.07367f), +			vec3(-0.10208f, 1.10813f, -0.00605f), +			vec3(-0.00327f, -0.07276f, 1.07602f)); + +	color *= rgb_to_rrt; +	vec3 color_tonemapped = (color * (color + A) - B) / (color * (C * color + D) + E); +	color_tonemapped *= odt_to_rgb; + +	white *= exposure_bias; +	float white_tonemapped = (white * (white + A) - B) / (white * (C * white + D) + E);  	return color_tonemapped / white_tonemapped;  } @@ -200,15 +217,16 @@ vec3 linear_to_srgb(vec3 color) {  #define TONEMAPPER_ACES 3  vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color - +	// Ensure color values passed to tonemappers are positive. +	// They can be negative in the case of negative lights, which leads to undesired behavior.  	if (params.tonemapper == TONEMAPPER_LINEAR) {  		return color;  	} else if (params.tonemapper == TONEMAPPER_REINHARD) { -		return tonemap_reinhard(color, white); +		return tonemap_reinhard(max(vec3(0.0f), color), white);  	} else if (params.tonemapper == TONEMAPPER_FILMIC) { -		return tonemap_filmic(color, white); +		return tonemap_filmic(max(vec3(0.0f), color), white);  	} else { // TONEMAPPER_ACES -		return tonemap_aces(color, white); +		return tonemap_aces(max(vec3(0.0f), color), white);  	}  } @@ -401,9 +419,7 @@ void main() {  		color += screen_space_dither(gl_FragCoord.xy);  	} -	// Ensure color values passed to tonemappers are positive. -	// They can be negative in the case of negative lights, which leads to undesired behavior. -	color = apply_tonemapping(max(vec3(0.0), color), params.white); +	color = apply_tonemapping(color, params.white);  	color = linear_to_srgb(color); // regular linear -> SRGB conversion  |