Add sky_only setting to DirectionalLight3Ds
This commit is contained in:
parent
c3964b6c83
commit
6299575250
|
@ -41,6 +41,9 @@
|
|||
</member>
|
||||
<member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.05" />
|
||||
<member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" override="true" default="1.0" />
|
||||
<member name="use_in_sky_only" type="bool" setter="set_sky_only" getter="is_sky_only" default="false">
|
||||
If [code]true[/code], this [DirectionalLight3D] will not be used for anything except sky shaders. Use this for lights that impact your sky shader that you may want to hide from affecting the rest of the scene. For example, you may want to enable this when the sun in your sky shader falls below the horizon.
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
<constant name="SHADOW_ORTHOGONAL" value="0" enum="ShadowMode">
|
||||
|
|
|
@ -1432,6 +1432,17 @@
|
|||
Sets the shadow mode for this directional light. Equivalent to [member DirectionalLight3D.directional_shadow_mode]. See [enum LightDirectionalShadowMode] for options.
|
||||
</description>
|
||||
</method>
|
||||
<method name="light_directional_set_sky_only">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="light" type="RID">
|
||||
</argument>
|
||||
<argument index="1" name="enable" type="bool">
|
||||
</argument>
|
||||
<description>
|
||||
If [code]true[/code], this light will not be used for anything except sky shaders. Use this for lights that impact your sky shader that you may want to hide from affecting the rest of the scene. For example, you may want to enable this when the sun in your sky shader falls below the horizon.
|
||||
</description>
|
||||
</method>
|
||||
<method name="light_omni_set_shadow_mode">
|
||||
<return type="void">
|
||||
</return>
|
||||
|
|
|
@ -591,6 +591,8 @@ public:
|
|||
void light_directional_set_blend_splits(RID p_light, bool p_enable) override {}
|
||||
bool light_directional_get_blend_splits(RID p_light) const override { return false; }
|
||||
void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) override {}
|
||||
void light_directional_set_sky_only(RID p_light, bool p_sky_only) override {}
|
||||
bool light_directional_is_sky_only(RID p_light) const override { return false; }
|
||||
RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const override { return RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; }
|
||||
|
||||
RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) override { return RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; }
|
||||
|
|
|
@ -394,6 +394,15 @@ bool DirectionalLight3D::is_blend_splits_enabled() const {
|
|||
return blend_splits;
|
||||
}
|
||||
|
||||
void DirectionalLight3D::set_sky_only(bool p_sky_only) {
|
||||
sky_only = p_sky_only;
|
||||
RS::get_singleton()->light_directional_set_sky_only(light, p_sky_only);
|
||||
}
|
||||
|
||||
bool DirectionalLight3D::is_sky_only() const {
|
||||
return sky_only;
|
||||
}
|
||||
|
||||
void DirectionalLight3D::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &DirectionalLight3D::set_shadow_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &DirectionalLight3D::get_shadow_mode);
|
||||
|
@ -404,6 +413,9 @@ void DirectionalLight3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_blend_splits", "enabled"), &DirectionalLight3D::set_blend_splits);
|
||||
ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight3D::is_blend_splits_enabled);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_sky_only", "priority"), &DirectionalLight3D::set_sky_only);
|
||||
ClassDB::bind_method(D_METHOD("is_sky_only"), &DirectionalLight3D::is_sky_only);
|
||||
|
||||
ADD_GROUP("Directional Shadow", "directional_shadow_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal (Fast),PSSM 2 Splits (Average),PSSM 4 Splits (Slow)"), "set_shadow_mode", "get_shadow_mode");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_split_1", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_1_OFFSET);
|
||||
|
@ -415,6 +427,8 @@ void DirectionalLight3D::_bind_methods() {
|
|||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_EXP_RANGE, "0,8192,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_pancake_size", PROPERTY_HINT_EXP_RANGE, "0,1024,0.1,or_greater"), "set_param", "get_param", PARAM_SHADOW_PANCAKE_SIZE);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_in_sky_only"), "set_sky_only", "is_sky_only");
|
||||
|
||||
BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL);
|
||||
BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS);
|
||||
BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS);
|
||||
|
|
|
@ -158,6 +158,7 @@ private:
|
|||
bool blend_splits;
|
||||
ShadowMode shadow_mode;
|
||||
ShadowDepthRange shadow_depth_range;
|
||||
bool sky_only = false;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
@ -172,6 +173,9 @@ public:
|
|||
void set_blend_splits(bool p_enable);
|
||||
bool is_blend_splits_enabled() const;
|
||||
|
||||
void set_sky_only(bool p_sky_only);
|
||||
bool is_sky_only() const;
|
||||
|
||||
DirectionalLight3D();
|
||||
};
|
||||
|
||||
|
|
|
@ -517,6 +517,8 @@ public:
|
|||
virtual void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) = 0;
|
||||
virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0;
|
||||
virtual bool light_directional_get_blend_splits(RID p_light) const = 0;
|
||||
virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0;
|
||||
virtual bool light_directional_is_sky_only(RID p_light) const = 0;
|
||||
virtual void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) = 0;
|
||||
virtual RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const = 0;
|
||||
|
||||
|
|
|
@ -1187,6 +1187,11 @@ void RasterizerSceneRD::sdfgi_update_probes(RID p_render_buffers, RID p_environm
|
|||
|
||||
LightInstance *li = light_instance_owner.getornull(p_directional_light_instances[j]);
|
||||
ERR_CONTINUE(!li);
|
||||
|
||||
if (storage->light_directional_is_sky_only(li->light)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector3 dir = -li->transform.basis.get_axis(Vector3::AXIS_Z);
|
||||
dir.y *= rb->sdfgi->y_mult;
|
||||
dir.normalize();
|
||||
|
@ -4391,6 +4396,11 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
|
|||
RID light = light_instance_get_base_light(light_instance);
|
||||
|
||||
l.type = storage->light_get_type(light);
|
||||
if (l.type == RS::LIGHT_DIRECTIONAL && storage->light_directional_is_sky_only(light)) {
|
||||
light_count--;
|
||||
continue;
|
||||
}
|
||||
|
||||
l.attenuation = storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
|
||||
l.energy = storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
|
||||
l.radius = to_cell.basis.xform(Vector3(storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();
|
||||
|
@ -5930,7 +5940,40 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
|
|||
RS::LightType type = storage->light_get_type(base);
|
||||
switch (type) {
|
||||
case RS::LIGHT_DIRECTIONAL: {
|
||||
if (r_directional_light_count >= cluster.max_directional_lights) {
|
||||
// Copy to SkyDirectionalLightData
|
||||
if (r_directional_light_count < sky_scene_state.max_directional_lights) {
|
||||
SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[r_directional_light_count];
|
||||
Transform light_transform = light_instance_get_base_transform(li);
|
||||
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
|
||||
|
||||
sky_light_data.direction[0] = world_direction.x;
|
||||
sky_light_data.direction[1] = world_direction.y;
|
||||
sky_light_data.direction[2] = -world_direction.z;
|
||||
|
||||
float sign = storage->light_is_negative(base) ? -1 : 1;
|
||||
sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
|
||||
|
||||
Color linear_col = storage->light_get_color(base).to_linear();
|
||||
sky_light_data.color[0] = linear_col.r;
|
||||
sky_light_data.color[1] = linear_col.g;
|
||||
sky_light_data.color[2] = linear_col.b;
|
||||
|
||||
sky_light_data.enabled = true;
|
||||
|
||||
float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
|
||||
if (angular_diameter > 0.0) {
|
||||
// I know tan(0) is 0, but let's not risk it with numerical precision.
|
||||
// technically this will keep expanding until reaching the sun, but all we care
|
||||
// is expand until we reach the radius of the near plane (there can't be more occluders than that)
|
||||
angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
|
||||
} else {
|
||||
angular_diameter = 0.0;
|
||||
}
|
||||
sky_light_data.size = angular_diameter;
|
||||
sky_scene_state.ubo.directional_light_count++;
|
||||
}
|
||||
|
||||
if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_is_sky_only(base)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -6073,27 +6116,6 @@ void RasterizerSceneRD::_setup_lights(RID *p_light_cull_result, int p_light_cull
|
|||
}
|
||||
}
|
||||
|
||||
// Copy to SkyDirectionalLightData
|
||||
if (r_directional_light_count < sky_scene_state.max_directional_lights) {
|
||||
SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[r_directional_light_count];
|
||||
|
||||
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
|
||||
|
||||
sky_light_data.direction[0] = world_direction.x;
|
||||
sky_light_data.direction[1] = world_direction.y;
|
||||
sky_light_data.direction[2] = -world_direction.z;
|
||||
|
||||
sky_light_data.energy = light_data.energy / Math_PI;
|
||||
|
||||
sky_light_data.color[0] = light_data.color[0];
|
||||
sky_light_data.color[1] = light_data.color[1];
|
||||
sky_light_data.color[2] = light_data.color[2];
|
||||
|
||||
sky_light_data.enabled = true;
|
||||
sky_light_data.size = angular_diameter;
|
||||
sky_scene_state.ubo.directional_light_count++;
|
||||
}
|
||||
|
||||
r_directional_light_count++;
|
||||
} break;
|
||||
case RS::LIGHT_SPOT:
|
||||
|
|
|
@ -4950,6 +4950,20 @@ bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const
|
|||
return light->directional_blend_splits;
|
||||
}
|
||||
|
||||
void RasterizerStorageRD::light_directional_set_sky_only(RID p_light, bool p_sky_only) {
|
||||
Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->directional_sky_only = p_sky_only;
|
||||
}
|
||||
|
||||
bool RasterizerStorageRD::light_directional_is_sky_only(RID p_light) const {
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, false);
|
||||
|
||||
return light->directional_sky_only;
|
||||
}
|
||||
|
||||
RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow_mode(RID p_light) {
|
||||
const Light *light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
|
||||
|
|
|
@ -823,6 +823,7 @@ private:
|
|||
RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
|
||||
RS::LightDirectionalShadowDepthRangeMode directional_range_mode = RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE;
|
||||
bool directional_blend_splits = false;
|
||||
bool directional_sky_only = false;
|
||||
uint64_t version = 0;
|
||||
|
||||
RasterizerScene::InstanceDependency instance_dependency;
|
||||
|
@ -1459,6 +1460,8 @@ public:
|
|||
void light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode);
|
||||
void light_directional_set_blend_splits(RID p_light, bool p_enable);
|
||||
bool light_directional_get_blend_splits(RID p_light) const;
|
||||
void light_directional_set_sky_only(RID p_light, bool p_sky_only);
|
||||
bool light_directional_is_sky_only(RID p_light) const;
|
||||
void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode);
|
||||
RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const;
|
||||
|
||||
|
|
|
@ -337,6 +337,7 @@ public:
|
|||
|
||||
BIND2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
|
||||
BIND2(light_directional_set_blend_splits, RID, bool)
|
||||
BIND2(light_directional_set_sky_only, RID, bool)
|
||||
BIND2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
|
||||
|
||||
/* PROBE API */
|
||||
|
|
|
@ -2169,7 +2169,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
|
|||
//check shadow..
|
||||
|
||||
if (light) {
|
||||
if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->get()->base)) {
|
||||
if (p_using_shadows && p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(E->get()->base) && !(RSG::storage->light_get_type(E->get()->base) == RS::LIGHT_DIRECTIONAL && RSG::storage->light_directional_is_sky_only(E->get()->base))) {
|
||||
lights_with_shadow[directional_shadow_count++] = E->get();
|
||||
}
|
||||
//add to list
|
||||
|
@ -2595,7 +2595,8 @@ void RenderingServerScene::render_probes() {
|
|||
cache->radius != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_RANGE) ||
|
||||
cache->attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION) ||
|
||||
cache->spot_angle != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE) ||
|
||||
cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION)) {
|
||||
cache->spot_attenuation != RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION) ||
|
||||
cache->sky_only != RSG::storage->light_directional_is_sky_only(instance->base)) {
|
||||
cache_dirty = true;
|
||||
}
|
||||
}
|
||||
|
@ -2664,6 +2665,7 @@ void RenderingServerScene::render_probes() {
|
|||
cache->attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_ATTENUATION);
|
||||
cache->spot_angle = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ANGLE);
|
||||
cache->spot_attenuation = RSG::storage->light_get_param(instance->base, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
cache->sky_only = RSG::storage->light_directional_is_sky_only(instance->base);
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
|
|
@ -351,6 +351,7 @@ public:
|
|||
float spot_angle;
|
||||
float spot_attenuation;
|
||||
bool has_shadow;
|
||||
bool sky_only;
|
||||
};
|
||||
|
||||
Vector<LightCache> light_cache;
|
||||
|
|
|
@ -244,6 +244,7 @@ public:
|
|||
|
||||
FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
|
||||
FUNC2(light_directional_set_blend_splits, RID, bool)
|
||||
FUNC2(light_directional_set_sky_only, RID, bool)
|
||||
FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode)
|
||||
|
||||
/* PROBE API */
|
||||
|
|
|
@ -1618,6 +1618,7 @@ void RenderingServer::_bind_methods() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("light_directional_set_shadow_mode", "light", "mode"), &RenderingServer::light_directional_set_shadow_mode);
|
||||
ClassDB::bind_method(D_METHOD("light_directional_set_blend_splits", "light", "enable"), &RenderingServer::light_directional_set_blend_splits);
|
||||
ClassDB::bind_method(D_METHOD("light_directional_set_sky_only", "light", "enable"), &RenderingServer::light_directional_set_sky_only);
|
||||
ClassDB::bind_method(D_METHOD("light_directional_set_shadow_depth_range_mode", "light", "range_mode"), &RenderingServer::light_directional_set_shadow_depth_range_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("reflection_probe_create"), &RenderingServer::reflection_probe_create);
|
||||
|
|
|
@ -435,6 +435,7 @@ public:
|
|||
|
||||
virtual void light_directional_set_shadow_mode(RID p_light, LightDirectionalShadowMode p_mode) = 0;
|
||||
virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0;
|
||||
virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0;
|
||||
|
||||
enum LightDirectionalShadowDepthRangeMode {
|
||||
LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE,
|
||||
|
|
Loading…
Reference in New Issue