2
0
Эх сурвалжийг харах

Add parameter for fog max depth and use alpha as density.

Dominique LaSalle 7 жил өмнө
parent
commit
6eae6247e4

+ 1 - 1
drivers/dummy/rasterizer_dummy.h

@@ -74,7 +74,7 @@ public:
 	void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {}
 
 	void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {}
-	void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {}
+	void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {}
 	void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {}
 
 	bool is_environment(RID p_env) { return false; }

+ 7 - 2
drivers/gles2/rasterizer_scene_gles2.cpp

@@ -752,13 +752,14 @@ void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, const C
 	env->fog_sun_amount = p_sun_amount;
 }
 
-void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
+void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
 
 	Environment *env = environment_owner.getornull(p_env);
 	ERR_FAIL_COND(!env);
 
 	env->fog_depth_enabled = p_enable;
 	env->fog_depth_begin = p_depth_begin;
+	env->fog_depth_end = p_depth_end;
 	env->fog_depth_curve = p_depth_curve;
 	env->fog_transmit_enabled = p_transmit;
 	env->fog_transmit_curve = p_transmit_curve;
@@ -2054,7 +2055,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
 	if (p_env && !p_shadow && p_env->fog_enabled && (p_env->fog_depth_enabled || p_env->fog_height_enabled)) {
 		state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, p_env->fog_depth_enabled);
 		state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, p_env->fog_height_enabled);
-		fog_max_distance = p_projection.get_z_far();
+		if (p_env->fog_depth_end > 0) {
+			fog_max_distance = p_env->fog_depth_end;
+		} else {
+			fog_max_distance = p_projection.get_z_far();
+		}
 		using_fog = true;
 	}
 

+ 3 - 1
drivers/gles2/rasterizer_scene_gles2.h

@@ -360,6 +360,7 @@ public:
 
 		bool fog_depth_enabled;
 		float fog_depth_begin;
+		float fog_depth_end;
 		float fog_depth_curve;
 		bool fog_transmit_enabled;
 		float fog_transmit_curve;
@@ -385,6 +386,7 @@ public:
 			fog_depth_enabled = true;
 
 			fog_depth_begin = 10;
+			fog_depth_end = 0;
 			fog_depth_curve = 1;
 
 			fog_transmit_enabled = true;
@@ -422,7 +424,7 @@ public:
 	virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp);
 
 	virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount);
-	virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve);
+	virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve);
 	virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve);
 
 	virtual bool is_environment(RID p_env);

+ 2 - 2
drivers/gles2/shaders/scene.glsl

@@ -626,7 +626,7 @@ VERTEX_SHADER_CODE
 
 		float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
 
-		fog_amount = pow(fog_z, fog_depth_curve);
+		fog_amount = pow(fog_z, fog_depth_curve) * fog_color_base.a;
 	}
 #endif
 
@@ -2037,7 +2037,7 @@ FRAGMENT_SHADER_CODE
 
 		float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
 
-		fog_amount = pow(fog_z, fog_depth_curve);
+		fog_amount = pow(fog_z, fog_depth_curve) * fog_color_base.a;
 
 		if (fog_transmit_enabled) {
 			vec3 total_light = gl_FragColor.rgb;

+ 4 - 1
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -934,13 +934,14 @@ void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, const C
 	env->fog_sun_amount = p_sun_amount;
 }
 
-void RasterizerSceneGLES3::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
+void RasterizerSceneGLES3::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
 
 	Environment *env = environment_owner.getornull(p_env);
 	ERR_FAIL_COND(!env);
 
 	env->fog_depth_enabled = p_enable;
 	env->fog_depth_begin = p_depth_begin;
+	env->fog_depth_end = p_depth_end;
 	env->fog_depth_curve = p_depth_curve;
 	env->fog_transmit_enabled = p_transmit;
 	env->fog_transmit_curve = p_transmit_curve;
@@ -2568,6 +2569,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
 		state.ubo_data.fog_color_enabled[1] = linear_fog.g;
 		state.ubo_data.fog_color_enabled[2] = linear_fog.b;
 		state.ubo_data.fog_color_enabled[3] = (!p_no_fog && env->fog_enabled) ? 1.0 : 0.0;
+		state.ubo_data.fog_density = linear_fog.a;
 
 		Color linear_sun = env->fog_sun_color.to_linear();
 		state.ubo_data.fog_sun_color_amount[0] = linear_sun.r;
@@ -2576,6 +2578,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
 		state.ubo_data.fog_sun_color_amount[3] = env->fog_sun_amount;
 		state.ubo_data.fog_depth_enabled = env->fog_depth_enabled;
 		state.ubo_data.fog_depth_begin = env->fog_depth_begin;
+		state.ubo_data.fog_depth_end = env->fog_depth_end;
 		state.ubo_data.fog_depth_curve = env->fog_depth_curve;
 		state.ubo_data.fog_transmit_enabled = env->fog_transmit_enabled;
 		state.ubo_data.fog_transmit_curve = env->fog_transmit_curve;

+ 5 - 1
drivers/gles3/rasterizer_scene_gles3.h

@@ -145,6 +145,8 @@ public:
 
 			uint32_t fog_depth_enabled;
 			float fog_depth_begin;
+			float fog_depth_end;
+			float fog_density;
 			float fog_depth_curve;
 			uint32_t fog_transmit_enabled;
 			float fog_transmit_curve;
@@ -438,6 +440,7 @@ public:
 
 		bool fog_depth_enabled;
 		float fog_depth_begin;
+		float fog_depth_end;
 		float fog_depth_curve;
 		bool fog_transmit_enabled;
 		float fog_transmit_curve;
@@ -518,6 +521,7 @@ public:
 			fog_depth_enabled = true;
 
 			fog_depth_begin = 10;
+			fog_depth_end = 0;
 			fog_depth_curve = 1;
 
 			fog_transmit_enabled = true;
@@ -555,7 +559,7 @@ public:
 	virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp);
 
 	virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount);
-	virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve);
+	virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve);
 	virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve);
 
 	virtual bool is_environment(RID p_env);

+ 7 - 2
drivers/gles3/shaders/scene.glsl

@@ -98,6 +98,8 @@ layout(std140) uniform SceneData { // ubo:0
 
 	bool fog_depth_enabled;
 	highp float fog_depth_begin;
+	highp float fog_depth_end;
+	mediump float fog_density;
 	highp float fog_depth_curve;
 	bool fog_transmit_enabled;
 	highp float fog_transmit_curve;
@@ -675,6 +677,8 @@ layout(std140) uniform SceneData {
 
 	bool fog_depth_enabled;
 	highp float fog_depth_begin;
+	highp float fog_depth_end;
+	mediump float fog_density;
 	highp float fog_depth_curve;
 	bool fog_transmit_enabled;
 	highp float fog_transmit_curve;
@@ -2033,10 +2037,11 @@ FRAGMENT_SHADER_CODE
 		//apply fog
 
 		if (fog_depth_enabled) {
+			float fog_far = fog_depth_end > 0 ? fog_depth_end : z_far;
 
-			float fog_z = smoothstep(fog_depth_begin, z_far, length(vertex));
+			float fog_z = smoothstep(fog_depth_begin, fog_far, length(vertex));
 
-			fog_amount = pow(fog_z, fog_depth_curve);
+			fog_amount = pow(fog_z, fog_depth_curve) * fog_density;
 			if (fog_transmit_enabled) {
 				vec3 total_light = emission + ambient_light + specular_light + diffuse_light;
 				float transmit = pow(fog_z, fog_transmit_curve);

+ 21 - 5
scene/resources/environment.cpp

@@ -761,7 +761,7 @@ float Environment::get_fog_sun_amount() const {
 void Environment::set_fog_depth_enabled(bool p_enabled) {
 
 	fog_depth_enabled = p_enabled;
-	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
 }
 bool Environment::is_fog_depth_enabled() const {
 
@@ -771,17 +771,28 @@ bool Environment::is_fog_depth_enabled() const {
 void Environment::set_fog_depth_begin(float p_distance) {
 
 	fog_depth_begin = p_distance;
-	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
 }
 float Environment::get_fog_depth_begin() const {
 
 	return fog_depth_begin;
 }
 
+void Environment::set_fog_depth_end(float p_distance) {
+
+	fog_depth_end = p_distance;
+	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+}
+
+float Environment::get_fog_depth_end() const {
+
+	return fog_depth_end;
+}
+
 void Environment::set_fog_depth_curve(float p_curve) {
 
 	fog_depth_curve = p_curve;
-	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
 }
 float Environment::get_fog_depth_curve() const {
 
@@ -791,7 +802,7 @@ float Environment::get_fog_depth_curve() const {
 void Environment::set_fog_transmit_enabled(bool p_enabled) {
 
 	fog_transmit_enabled = p_enabled;
-	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
 }
 bool Environment::is_fog_transmit_enabled() const {
 
@@ -801,7 +812,7 @@ bool Environment::is_fog_transmit_enabled() const {
 void Environment::set_fog_transmit_curve(float p_curve) {
 
 	fog_transmit_curve = p_curve;
-	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+	VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
 }
 float Environment::get_fog_transmit_curve() const {
 
@@ -900,6 +911,9 @@ void Environment::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin);
 	ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin);
 
+	ClassDB::bind_method(D_METHOD("set_fog_depth_end", "distance"), &Environment::set_fog_depth_end);
+	ClassDB::bind_method(D_METHOD("get_fog_depth_end"), &Environment::get_fog_depth_end);
+
 	ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve);
 	ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve);
 
@@ -928,6 +942,7 @@ void Environment::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin");
+	ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve");
@@ -1269,6 +1284,7 @@ Environment::Environment() {
 	fog_depth_enabled = true;
 
 	fog_depth_begin = 10;
+	fog_depth_end = 0;
 	fog_depth_curve = 1;
 
 	fog_transmit_enabled = false;

+ 4 - 0
scene/resources/environment.h

@@ -162,6 +162,7 @@ private:
 
 	bool fog_depth_enabled;
 	float fog_depth_begin;
+	float fog_depth_end;
 	float fog_depth_curve;
 
 	bool fog_transmit_enabled;
@@ -365,6 +366,9 @@ public:
 	void set_fog_depth_begin(float p_distance);
 	float get_fog_depth_begin() const;
 
+	void set_fog_depth_end(float p_distance);
+	float get_fog_depth_end() const;
+
 	void set_fog_depth_curve(float p_curve);
 	float get_fog_depth_curve() const;
 

+ 1 - 1
servers/visual/rasterizer.h

@@ -73,7 +73,7 @@ public:
 	virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0;
 
 	virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
-	virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+	virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
 	virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
 
 	virtual bool is_environment(RID p_env) = 0;

+ 1 - 1
servers/visual/visual_server_raster.h

@@ -511,7 +511,7 @@ public:
 	BIND6(environment_set_adjustment, RID, bool, float, float, float, RID)
 
 	BIND5(environment_set_fog, RID, bool, const Color &, const Color &, float)
-	BIND6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+	BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float)
 	BIND5(environment_set_fog_height, RID, bool, float, float, float)
 
 	/* SCENARIO API */

+ 1 - 1
servers/visual/visual_server_wrap_mt.h

@@ -437,7 +437,7 @@ public:
 	FUNC6(environment_set_adjustment, RID, bool, float, float, float, RID)
 
 	FUNC5(environment_set_fog, RID, bool, const Color &, const Color &, float)
-	FUNC6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+	FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float)
 	FUNC5(environment_set_fog_height, RID, bool, float, float, float)
 
 	FUNCRID(scenario)

+ 3 - 1
servers/visual_server.cpp

@@ -1915,7 +1915,9 @@ void VisualServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance", "roughness"), &VisualServer::environment_set_ssr);
 	ClassDB::bind_method(D_METHOD("environment_set_ssao", "env", "enable", "radius", "intensity", "radius2", "intensity2", "bias", "light_affect", "ao_channel_affect", "color", "quality", "blur", "bilateral_sharpness"), &VisualServer::environment_set_ssao);
 	ClassDB::bind_method(D_METHOD("environment_set_fog", "env", "enable", "color", "sun_color", "sun_amount"), &VisualServer::environment_set_fog);
-	ClassDB::bind_method(D_METHOD("environment_set_fog_depth", "env", "enable", "depth_begin", "depth_curve", "transmit", "transmit_curve"), &VisualServer::environment_set_fog_depth);
+
+	ClassDB::bind_method(D_METHOD("environment_set_fog_depth", "env", "enable", "depth_begin", "depth_end", "depth_curve", "transmit", "transmit_curve"), &VisualServer::environment_set_fog_depth);
+
 	ClassDB::bind_method(D_METHOD("environment_set_fog_height", "env", "enable", "min_height", "max_height", "height_curve"), &VisualServer::environment_set_fog_height);
 
 	ClassDB::bind_method(D_METHOD("scenario_create"), &VisualServer::scenario_create);

+ 1 - 1
servers/visual_server.h

@@ -763,7 +763,7 @@ public:
 	virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, float p_ao_channel_affect, const Color &p_color, EnvironmentSSAOQuality p_quality, EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) = 0;
 
 	virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
-	virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+	virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
 	virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
 
 	/* SCENARIO API */