From 7cd2ff309c5f1c512ed871998157f3fd19aa23ec Mon Sep 17 00:00:00 2001 From: clayjohn Date: Thu, 16 Apr 2020 23:38:22 -0700 Subject: [PATCH] Add light size to Sky Shaders --- doc/classes/ProceduralSkyMaterial.xml | 5 +-- scene/resources/sky_material.cpp | 39 ++++++------------- scene/resources/sky_material.h | 4 -- .../rasterizer_scene_high_end_rd.cpp | 1 + .../rasterizer_rd/rasterizer_scene_rd.cpp | 37 +++++++++++------- .../rasterizer_rd/rasterizer_scene_rd.h | 2 + .../rendering/rasterizer_rd/shaders/sky.glsl | 5 +-- servers/rendering/shader_types.cpp | 4 ++ 8 files changed, 44 insertions(+), 53 deletions(-) diff --git a/doc/classes/ProceduralSkyMaterial.xml b/doc/classes/ProceduralSkyMaterial.xml index 70e82d248c4..d3e1dbca275 100644 --- a/doc/classes/ProceduralSkyMaterial.xml +++ b/doc/classes/ProceduralSkyMaterial.xml @@ -40,11 +40,8 @@ Distance from center of sun where it fades out completely. - - Distance from sun where it goes from solid to starting to fade. - - 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]. diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index 37b88ccceae..a0b6ab1e309 100644 --- a/scene/resources/sky_material.cpp +++ b/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"; diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h index 515706b0c57..9bd9d7ec8b4 100644 --- a/scene/resources/sky_material.h +++ b/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; diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index 77096b95ba3..d59dae3cd8d 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/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++; } diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index 37e2aaad0e4..8555271857d 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/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); diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h index bb42ce71827..00054d941b3 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h +++ b/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 { diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/rasterizer_rd/shaders/sky.glsl index c6c863ec604..e4019725cbe 100644 --- a/servers/rendering/rasterizer_rd/shaders/sky.glsl +++ b/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; }; diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index de69fea16f1..78bbd73db4a 100644 --- a/servers/rendering/shader_types.cpp +++ b/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;