@@ -189,6 +189,14 @@ PackedStringArray Light3D::get_configuration_warnings() const {
189189 warnings.push_back (RTR (" A light's scale does not affect the visual size of the light." ));
190190 }
191191
192+ if (!has_shadow () && get_projector ().is_valid ()) {
193+ warnings.push_back (RTR (" Projector texture only works with shadows active." ));
194+ }
195+
196+ if (get_projector ().is_valid () && (OS::get_singleton ()->get_current_rendering_method () == " gl_compatibility" || OS::get_singleton ()->get_current_rendering_method () == " dummy" )) {
197+ warnings.push_back (RTR (" Projector textures are not supported when using the Compatibility renderer yet. Support will be added in a future release." ));
198+ }
199+
192200 return warnings;
193201}
194202
@@ -226,6 +234,24 @@ Ref<Texture2D> Light3D::get_projector() const {
226234 return projector;
227235}
228236
237+ void Light3D::set_projector_size (const Vector2 &p_size) {
238+ projector_size = p_size;
239+ RS::get_singleton ()->light_set_projector_size (light, p_size);
240+ }
241+
242+ Vector2 Light3D::get_projector_size () const {
243+ return projector_size;
244+ }
245+
246+ void Light3D::set_projector_offset (const Vector2 &p_offset) {
247+ projector_offset = p_offset;
248+ RS::get_singleton ()->light_set_projector_offset (light, p_offset);
249+ }
250+
251+ Vector2 Light3D::get_projector_offset () const {
252+ return projector_offset;
253+ }
254+
229255void Light3D::owner_changed_notify () {
230256 // For cases where owner changes _after_ entering tree (as example, editor editing).
231257 _update_visibility ();
@@ -327,8 +353,8 @@ bool Light3D::is_editor_only() const {
327353}
328354
329355void Light3D::_validate_property (PropertyInfo &p_property) const {
330- if (get_light_type () != RSE::LIGHT_DIRECTIONAL && (p_property.name == " light_angular_distance" || p_property.name == " light_intensity_lux" )) {
331- // Angular distance and Light Intensity Lux are only used in DirectionalLight3D.
356+ if (get_light_type () != RSE::LIGHT_DIRECTIONAL && (p_property.name == " light_angular_distance" || p_property.name == " light_intensity_lux" || p_property. name == " Projector " || p_property. name == " light_projector_size " || p_property. name == " light_projector_offset " )) {
357+ // Angular distance, Light Intensity Lux and Projector Subgroup/Size/Offset are only used in DirectionalLight3D.
332358 p_property.usage = PROPERTY_USAGE_NONE;
333359 } else if (get_light_type () == RSE::LIGHT_DIRECTIONAL && p_property.name == " light_intensity_lumens" ) {
334360 p_property.usage = PROPERTY_USAGE_NONE;
@@ -380,6 +406,12 @@ void Light3D::_bind_methods() {
380406 ClassDB::bind_method (D_METHOD (" set_projector" , " projector" ), &Light3D::set_projector);
381407 ClassDB::bind_method (D_METHOD (" get_projector" ), &Light3D::get_projector);
382408
409+ ClassDB::bind_method (D_METHOD (" set_projector_size" , " size" ), &Light3D::set_projector_size);
410+ ClassDB::bind_method (D_METHOD (" get_projector_size" ), &Light3D::get_projector_size);
411+
412+ ClassDB::bind_method (D_METHOD (" set_projector_offset" , " offset" ), &Light3D::set_projector_offset);
413+ ClassDB::bind_method (D_METHOD (" get_projector_offset" ), &Light3D::get_projector_offset);
414+
383415 ClassDB::bind_method (D_METHOD (" set_temperature" , " temperature" ), &Light3D::set_temperature);
384416 ClassDB::bind_method (D_METHOD (" get_temperature" ), &Light3D::get_temperature);
385417 ClassDB::bind_method (D_METHOD (" get_correlated_color" ), &Light3D::get_correlated_color);
@@ -392,8 +424,13 @@ void Light3D::_bind_methods() {
392424 ADD_PROPERTYI (PropertyInfo (Variant::FLOAT, " light_energy" , PROPERTY_HINT_RANGE, " 0,16,0.001,or_greater" ), " set_param" , " get_param" , PARAM_ENERGY);
393425 ADD_PROPERTYI (PropertyInfo (Variant::FLOAT, " light_indirect_energy" , PROPERTY_HINT_RANGE, " 0,16,0.001,or_greater" ), " set_param" , " get_param" , PARAM_INDIRECT_ENERGY);
394426 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);
427+
395428 // Only allow texture types that display correctly.
429+ ADD_SUBGROUP (" Projector" , " light_projector_" );
396430 ADD_PROPERTY (PropertyInfo (Variant::OBJECT, " light_projector" , PROPERTY_HINT_RESOURCE_TYPE, " Texture2D,-AnimatedTexture,-AtlasTexture,-CameraTexture,-CanvasTexture,-MeshTexture,-Texture2DRD,-ViewportTexture" ), " set_projector" , " get_projector" );
431+ ADD_PROPERTY (PropertyInfo (Variant::VECTOR2, " light_projector_size" , PROPERTY_HINT_LINK, " suffix:m" ), " set_projector_size" , " get_projector_size" );
432+ ADD_PROPERTY (PropertyInfo (Variant::VECTOR2, " light_projector_offset" , PROPERTY_HINT_NONE, " suffix:m" ), " set_projector_offset" , " get_projector_offset" );
433+
397434 ADD_PROPERTYI (PropertyInfo (Variant::FLOAT, " light_size" , PROPERTY_HINT_RANGE, " 0,1,0.001,or_greater,suffix:m" ), " set_param" , " get_param" , PARAM_SIZE);
398435 ADD_PROPERTYI (PropertyInfo (Variant::FLOAT, " light_angular_distance" , PROPERTY_HINT_RANGE, " 0,90,0.01,degrees" ), " set_param" , " get_param" , PARAM_SIZE);
399436 ADD_PROPERTY (PropertyInfo (Variant::BOOL, " light_negative" ), " set_negative" , " is_negative" );
@@ -555,7 +592,7 @@ void DirectionalLight3D::_validate_property(PropertyInfo &p_property) const {
555592 p_property.usage = PROPERTY_USAGE_NO_EDITOR;
556593 }
557594 }
558- if (p_property.name == " light_size" || p_property. name == " light_projector " ) {
595+ if (p_property.name == " light_size" ) {
559596 // Not implemented in DirectionalLight3D (`light_size` is replaced by `light_angular_distance`).
560597 p_property.usage = PROPERTY_USAGE_NONE;
561598 } else if (p_property.name == " distance_fade_enabled" || p_property.name == " distance_fade_begin" || p_property.name == " distance_fade_shadow" || p_property.name == " distance_fade_length" ) {
@@ -607,6 +644,7 @@ DirectionalLight3D::DirectionalLight3D() :
607644 set_shadow_mode (SHADOW_PARALLEL_4_SPLITS);
608645 blend_splits = false ;
609646 set_sky_mode (SKY_MODE_LIGHT_AND_SKY);
647+ set_projector_size (Vector2 (100.0 , 100.0 ));
610648}
611649
612650void OmniLight3D::set_shadow_mode (ShadowMode p_mode) {
@@ -618,20 +656,6 @@ OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const {
618656 return shadow_mode;
619657}
620658
621- PackedStringArray OmniLight3D::get_configuration_warnings () const {
622- PackedStringArray warnings = Light3D::get_configuration_warnings ();
623-
624- if (!has_shadow () && get_projector ().is_valid ()) {
625- warnings.push_back (RTR (" Projector texture only works with shadows active." ));
626- }
627-
628- if (get_projector ().is_valid () && (OS::get_singleton ()->get_current_rendering_method () == " gl_compatibility" || OS::get_singleton ()->get_current_rendering_method () == " dummy" )) {
629- warnings.push_back (RTR (" Projector textures are not supported when using the Compatibility renderer yet. Support will be added in a future release." ));
630- }
631-
632- return warnings;
633- }
634-
635659void OmniLight3D::_bind_methods () {
636660 ClassDB::bind_method (D_METHOD (" set_shadow_mode" , " mode" ), &OmniLight3D::set_shadow_mode);
637661 ClassDB::bind_method (D_METHOD (" get_shadow_mode" ), &OmniLight3D::get_shadow_mode);
@@ -657,14 +681,6 @@ PackedStringArray SpotLight3D::get_configuration_warnings() const {
657681 warnings.push_back (RTR (" A SpotLight3D with an angle wider than 90 degrees cannot cast shadows." ));
658682 }
659683
660- if (!has_shadow () && get_projector ().is_valid ()) {
661- warnings.push_back (RTR (" Projector texture only works with shadows active." ));
662- }
663-
664- if (get_projector ().is_valid () && (OS::get_singleton ()->get_current_rendering_method () == " gl_compatibility" || OS::get_singleton ()->get_current_rendering_method () == " dummy" )) {
665- warnings.push_back (RTR (" Projector textures are not supported when using the Compatibility renderer yet. Support will be added in a future release." ));
666- }
667-
668684 return warnings;
669685}
670686
0 commit comments