Browse Source

Add fixed fog to the sky in the Compatibility renderer

And apply luminance multiplier after fog in RD renderer
clayjohn 1 year ago
parent
commit
578049b7b9

+ 10 - 2
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -777,7 +777,6 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
 	ERR_FAIL_COND(p_env.is_null());
 	ERR_FAIL_COND(p_env.is_null());
 
 
 	Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));
 	Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));
-	ERR_FAIL_NULL(sky);
 
 
 	GLES3::SkyMaterialData *material_data = nullptr;
 	GLES3::SkyMaterialData *material_data = nullptr;
 	RID sky_material;
 	RID sky_material;
@@ -851,6 +850,15 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
 	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::SKY_ENERGY_MULTIPLIER, p_sky_energy_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
 	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::SKY_ENERGY_MULTIPLIER, p_sky_energy_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
 	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
 	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
 
 
+	Color fog_color = environment_get_fog_light_color(p_env).srgb_to_linear() * environment_get_fog_light_energy(p_env);
+	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_ENABLED, environment_get_fog_enabled(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_AERIAL_PERSPECTIVE, environment_get_fog_aerial_perspective(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_LIGHT_COLOR, fog_color, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_SUN_SCATTER, environment_get_fog_sun_scatter(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_DENSITY, environment_get_fog_density(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_SKY_AFFECT, environment_get_fog_sky_affect(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+	material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::DIRECTIONAL_LIGHT_COUNT, sky_globals.directional_light_count, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
+
 	if (p_use_multiview) {
 	if (p_use_multiview) {
 		glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
 		glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
 		glBindBuffer(GL_UNIFORM_BUFFER, 0);
 		glBindBuffer(GL_UNIFORM_BUFFER, 0);
@@ -2587,7 +2595,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
 
 
 	scene_state.enable_gl_depth_draw(false);
 	scene_state.enable_gl_depth_draw(false);
 
 
-	if (draw_sky) {
+	if (draw_sky || draw_sky_fog_only) {
 		RENDER_TIMESTAMP("Render Sky");
 		RENDER_TIMESTAMP("Render Sky");
 
 
 		scene_state.enable_gl_depth_test(true);
 		scene_state.enable_gl_depth_test(true);

+ 35 - 2
drivers/gles3/shaders/sky.glsl

@@ -108,11 +108,11 @@ uniform float sky_energy_multiplier;
 uniform float luminance_multiplier;
 uniform float luminance_multiplier;
 
 
 uniform float fog_aerial_perspective;
 uniform float fog_aerial_perspective;
-uniform vec3 fog_light_color;
+uniform vec4 fog_light_color;
 uniform float fog_sun_scatter;
 uniform float fog_sun_scatter;
 uniform bool fog_enabled;
 uniform bool fog_enabled;
 uniform float fog_density;
 uniform float fog_density;
-uniform float z_far;
+uniform float fog_sky_affect;
 uniform uint directional_light_count;
 uniform uint directional_light_count;
 
 
 #ifdef USE_MULTIVIEW
 #ifdef USE_MULTIVIEW
@@ -135,6 +135,24 @@ vec3 interleaved_gradient_noise(vec2 pos) {
 }
 }
 #endif
 #endif
 
 
+#if !defined(DISABLE_FOG)
+vec4 fog_process(vec3 view, vec3 sky_color) {
+	vec3 fog_color = mix(fog_light_color.rgb, sky_color, fog_aerial_perspective);
+
+	if (fog_sun_scatter > 0.001) {
+		vec4 sun_scatter = vec4(0.0);
+		float sun_total = 0.0;
+		for (uint i = 0u; i < directional_light_count; i++) {
+			vec3 light_color = directional_lights.data[i].color_size.xyz * directional_lights.data[i].direction_energy.w;
+			float light_amount = pow(max(dot(view, directional_lights.data[i].direction_energy.xyz), 0.0), 8.0);
+			fog_color += light_color * light_amount * fog_sun_scatter;
+		}
+	}
+
+	return vec4(fog_color, 1.0);
+}
+#endif // !DISABLE_FOG
+
 void main() {
 void main() {
 	vec3 cube_normal;
 	vec3 cube_normal;
 #ifdef USE_MULTIVIEW
 #ifdef USE_MULTIVIEW
@@ -203,6 +221,21 @@ void main() {
 
 
 	// Convert to Linear for tonemapping so color matches scene shader better
 	// Convert to Linear for tonemapping so color matches scene shader better
 	color = srgb_to_linear(color);
 	color = srgb_to_linear(color);
+
+#if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)
+
+	// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
+	if (fog_enabled) {
+		vec4 fog = fog_process(cube_normal, color.rgb);
+		color.rgb = mix(color.rgb, fog.rgb, fog.a * fog_sky_affect);
+	}
+
+	if (custom_fog.a > 0.0) {
+		color.rgb = mix(color.rgb, custom_fog.rgb, custom_fog.a);
+	}
+
+#endif // DISABLE_FOG
+
 	color *= exposure;
 	color *= exposure;
 #ifdef APPLY_TONEMAPPING
 #ifdef APPLY_TONEMAPPING
 	color = apply_tonemapping(color, white);
 	color = apply_tonemapping(color, white);

+ 4 - 4
servers/rendering/renderer_rd/shaders/environment/sky.glsl

@@ -255,10 +255,6 @@ void main() {
 	frag_color.rgb = color;
 	frag_color.rgb = color;
 	frag_color.a = alpha;
 	frag_color.a = alpha;
 
 
-	// For mobile renderer we're multiplying by 0.5 as we're using a UNORM buffer.
-	// For both mobile and clustered, we also bake in the exposure value for the environment and camera.
-	frag_color.rgb = frag_color.rgb * params.luminance_multiplier;
-
 #if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)
 #if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)
 
 
 	// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
 	// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
@@ -278,6 +274,10 @@ void main() {
 
 
 #endif // DISABLE_FOG
 #endif // DISABLE_FOG
 
 
+	// For mobile renderer we're multiplying by 0.5 as we're using a UNORM buffer.
+	// For both mobile and clustered, we also bake in the exposure value for the environment and camera.
+	frag_color.rgb = frag_color.rgb * params.luminance_multiplier;
+
 	// Blending is disabled for Sky, so alpha doesn't blend.
 	// Blending is disabled for Sky, so alpha doesn't blend.
 	// Alpha is used for subsurface scattering so make sure it doesn't get applied to Sky.
 	// Alpha is used for subsurface scattering so make sure it doesn't get applied to Sky.
 	if (!AT_CUBEMAP_PASS && !AT_HALF_RES_PASS && !AT_QUARTER_RES_PASS) {
 	if (!AT_CUBEMAP_PASS && !AT_HALF_RES_PASS && !AT_QUARTER_RES_PASS) {