Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions drivers/gles3/storage/light_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,18 +181,30 @@ void LightStorage::light_set_projector(RID p_light, RID p_texture) {
return;
}

if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
if (light->projector.is_valid()) {
texture_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}

light->projector = p_texture;

if (light->type != RS::LIGHT_DIRECTIONAL) {
if (light->projector.is_valid()) {
texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
if (light->projector.is_valid()) {
texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}
light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
}

void LightStorage::light_set_projector_scale(RID p_light, const Vector2 &p_scale) {
Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_NULL(light);

light->projector_scale = p_scale;
}

void LightStorage::light_set_projector_offset(RID p_light, const Vector2 &p_offset) {
Light *light = light_owner.get_or_null(p_light);
ERR_FAIL_NULL(light);

light->projector_offset = p_offset;
}

void LightStorage::light_set_negative(RID p_light, bool p_enable) {
Expand Down
4 changes: 4 additions & 0 deletions drivers/gles3/storage/light_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ struct Light {
float param[RS::LIGHT_PARAM_MAX];
Color color = Color(1, 1, 1, 1);
RID projector;
Vector2 projector_scale;
Vector2 projector_offset;
bool shadow = false;
bool negative = false;
bool reverse_cull = false;
Expand Down Expand Up @@ -322,6 +324,8 @@ class LightStorage : public RendererLightStorage {
virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override;
virtual void light_set_shadow(RID p_light, bool p_enabled) override;
virtual void light_set_projector(RID p_light, RID p_texture) override;
virtual void light_set_projector_scale(RID p_light, const Vector2 &p_scale) override;
virtual void light_set_projector_offset(RID p_light, const Vector2 &p_offset) override;
virtual void light_set_negative(RID p_light, bool p_enable) override;
virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) override;
virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override;
Expand Down
66 changes: 41 additions & 25 deletions scene/3d/light_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ PackedStringArray Light3D::get_configuration_warnings() const {
warnings.push_back(RTR("A light's scale does not affect the visual size of the light."));
}

if (!has_shadow() && get_projector().is_valid()) {
warnings.push_back(RTR("Projector texture only works with shadows active."));
}

if (get_projector().is_valid() && (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility" || OS::get_singleton()->get_current_rendering_method() == "dummy")) {
warnings.push_back(RTR("Projector textures are not supported when using the Compatibility renderer yet. Support will be added in a future release."));
}

return warnings;
}

Expand Down Expand Up @@ -222,6 +230,24 @@ Ref<Texture2D> Light3D::get_projector() const {
return projector;
}

void Light3D::set_projector_scale(const Vector2 &p_scale) {
projector_scale = p_scale;
RS::get_singleton()->light_set_projector_scale(light, p_scale);
}

Vector2 Light3D::get_projector_scale() const {
return projector_scale;
}

void Light3D::set_projector_offset(const Vector2 &p_offset) {
projector_offset = p_offset;
RS::get_singleton()->light_set_projector_offset(light, p_offset);
}

Vector2 Light3D::get_projector_offset() const {
return projector_offset;
}

void Light3D::owner_changed_notify() {
// For cases where owner changes _after_ entering tree (as example, editor editing).
_update_visibility();
Expand Down Expand Up @@ -327,8 +353,8 @@ void Light3D::_validate_property(PropertyInfo &p_property) const {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}

if (get_light_type() != RS::LIGHT_DIRECTIONAL && (p_property.name == "light_angular_distance" || p_property.name == "light_intensity_lux")) {
// Angular distance and Light Intensity Lux are only used in DirectionalLight3D.
if (get_light_type() != RS::LIGHT_DIRECTIONAL && (p_property.name == "light_angular_distance" || p_property.name == "light_intensity_lux" || p_property.name == "Projector" || p_property.name == "light_projector_scale" || p_property.name == "light_projector_offset")) {
// Angular distance, Light Intensity Lux and Projector Subgroup/Scale/Offset are only used in DirectionalLight3D.
p_property.usage = PROPERTY_USAGE_NONE;
} else if (get_light_type() == RS::LIGHT_DIRECTIONAL && p_property.name == "light_intensity_lumens") {
p_property.usage = PROPERTY_USAGE_NONE;
Expand Down Expand Up @@ -386,6 +412,12 @@ void Light3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_projector", "projector"), &Light3D::set_projector);
ClassDB::bind_method(D_METHOD("get_projector"), &Light3D::get_projector);

ClassDB::bind_method(D_METHOD("set_projector_scale", "scale"), &Light3D::set_projector_scale);
ClassDB::bind_method(D_METHOD("get_projector_scale"), &Light3D::get_projector_scale);

ClassDB::bind_method(D_METHOD("set_projector_offset", "offset"), &Light3D::set_projector_offset);
ClassDB::bind_method(D_METHOD("get_projector_offset"), &Light3D::get_projector_offset);

ClassDB::bind_method(D_METHOD("set_temperature", "temperature"), &Light3D::set_temperature);
ClassDB::bind_method(D_METHOD("get_temperature"), &Light3D::get_temperature);
ClassDB::bind_method(D_METHOD("get_correlated_color"), &Light3D::get_correlated_color);
Expand All @@ -398,8 +430,13 @@ void Light3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_ENERGY);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_INDIRECT_ENERGY);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_volumetric_fog_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), "set_param", "get_param", PARAM_VOLUMETRIC_FOG_ENERGY);

// Only allow texture types that display correctly.
ADD_SUBGROUP("Projector", "light_projector_");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_projector", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D,-AnimatedTexture,-AtlasTexture,-CameraTexture,-CanvasTexture,-MeshTexture,-Texture2DRD,-ViewportTexture"), "set_projector", "get_projector");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "light_projector_scale", PROPERTY_HINT_LINK), "set_projector_scale", "get_projector_scale");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "light_projector_offset"), "set_projector_offset", "get_projector_offset");

ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_size", PROPERTY_HINT_RANGE, "0,1,0.001,or_greater,suffix:m"), "set_param", "get_param", PARAM_SIZE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "light_angular_distance", PROPERTY_HINT_RANGE, "0,90,0.01,degrees"), "set_param", "get_param", PARAM_SIZE);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative");
Expand Down Expand Up @@ -560,7 +597,7 @@ void DirectionalLight3D::_validate_property(PropertyInfo &p_property) const {
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
}

if (p_property.name == "light_size" || p_property.name == "light_projector") {
if (p_property.name == "light_size") {
// Not implemented in DirectionalLight3D (`light_size` is replaced by `light_angular_distance`).
p_property.usage = PROPERTY_USAGE_NONE;
}
Expand Down Expand Up @@ -614,6 +651,7 @@ DirectionalLight3D::DirectionalLight3D() :
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
blend_splits = false;
set_sky_mode(SKY_MODE_LIGHT_AND_SKY);
set_projector_scale(Vector2(1, 1));
}

void OmniLight3D::set_shadow_mode(ShadowMode p_mode) {
Expand All @@ -625,20 +663,6 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const {
return shadow_mode;
}

PackedStringArray OmniLight3D::get_configuration_warnings() const {
PackedStringArray warnings = Light3D::get_configuration_warnings();

if (!has_shadow() && get_projector().is_valid()) {
warnings.push_back(RTR("Projector texture only works with shadows active."));
}

if (get_projector().is_valid() && (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility" || OS::get_singleton()->get_current_rendering_method() == "dummy")) {
warnings.push_back(RTR("Projector textures are not supported when using the Compatibility renderer yet. Support will be added in a future release."));
}

return warnings;
}

void OmniLight3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight3D::set_shadow_mode);
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &OmniLight3D::get_shadow_mode);
Expand All @@ -664,14 +688,6 @@ PackedStringArray SpotLight3D::get_configuration_warnings() const {
warnings.push_back(RTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows."));
}

if (!has_shadow() && get_projector().is_valid()) {
warnings.push_back(RTR("Projector texture only works with shadows active."));
}

if (get_projector().is_valid() && (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility" || OS::get_singleton()->get_current_rendering_method() == "dummy")) {
warnings.push_back(RTR("Projector textures are not supported when using the Compatibility renderer yet. Support will be added in a future release."));
}

return warnings;
}

Expand Down
10 changes: 8 additions & 2 deletions scene/3d/light_3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class Light3D : public VisualInstance3D {
void _update_visibility();
BakeMode bake_mode = BAKE_DYNAMIC;
Ref<Texture2D> projector;
Vector2 projector_scale;
Vector2 projector_offset;
Color correlated_color = Color(1.0, 1.0, 1.0);
float temperature = 6500.0;

Expand Down Expand Up @@ -145,6 +147,12 @@ class Light3D : public VisualInstance3D {
void set_projector(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_projector() const;

void set_projector_scale(const Vector2 &p_scale);
Vector2 get_projector_scale() const;

void set_projector_offset(const Vector2 &p_offset);
Vector2 get_projector_offset() const;

void set_temperature(const float p_temperature);
float get_temperature() const;
Color get_correlated_color() const;
Expand Down Expand Up @@ -220,8 +228,6 @@ class OmniLight3D : public Light3D {
void set_shadow_mode(ShadowMode p_mode);
ShadowMode get_shadow_mode() const;

PackedStringArray get_configuration_warnings() const override;

OmniLight3D();
};

Expand Down
11 changes: 11 additions & 0 deletions scene/resources/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ void Environment::_update_volumetric_fog() {
environment,
volumetric_fog_enabled,
volumetric_fog_density,
volumetric_fog_fade,
volumetric_fog_albedo,
volumetric_fog_emission,
volumetric_fog_emission_energy,
Expand Down Expand Up @@ -932,6 +933,13 @@ void Environment::set_volumetric_fog_density(float p_density) {
float Environment::get_volumetric_fog_density() const {
return volumetric_fog_density;
}
void Environment::set_volumetric_fog_fade(float p_fade) {
volumetric_fog_fade = p_fade;
_update_volumetric_fog();
}
float Environment::get_volumetric_fog_fade() const {
return volumetric_fog_fade;
}
void Environment::set_volumetric_fog_albedo(Color p_color) {
volumetric_fog_albedo = p_color;
_update_volumetric_fog();
Expand Down Expand Up @@ -1503,6 +1511,8 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_volumetric_fog_albedo"), &Environment::get_volumetric_fog_albedo);
ClassDB::bind_method(D_METHOD("set_volumetric_fog_density", "density"), &Environment::set_volumetric_fog_density);
ClassDB::bind_method(D_METHOD("get_volumetric_fog_density"), &Environment::get_volumetric_fog_density);
ClassDB::bind_method(D_METHOD("set_volumetric_fog_fade", "density"), &Environment::set_volumetric_fog_fade);
ClassDB::bind_method(D_METHOD("get_volumetric_fog_fade"), &Environment::get_volumetric_fog_fade);
ClassDB::bind_method(D_METHOD("set_volumetric_fog_emission_energy", "begin"), &Environment::set_volumetric_fog_emission_energy);
ClassDB::bind_method(D_METHOD("get_volumetric_fog_emission_energy"), &Environment::get_volumetric_fog_emission_energy);
ClassDB::bind_method(D_METHOD("set_volumetric_fog_anisotropy", "anisotropy"), &Environment::set_volumetric_fog_anisotropy);
Expand All @@ -1525,6 +1535,7 @@ void Environment::_bind_methods() {
ADD_GROUP("Volumetric Fog", "volumetric_fog_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_enabled", PROPERTY_HINT_GROUP_ENABLE), "set_volumetric_fog_enabled", "is_volumetric_fog_enabled");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_density", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater"), "set_volumetric_fog_density", "get_volumetric_fog_density");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_fade", PROPERTY_HINT_RANGE, "0.0001,1,0.0001,or_greater"), "set_volumetric_fog_fade", "get_volumetric_fog_fade");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "volumetric_fog_albedo", PROPERTY_HINT_COLOR_NO_ALPHA), "set_volumetric_fog_albedo", "get_volumetric_fog_albedo");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "volumetric_fog_emission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_volumetric_fog_emission", "get_volumetric_fog_emission");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_emission_energy", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_emission_energy", "get_volumetric_fog_emission_energy");
Expand Down
3 changes: 3 additions & 0 deletions scene/resources/environment.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ class Environment : public Resource {
// Volumetric Fog
bool volumetric_fog_enabled = false;
float volumetric_fog_density = 0.05;
float volumetric_fog_fade = 0.1;
Color volumetric_fog_albedo = Color(1.0, 1.0, 1.0);
Color volumetric_fog_emission = Color(0.0, 0.0, 0.0);
float volumetric_fog_emission_energy = 1.0;
Expand Down Expand Up @@ -407,6 +408,8 @@ class Environment : public Resource {
bool is_volumetric_fog_enabled() const;
void set_volumetric_fog_density(float p_density);
float get_volumetric_fog_density() const;
void set_volumetric_fog_fade(float p_fade);
float get_volumetric_fog_fade() const;
void set_volumetric_fog_albedo(Color p_color);
Color get_volumetric_fog_albedo() const;
void set_volumetric_fog_emission(Color p_color);
Expand Down
2 changes: 2 additions & 0 deletions servers/rendering/dummy/storage/light_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class LightStorage : public RendererLightStorage {
virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {}
virtual void light_set_shadow(RID p_light, bool p_enabled) override {}
virtual void light_set_projector(RID p_light, RID p_texture) override {}
virtual void light_set_projector_scale(RID p_light, const Vector2 &p_scale) override {}
virtual void light_set_projector_offset(RID p_light, const Vector2 &p_offset) override {}
virtual void light_set_negative(RID p_light, bool p_enable) override {}
virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) override {}
virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override {}
Expand Down
9 changes: 7 additions & 2 deletions servers/rendering/renderer_rd/effects/copy_effects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ void CopyEffects::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID
RD::get_singleton()->compute_list_end();
}

void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) {
void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama, Vector2 uv_offset) {
UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
ERR_FAIL_NULL(uniform_set_cache);
MaterialStorage *material_storage = MaterialStorage::get_singleton();
Expand All @@ -516,8 +516,13 @@ void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuff

copy_to_fb.push_constant.luminance_multiplier = 1.0;

copy_to_fb.push_constant.set_color[0] = uv_offset.x;
copy_to_fb.push_constant.set_color[1] = uv_offset.y;

// setup our uniforms
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
// This work too but maybe worse ? I don't know if there is scenario where we want to use repeat disabled
// RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);

RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));

Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/renderer_rd/effects/copy_effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class CopyEffects {
void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false, bool alpha_to_one = false, bool p_linear = false, bool p_normal = false, const Rect2 &p_src_rect = Rect2());
void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false);
void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false, Vector2 uv_offset = Vector2());
void copy_to_drawlist(RD::DrawListID p_draw_list, RD::FramebufferFormatID p_fb_format, RID p_source_rd_texture, bool p_linear = false);
void copy_raster(RID p_source_texture, RID p_dest_framebuffer);

Expand Down
Loading