소스 검색

Merge pull request #45731 from reduz/reprojected-volumetric-fog

Added temporal reprojection to Volumetric Fog
Juan Linietsky 4 년 전
부모
커밋
b7e1014119

+ 24 - 1
scene/resources/environment.cpp

@@ -797,7 +797,7 @@ void Environment::_update_fog() {
 // Volumetric Fog
 
 void Environment::_update_volumetric_fog() {
-	RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, RS::EnvVolumetricFogShadowFilter(volumetric_fog_shadow_filter));
+	RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, RS::EnvVolumetricFogShadowFilter(volumetric_fog_shadow_filter), volumetric_fog_temporal_reproject, volumetric_fog_temporal_reproject_amount);
 }
 
 void Environment::set_volumetric_fog_enabled(bool p_enable) {
@@ -854,6 +854,22 @@ float Environment::get_volumetric_fog_gi_inject() const {
 	return volumetric_fog_gi_inject;
 }
 
+void Environment::set_volumetric_fog_temporal_reprojection_enabled(bool p_enable) {
+	volumetric_fog_temporal_reproject = p_enable;
+	_update_volumetric_fog();
+}
+bool Environment::is_volumetric_fog_temporal_reprojection_enabled() const {
+	return volumetric_fog_temporal_reproject;
+}
+void Environment::set_volumetric_fog_temporal_reprojection_amount(float p_amount) {
+	volumetric_fog_temporal_reproject_amount = p_amount;
+	_update_volumetric_fog();
+}
+
+float Environment::get_volumetric_fog_temporal_reprojection_amount() const {
+	return volumetric_fog_temporal_reproject_amount;
+}
+
 void Environment::set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter) {
 	volumetric_fog_shadow_filter = p_filter;
 	_update_volumetric_fog();
@@ -1319,6 +1335,10 @@ void Environment::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject);
 	ClassDB::bind_method(D_METHOD("set_volumetric_fog_shadow_filter", "shadow_filter"), &Environment::set_volumetric_fog_shadow_filter);
 	ClassDB::bind_method(D_METHOD("get_volumetric_fog_shadow_filter"), &Environment::get_volumetric_fog_shadow_filter);
+	ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_enabled", "enabled"), &Environment::set_volumetric_fog_temporal_reprojection_enabled);
+	ClassDB::bind_method(D_METHOD("is_volumetric_fog_temporal_reprojection_enabled"), &Environment::is_volumetric_fog_temporal_reprojection_enabled);
+	ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_amount", "temporal_reprojection_amount"), &Environment::set_volumetric_fog_temporal_reprojection_amount);
+	ClassDB::bind_method(D_METHOD("get_volumetric_fog_temporal_reprojection_amount"), &Environment::get_volumetric_fog_temporal_reprojection_amount);
 
 	ADD_GROUP("Volumetric Fog", "volumetric_fog_");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_enabled"), "set_volumetric_fog_enabled", "is_volumetric_fog_enabled");
@@ -1329,6 +1349,9 @@ void Environment::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "volumetric_fog_shadow_filter", PROPERTY_HINT_ENUM, "Disabled,Low,Medium,High"), "set_volumetric_fog_shadow_filter", "get_volumetric_fog_shadow_filter");
+	ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled");
+	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_temporal_reprojection_amount", PROPERTY_HINT_RANGE, "0.0,0.999,0.001"), "set_volumetric_fog_temporal_reprojection_amount", "get_volumetric_fog_temporal_reprojection_amount");
 
 	// Adjustment
 

+ 6 - 0
scene/resources/environment.h

@@ -198,6 +198,8 @@ private:
 	float volumetric_fog_detail_spread = 2.0;
 	VolumetricFogShadowFilter volumetric_fog_shadow_filter = VOLUMETRIC_FOG_SHADOW_FILTER_LOW;
 	float volumetric_fog_gi_inject = 0.0;
+	bool volumetric_fog_temporal_reproject = false;
+	float volumetric_fog_temporal_reproject_amount = 0.95;
 	void _update_volumetric_fog();
 
 	// Adjustment
@@ -389,6 +391,10 @@ public:
 	VolumetricFogShadowFilter get_volumetric_fog_shadow_filter() const;
 	void set_volumetric_fog_gi_inject(float p_gi_inject);
 	float get_volumetric_fog_gi_inject() const;
+	void set_volumetric_fog_temporal_reprojection_enabled(bool p_enable);
+	bool is_volumetric_fog_temporal_reprojection_enabled() const;
+	void set_volumetric_fog_temporal_reprojection_amount(float p_amount);
+	float get_volumetric_fog_temporal_reprojection_amount() const;
 
 	// Adjustment
 	void set_adjustment_enabled(bool p_enabled);

+ 33 - 4
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -3151,7 +3151,7 @@ float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) c
 	return env->fog_aerial_perspective;
 }
 
-void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter) {
+void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) {
 	Environment *env = environment_owner.getornull(p_env);
 	ERR_FAIL_COND(!env);
 
@@ -3167,6 +3167,8 @@ void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_ena
 	env->volumetric_fog_detail_spread = p_detail_spread;
 	env->volumetric_fog_shadow_filter = p_shadow_filter;
 	env->volumetric_fog_gi_inject = p_gi_inject;
+	env->volumetric_fog_temporal_reprojection = p_temporal_reprojection;
+	env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount;
 }
 
 void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_size, int p_depth) {
@@ -6796,6 +6798,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
 void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
 	ERR_FAIL_COND(!rb->volumetric_fog);
 
+	RD::get_singleton()->free(rb->volumetric_fog->prev_light_density_map);
 	RD::get_singleton()->free(rb->volumetric_fog->light_density_map);
 	RD::get_singleton()->free(rb->volumetric_fog->fog_map);
 
@@ -6897,11 +6900,16 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 		tf.height = target_height;
 		tf.depth = volumetric_fog_depth;
 		tf.texture_type = RD::TEXTURE_TYPE_3D;
-		tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
+		tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
 
 		rb->volumetric_fog->light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
 
-		tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT;
+		tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+
+		rb->volumetric_fog->prev_light_density_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
+		RD::get_singleton()->texture_clear(rb->volumetric_fog->prev_light_density_map, Color(0, 0, 0, 0), 0, 1, 0, 1);
+
+		tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
 
 		rb->volumetric_fog->fog_map = RD::get_singleton()->texture_create(tf, RD::TextureView());
 		_render_buffers_uniform_set_changed(p_render_buffers);
@@ -7211,6 +7219,13 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 			u.ids.push_back(volumetric_fog.params_ubo);
 			uniforms.push_back(u);
 		}
+		{
+			RD::Uniform u;
+			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+			u.binding = 15;
+			u.ids.push_back(rb->volumetric_fog->prev_light_density_map);
+			uniforms.push_back(u);
+		}
 
 		rb->volumetric_fog->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.shader.version_get_shader(volumetric_fog.shader_version, 0), 0);
 
@@ -7312,6 +7327,13 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 	params.cam_rotation[11] = 0;
 	params.filter_axis = 0;
 	params.max_gi_probes = env->volumetric_fog_gi_inject > 0.001 ? p_gi_probe_count : 0;
+	params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;
+
+	Transform to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform;
+	storage->store_transform(to_prev_cam_view, params.to_prev_view);
+
+	params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection;
+	params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount;
 
 	{
 		uint32_t cluster_size = rb->cluster_builder->get_cluster_size();
@@ -7351,7 +7373,12 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 	RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth);
 
 	RD::get_singleton()->draw_command_end_label();
-	RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+	RD::get_singleton()->compute_list_end();
+
+	RD::get_singleton()->texture_copy(rb->volumetric_fog->light_density_map, rb->volumetric_fog->prev_light_density_map, Vector3(0, 0, 0), Vector3(0, 0, 0), Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), 0, 0, 0, 0);
+
+	compute_list = RD::get_singleton()->compute_list_begin();
 
 	if (use_filter) {
 		RD::get_singleton()->draw_command_begin_label("Filter Fog");
@@ -7392,6 +7419,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
 
 	RENDER_TIMESTAMP("<Volumetric Fog");
 	RD::get_singleton()->draw_command_end_label();
+
+	rb->volumetric_fog->prev_cam_transform = p_cam_transform;
 }
 
 uint32_t RendererSceneRenderRD::_get_render_state_directional_light_count() const {

+ 15 - 2
servers/rendering/renderer_rd/renderer_scene_render_rd.h

@@ -745,6 +745,8 @@ private:
 		float volumetric_fog_detail_spread = 2.0;
 		RS::EnvVolumetricFogShadowFilter volumetric_fog_shadow_filter = RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW;
 		float volumetric_fog_gi_inject = 0.0;
+		bool volumetric_fog_temporal_reprojection = false;
+		float volumetric_fog_temporal_reprojection_amount = 0.95;
 
 		/// Glow
 
@@ -1515,6 +1517,10 @@ private:
 	} render_state;
 
 	struct VolumetricFog {
+		enum {
+			MAX_TEMPORAL_FRAMES = 16
+		};
+
 		uint32_t width = 0;
 		uint32_t height = 0;
 		uint32_t depth = 0;
@@ -1523,6 +1529,8 @@ private:
 		float spread;
 
 		RID light_density_map;
+		RID prev_light_density_map;
+
 		RID fog_map;
 		RID uniform_set;
 		RID uniform_set2;
@@ -1530,6 +1538,8 @@ private:
 		RID sky_uniform_set;
 
 		int last_shadow_filter = -1;
+
+		Transform prev_cam_transform;
 	};
 
 	enum {
@@ -1565,10 +1575,13 @@ private:
 			uint32_t cluster_shift;
 			uint32_t cluster_width;
 
-			uint32_t cluster_pad[3];
 			uint32_t max_cluster_element_count_div_32;
+			uint32_t use_temporal_reprojection;
+			uint32_t temporal_frame;
+			float temporal_blend;
 
 			float cam_rotation[12];
+			float to_prev_view[16];
 		};
 
 		VolumetricFogShaderRD shader;
@@ -1708,7 +1721,7 @@ public:
 	float environment_get_fog_height_density(RID p_env) const;
 	float environment_get_fog_aerial_perspective(RID p_env) const;
 
-	void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter);
+	void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount);
 
 	virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth);
 	virtual void environment_set_volumetric_fog_filter_active(bool p_enable);

+ 70 - 2
servers/rendering/renderer_rd/shaders/volumetric_fog.glsl

@@ -168,13 +168,18 @@ layout(set = 0, binding = 14, std140) uniform Params {
 	uint cluster_shift;
 	uint cluster_width;
 
-	uvec3 cluster_pad;
 	uint max_cluster_element_count_div_32;
+	bool use_temporal_reprojection;
+	uint temporal_frame;
+	float temporal_blend;
 
 	mat3x4 cam_rotation;
+	mat4 to_prev_view;
 }
 params;
 
+layout(set = 0, binding = 15) uniform texture3D prev_density_texture;
+
 float get_depth_at_pos(float cell_depth_size, int z) {
 	float d = float(z) * cell_depth_size + cell_depth_size * 0.5; //center of voxels
 	d = pow(d, params.detail_spread);
@@ -213,6 +218,26 @@ uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) {
 	return bitfieldInsert(uint(0), uint(0xFFFFFFFF), local_min, mask_width);
 }
 
+#define TEMPORAL_FRAMES 16
+
+const vec3 halton_map[TEMPORAL_FRAMES] = vec3[](
+		vec3(0.5, 0.33333333, 0.2),
+		vec3(0.25, 0.66666667, 0.4),
+		vec3(0.75, 0.11111111, 0.6),
+		vec3(0.125, 0.44444444, 0.8),
+		vec3(0.625, 0.77777778, 0.04),
+		vec3(0.375, 0.22222222, 0.24),
+		vec3(0.875, 0.55555556, 0.44),
+		vec3(0.0625, 0.88888889, 0.64),
+		vec3(0.5625, 0.03703704, 0.84),
+		vec3(0.3125, 0.37037037, 0.08),
+		vec3(0.8125, 0.7037037, 0.28),
+		vec3(0.1875, 0.14814815, 0.48),
+		vec3(0.6875, 0.48148148, 0.68),
+		vec3(0.4375, 0.81481481, 0.88),
+		vec3(0.9375, 0.25925926, 0.12),
+		vec3(0.03125, 0.59259259, 0.32));
+
 void main() {
 	vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size);
 
@@ -241,6 +266,45 @@ void main() {
 	view_pos.z = -params.fog_frustum_end * fog_unit_pos.z;
 	view_pos.y = -view_pos.y;
 
+	vec4 reprojected_density = vec4(0.0);
+	float reproject_amount = 0.0;
+
+	if (params.use_temporal_reprojection) {
+		vec3 prev_view = (params.to_prev_view * vec4(view_pos, 1.0)).xyz;
+		//undo transform into prev view
+		prev_view.y = -prev_view.y;
+		//z back to unit size
+		prev_view.z /= -params.fog_frustum_end;
+		//xy back to unit size
+		prev_view.xy /= mix(params.fog_frustum_size_begin, params.fog_frustum_size_end, vec2(prev_view.z));
+		prev_view.xy = prev_view.xy * 0.5 + 0.5;
+		//z back to unspread value
+		prev_view.z = pow(prev_view.z, 1.0 / params.detail_spread);
+
+		if (all(greaterThan(prev_view, vec3(0.0))) && all(lessThan(prev_view, vec3(1.0)))) {
+			//reprojectinon fits
+
+			reprojected_density = textureLod(sampler3D(prev_density_texture, linear_sampler), prev_view, 0.0);
+			reproject_amount = params.temporal_blend;
+
+			// Since we can reproject, now we must jitter the current view pos.
+			// This is done here because cells that can't reproject should not jitter.
+
+			fog_unit_pos = posf * fog_cell_size + fog_cell_size * halton_map[params.temporal_frame]; //center of voxels, offset by halton table
+
+			screen_pos = uvec2(fog_unit_pos.xy * params.screen_size);
+			cluster_pos = screen_pos >> params.cluster_shift;
+			cluster_offset = (params.cluster_width * cluster_pos.y + cluster_pos.x) * (params.max_cluster_element_count_div_32 + 32);
+			//positions in screen are too spread apart, no hopes for optimizing with subgroups
+
+			fog_unit_pos.z = pow(fog_unit_pos.z, params.detail_spread);
+
+			view_pos.xy = (fog_unit_pos.xy * 2.0 - 1.0) * mix(params.fog_frustum_size_begin, params.fog_frustum_size_end, vec2(fog_unit_pos.z));
+			view_pos.z = -params.fog_frustum_end * fog_unit_pos.z;
+			view_pos.y = -view_pos.y;
+		}
+	}
+
 	uint cluster_z = uint(clamp((abs(view_pos.z) / params.z_far) * 32.0, 0.0, 31.0));
 
 	vec3 total_light = params.light_color;
@@ -565,7 +629,11 @@ void main() {
 
 #endif
 
-	imageStore(density_map, pos, vec4(total_light, total_density));
+	vec4 final_density = vec4(total_light, total_density);
+
+	final_density = mix(final_density, reprojected_density, reproject_amount);
+
+	imageStore(density_map, pos, final_density);
 #endif
 
 #ifdef MODE_FOG

+ 1 - 1
servers/rendering/renderer_scene.h

@@ -122,7 +122,7 @@ public:
 	virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
 	virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
 
-	virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+	virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
 
 	virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
 	virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;

+ 1 - 1
servers/rendering/renderer_scene_cull.h

@@ -991,7 +991,7 @@ public:
 	PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
 
 	PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
-	PASS9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter)
+	PASS11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter, bool, float)
 
 	PASS2(environment_set_volumetric_fog_volume_size, int, int)
 	PASS1(environment_set_volumetric_fog_filter_active, bool)

+ 1 - 1
servers/rendering/renderer_scene_render.h

@@ -117,7 +117,7 @@ public:
 	virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
 	virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
 
-	virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+	virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
 
 	virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
 	virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;

+ 1 - 1
servers/rendering/rendering_server_default.h

@@ -615,7 +615,7 @@ public:
 	BIND7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
 
 	BIND9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
-	BIND9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter)
+	BIND11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter, bool, float)
 
 	BIND2(environment_set_volumetric_fog_volume_size, int, int)
 	BIND1(environment_set_volumetric_fog_filter_active, bool)

+ 1 - 1
servers/rendering/rendering_server_wrap_mt.h

@@ -520,7 +520,7 @@ public:
 
 	FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
 
-	FUNC9(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter)
+	FUNC11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter, bool, float)
 
 	FUNC2(environment_set_volumetric_fog_volume_size, int, int)
 	FUNC1(environment_set_volumetric_fog_filter_active, bool)

+ 1 - 1
servers/rendering_server.h

@@ -1032,7 +1032,7 @@ public:
 		ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH,
 	};
 
-	virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter) = 0;
+	virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
 	virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
 	virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
 	virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;