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

Merge pull request #37953 from clayjohn/VULKAN-sky-sun-size

Add light size to Sky Shaders
Rémi Verschelde 5 жил өмнө
parent
commit
cfda0e3770

+ 1 - 4
doc/classes/ProceduralSkyMaterial.xml

@@ -40,11 +40,8 @@
 		<member name="sun_angle_max" type="float" setter="set_sun_angle_max" getter="get_sun_angle_max" default="100.0">
 			Distance from center of sun where it fades out completely.
 		</member>
-		<member name="sun_angle_min" type="float" setter="set_sun_angle_min" getter="get_sun_angle_min" default="1.0">
-			Distance from sun where it goes from solid to starting to fade.
-		</member>
 		<member name="sun_curve" type="float" setter="set_sun_curve" getter="get_sun_curve" default="0.05">
-			How quickly the sun fades away between [member sun_angle_min] and [member sun_angle_max].
+			How quickly the sun fades away between the edge of the sun disk and [member sun_angle_max].
 		</member>
 	</members>
 	<constants>

+ 11 - 28
scene/resources/sky_material.cpp

@@ -111,16 +111,6 @@ float ProceduralSkyMaterial::get_ground_energy() const {
 	return ground_energy;
 }
 
-void ProceduralSkyMaterial::set_sun_angle_min(float p_angle) {
-
-	sun_angle_min = p_angle;
-	RS::get_singleton()->material_set_param(_get_material(), "sun_angle_min", Math::deg2rad(sun_angle_min));
-}
-float ProceduralSkyMaterial::get_sun_angle_min() const {
-
-	return sun_angle_min;
-}
-
 void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) {
 
 	sun_angle_max = p_angle;
@@ -181,9 +171,6 @@ void ProceduralSkyMaterial::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSkyMaterial::set_ground_energy);
 	ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSkyMaterial::get_ground_energy);
 
-	ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSkyMaterial::set_sun_angle_min);
-	ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSkyMaterial::get_sun_angle_min);
-
 	ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSkyMaterial::set_sun_angle_max);
 	ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSkyMaterial::get_sun_angle_max);
 
@@ -203,7 +190,6 @@ void ProceduralSkyMaterial::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
 
 	ADD_GROUP("Sun", "sun_");
-	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
 }
@@ -220,8 +206,7 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
 	code += "uniform vec4 ground_horizon_color : hint_color = vec4(0.37, 0.33, 0.31, 1.0);\n";
 	code += "uniform float ground_curve : hint_range(0, 1) = 0.02;\n";
 	code += "uniform float ground_energy = 1.0;\n\n";
-	code += "uniform float sun_angle_min = 0.01;\n";
-	code += "uniform float sun_angle_max = 1.0;\n";
+	code += "uniform float sun_angle_max = 1.74;\n";
 	code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n";
 	code += "const float PI = 3.1415926535897932384626433833;\n\n";
 	code += "void fragment() {\n";
@@ -231,37 +216,37 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
 	code += "\tsky *= sky_energy;\n";
 	code += "\tif (LIGHT0_ENABLED) {\n";
 	code += "\t\tfloat sun_angle = acos(dot(LIGHT0_DIRECTION, EYEDIR));\n";
-	code += "\t\tif (sun_angle < sun_angle_min) {\n";
+	code += "\t\tif (sun_angle < LIGHT0_SIZE) {\n";
 	code += "\t\t\tsky = LIGHT0_COLOR * LIGHT0_ENERGY;\n";
 	code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
-	code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+	code += "\t\t\tfloat c2 = (sun_angle - LIGHT0_SIZE) / (sun_angle_max - LIGHT0_SIZE);\n";
 	code += "\t\t\tsky = mix(LIGHT0_COLOR * LIGHT0_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
 	code += "\t\t}\n";
 	code += "\t}\n";
 	code += "\tif (LIGHT1_ENABLED) {\n";
 	code += "\t\tfloat sun_angle = acos(dot(LIGHT1_DIRECTION, EYEDIR));\n";
-	code += "\t\tif (sun_angle < sun_angle_min) {\n";
+	code += "\t\tif (sun_angle < LIGHT1_SIZE) {\n";
 	code += "\t\t\tsky = LIGHT1_COLOR * LIGHT1_ENERGY;\n";
 	code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
-	code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+	code += "\t\t\tfloat c2 = (sun_angle - LIGHT1_SIZE) / (sun_angle_max - LIGHT1_SIZE);\n";
 	code += "\t\t\tsky = mix(LIGHT1_COLOR * LIGHT1_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
 	code += "\t\t}\n";
 	code += "\t}\n";
 	code += "\tif (LIGHT2_ENABLED) {\n";
 	code += "\t\tfloat sun_angle = acos(dot(LIGHT2_DIRECTION, EYEDIR));\n";
-	code += "\t\tif (sun_angle < sun_angle_min) {\n";
+	code += "\t\tif (sun_angle < LIGHT2_SIZE) {\n";
 	code += "\t\t\tsky = LIGHT2_COLOR * LIGHT2_ENERGY;\n";
 	code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
-	code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+	code += "\t\t\tfloat c2 = (sun_angle - LIGHT2_SIZE) / (sun_angle_max - LIGHT2_SIZE);\n";
 	code += "\t\t\tsky = mix(LIGHT2_COLOR * LIGHT2_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
 	code += "\t\t}\n";
 	code += "\t}\n";
 	code += "\tif (LIGHT3_ENABLED) {\n";
 	code += "\t\tfloat sun_angle = acos(dot(LIGHT3_DIRECTION, EYEDIR));\n";
-	code += "\t\tif (sun_angle < sun_angle_min) {\n";
+	code += "\t\tif (sun_angle < LIGHT3_SIZE) {\n";
 	code += "\t\t\tsky = LIGHT3_COLOR * LIGHT3_ENERGY;\n";
 	code += "\t\t} else if (sun_angle < sun_angle_max) {\n";
-	code += "\t\t\tfloat c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);\n";
+	code += "\t\t\tfloat c2 = (sun_angle - LIGHT3_SIZE) / (sun_angle_max - LIGHT3_SIZE);\n";
 	code += "\t\t\tsky = mix(LIGHT3_COLOR * LIGHT3_ENERGY, sky, clamp(1.0 - pow(1.0 - c2, 1.0 / sun_curve), 0.0, 1.0));\n";
 	code += "\t\t}\n";
 	code += "\t}\n";
@@ -287,7 +272,6 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() {
 	set_ground_curve(0.02);
 	set_ground_energy(1.0);
 
-	set_sun_angle_min(1.0);
 	set_sun_angle_max(100.0);
 	set_sun_curve(0.05);
 }
@@ -535,7 +519,6 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
 	code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n";
 
 	code += "// Sun constants\n";
-	code += "const float SOL_SIZE = 0.00872663806;\n";
 	code += "const float SUN_ENERGY = 1000.0;\n\n";
 
 	code += "// optical length at zenith for molecules\n";
@@ -591,8 +574,8 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
 	code += "\tLin  *= mix(ground_color.rgb, vec3(1.0), smoothstep(-0.1, 0.1, dot(UP, EYEDIR)));\n\n";
 
 	code += "\t// Solar disk and out-scattering\n";
-	code += "\tfloat sunAngularDiameterCos = cos(SOL_SIZE * sun_disk_scale);\n";
-	code += "\tfloat sunAngularDiameterCos2 = cos(SOL_SIZE * sun_disk_scale*0.5);\n";
+	code += "\tfloat sunAngularDiameterCos = cos(LIGHT0_SIZE * sun_disk_scale);\n";
+	code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
 	code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
 	code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
 	code += "\t// Note: Add nightime here: L0 += night_sky * extinction\n\n";

+ 0 - 4
scene/resources/sky_material.h

@@ -49,7 +49,6 @@ private:
 	float ground_curve;
 	float ground_energy;
 
-	float sun_angle_min;
 	float sun_angle_max;
 	float sun_curve;
 
@@ -84,9 +83,6 @@ public:
 	void set_ground_energy(float p_energy);
 	float get_ground_energy() const;
 
-	void set_sun_angle_min(float p_angle);
-	float get_sun_angle_min() const;
-
 	void set_sun_angle_max(float p_angle);
 	float get_sun_angle_max() const;
 

+ 1 - 0
servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp

@@ -1784,6 +1784,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
 					sky_light_data.color[2] = light_data.color[2];
 
 					sky_light_data.enabled = true;
+					sky_light_data.size = light_data.softshadow_angle;
 					sky_scene_state.directional_light_count++;
 				}
 

+ 23 - 14
servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp

@@ -655,7 +655,8 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position,
 						sky_scene_state.directional_lights[i].color[0] != sky_scene_state.last_frame_directional_lights[i].color[0] ||
 						sky_scene_state.directional_lights[i].color[1] != sky_scene_state.last_frame_directional_lights[i].color[1] ||
 						sky_scene_state.directional_lights[i].color[2] != sky_scene_state.last_frame_directional_lights[i].color[2] ||
-						sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled) {
+						sky_scene_state.directional_lights[i].enabled != sky_scene_state.last_frame_directional_lights[i].enabled ||
+						sky_scene_state.directional_lights[i].size != sky_scene_state.last_frame_directional_lights[i].size) {
 					light_data_dirty = true;
 					break;
 				}
@@ -851,18 +852,22 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) {
 	actions.usage_flag_pointers["LIGHT0_ENERGY"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT0_DIRECTION"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT0_COLOR"] = &uses_light;
+	actions.usage_flag_pointers["LIGHT0_SIZE"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT1_ENABLED"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT1_ENERGY"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT1_DIRECTION"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT1_COLOR"] = &uses_light;
+	actions.usage_flag_pointers["LIGHT1_SIZE"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT2_ENABLED"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT2_ENERGY"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT2_DIRECTION"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT2_COLOR"] = &uses_light;
+	actions.usage_flag_pointers["LIGHT2_SIZE"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT3_ENABLED"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT3_ENERGY"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT3_DIRECTION"] = &uses_light;
 	actions.usage_flag_pointers["LIGHT3_COLOR"] = &uses_light;
+	actions.usage_flag_pointers["LIGHT3_SIZE"] = &uses_light;
 
 	actions.uniforms = &uniforms;
 
@@ -4187,21 +4192,25 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
 		actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color";
 		actions.renames["RADIANCE"] = "radiance";
 		actions.renames["LIGHT0_ENABLED"] = "directional_lights.data[0].enabled";
-		actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction";
-		actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].energy";
-		actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color";
+		actions.renames["LIGHT0_DIRECTION"] = "directional_lights.data[0].direction_energy.xyz";
+		actions.renames["LIGHT0_ENERGY"] = "directional_lights.data[0].direction_energy.w";
+		actions.renames["LIGHT0_COLOR"] = "directional_lights.data[0].color_size.xyz";
+		actions.renames["LIGHT0_SIZE"] = "directional_lights.data[0].color_size.w";
 		actions.renames["LIGHT1_ENABLED"] = "directional_lights.data[1].enabled";
-		actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction";
-		actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].energy";
-		actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color";
+		actions.renames["LIGHT1_DIRECTION"] = "directional_lights.data[1].direction_energy.xyz";
+		actions.renames["LIGHT1_ENERGY"] = "directional_lights.data[1].direction_energy.w";
+		actions.renames["LIGHT1_COLOR"] = "directional_lights.data[1].color_size.xyz";
+		actions.renames["LIGHT1_SIZE"] = "directional_lights.data[1].color_size.w";
 		actions.renames["LIGHT2_ENABLED"] = "directional_lights.data[2].enabled";
-		actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction";
-		actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].energy";
-		actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color";
+		actions.renames["LIGHT2_DIRECTION"] = "directional_lights.data[2].direction_energy.xyz";
+		actions.renames["LIGHT2_ENERGY"] = "directional_lights.data[2].direction_energy.w";
+		actions.renames["LIGHT2_COLOR"] = "directional_lights.data[2].color_size.xyz";
+		actions.renames["LIGHT2_SIZE"] = "directional_lights.data[2].color_size.w";
 		actions.renames["LIGHT3_ENABLED"] = "directional_lights.data[3].enabled";
-		actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction";
-		actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].energy";
-		actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color";
+		actions.renames["LIGHT3_DIRECTION"] = "directional_lights.data[3].direction_energy.xyz";
+		actions.renames["LIGHT3_ENERGY"] = "directional_lights.data[3].direction_energy.w";
+		actions.renames["LIGHT3_COLOR"] = "directional_lights.data[3].color_size.xyz";
+		actions.renames["LIGHT3_SIZE"] = "directional_lights.data[3].color_size.w";
 		actions.renames["AT_CUBEMAP_PASS"] = "AT_CUBEMAP_PASS";
 		actions.renames["AT_HALF_RES_PASS"] = "AT_HALF_RES_PASS";
 		actions.renames["AT_QUARTER_RES_PASS"] = "AT_QUARTER_RES_PASS";
@@ -4224,7 +4233,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
 	{
 		// default material and shader for sky shader
 		sky_shader.default_shader = storage->shader_create();
-		storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = mix(vec3(0.3), vec3(0.2, 0.4, 0.9), smoothstep(0.0, 0.05, EYEDIR.y)); } \n");
+		storage->shader_set_code(sky_shader.default_shader, "shader_type sky; void fragment() { COLOR = vec3(0.0); } \n");
 		sky_shader.default_material = storage->material_create();
 		storage->material_set_shader(sky_shader.default_material, sky_shader.default_shader);
 

+ 2 - 0
servers/rendering/rasterizer_rd/rasterizer_scene_rd.h

@@ -56,7 +56,9 @@ protected:
 		float direction[3];
 		float energy;
 		float color[3];
+		float size;
 		uint32_t enabled;
+		uint32_t pad[3];
 	};
 
 	struct SkySceneState {

+ 2 - 3
servers/rendering/rasterizer_rd/shaders/sky.glsl

@@ -96,9 +96,8 @@ layout(set = 2, binding = 2) uniform texture2D quarter_res;
 #endif
 
 struct DirectionalLightData {
-	vec3 direction;
-	float energy;
-	vec3 color;
+	vec4 direction_energy;
+	vec4 color_size;
 	bool enabled;
 };
 

+ 4 - 0
servers/rendering/shader_types.cpp

@@ -303,18 +303,22 @@ ShaderTypes::ShaderTypes() {
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
+	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT0_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
+	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT1_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
+	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT2_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_ENABLED"] = constt(ShaderLanguage::TYPE_BOOL);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_DIRECTION"] = constt(ShaderLanguage::TYPE_VEC3);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_ENERGY"] = constt(ShaderLanguage::TYPE_FLOAT);
 	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_COLOR"] = constt(ShaderLanguage::TYPE_VEC3);
+	shader_modes[RS::SHADER_SKY].functions["global"].built_ins["LIGHT3_SIZE"] = constt(ShaderLanguage::TYPE_FLOAT);
 
 	shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC3;
 	shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT;