Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/scene/2d/light_2d.cpp
9896 views
1
/**************************************************************************/
2
/* light_2d.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#include "light_2d.h"
32
33
void Light2D::owner_changed_notify() {
34
// For cases where owner changes _after_ entering tree (as example, editor editing).
35
_update_light_visibility();
36
}
37
38
void Light2D::_update_light_visibility() {
39
if (!is_inside_tree()) {
40
return;
41
}
42
43
bool editor_ok = true;
44
45
#ifdef TOOLS_ENABLED
46
if (editor_only) {
47
if (!Engine::get_singleton()->is_editor_hint()) {
48
editor_ok = false;
49
} else {
50
editor_ok = (get_tree()->get_edited_scene_root() && (this == get_tree()->get_edited_scene_root() || get_owner() == get_tree()->get_edited_scene_root()));
51
}
52
}
53
#else
54
if (editor_only) {
55
editor_ok = false;
56
}
57
#endif // TOOLS_ENABLED
58
59
RS::get_singleton()->canvas_light_set_enabled(canvas_light, enabled && is_visible_in_tree() && editor_ok);
60
}
61
62
void Light2D::set_enabled(bool p_enabled) {
63
enabled = p_enabled;
64
_update_light_visibility();
65
}
66
67
bool Light2D::is_enabled() const {
68
return enabled;
69
}
70
71
void Light2D::set_editor_only(bool p_editor_only) {
72
editor_only = p_editor_only;
73
_update_light_visibility();
74
}
75
76
bool Light2D::is_editor_only() const {
77
return editor_only;
78
}
79
80
void Light2D::set_color(const Color &p_color) {
81
color = p_color;
82
RS::get_singleton()->canvas_light_set_color(canvas_light, color);
83
}
84
85
Color Light2D::get_color() const {
86
return color;
87
}
88
89
void Light2D::set_height(real_t p_height) {
90
height = p_height;
91
RS::get_singleton()->canvas_light_set_height(canvas_light, height);
92
}
93
94
real_t Light2D::get_height() const {
95
return height;
96
}
97
98
void Light2D::set_energy(real_t p_energy) {
99
energy = p_energy;
100
RS::get_singleton()->canvas_light_set_energy(canvas_light, energy);
101
}
102
103
real_t Light2D::get_energy() const {
104
return energy;
105
}
106
107
void Light2D::set_z_range_min(int p_min_z) {
108
z_min = p_min_z;
109
RS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max);
110
}
111
112
int Light2D::get_z_range_min() const {
113
return z_min;
114
}
115
116
void Light2D::set_z_range_max(int p_max_z) {
117
z_max = p_max_z;
118
RS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max);
119
}
120
121
int Light2D::get_z_range_max() const {
122
return z_max;
123
}
124
125
void Light2D::set_layer_range_min(int p_min_layer) {
126
layer_min = p_min_layer;
127
RS::get_singleton()->canvas_light_set_layer_range(canvas_light, layer_min, layer_max);
128
}
129
130
int Light2D::get_layer_range_min() const {
131
return layer_min;
132
}
133
134
void Light2D::set_layer_range_max(int p_max_layer) {
135
layer_max = p_max_layer;
136
RS::get_singleton()->canvas_light_set_layer_range(canvas_light, layer_min, layer_max);
137
}
138
139
int Light2D::get_layer_range_max() const {
140
return layer_max;
141
}
142
143
void Light2D::set_item_cull_mask(int p_mask) {
144
item_mask = p_mask;
145
RS::get_singleton()->canvas_light_set_item_cull_mask(canvas_light, item_mask);
146
}
147
148
int Light2D::get_item_cull_mask() const {
149
return item_mask;
150
}
151
152
void Light2D::set_item_shadow_cull_mask(int p_mask) {
153
item_shadow_mask = p_mask;
154
RS::get_singleton()->canvas_light_set_item_shadow_cull_mask(canvas_light, item_shadow_mask);
155
}
156
157
int Light2D::get_item_shadow_cull_mask() const {
158
return item_shadow_mask;
159
}
160
161
void Light2D::set_shadow_enabled(bool p_enabled) {
162
shadow = p_enabled;
163
RS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow);
164
}
165
166
bool Light2D::is_shadow_enabled() const {
167
return shadow;
168
}
169
170
void Light2D::set_shadow_filter(ShadowFilter p_filter) {
171
ERR_FAIL_INDEX(p_filter, SHADOW_FILTER_MAX);
172
shadow_filter = p_filter;
173
RS::get_singleton()->canvas_light_set_shadow_filter(canvas_light, RS::CanvasLightShadowFilter(p_filter));
174
notify_property_list_changed();
175
}
176
177
Light2D::ShadowFilter Light2D::get_shadow_filter() const {
178
return shadow_filter;
179
}
180
181
void Light2D::set_shadow_color(const Color &p_shadow_color) {
182
shadow_color = p_shadow_color;
183
RS::get_singleton()->canvas_light_set_shadow_color(canvas_light, shadow_color);
184
}
185
186
Color Light2D::get_shadow_color() const {
187
return shadow_color;
188
}
189
190
void Light2D::set_blend_mode(BlendMode p_mode) {
191
blend_mode = p_mode;
192
RS::get_singleton()->canvas_light_set_blend_mode(_get_light(), RS::CanvasLightBlendMode(p_mode));
193
}
194
195
Light2D::BlendMode Light2D::get_blend_mode() const {
196
return blend_mode;
197
}
198
199
void Light2D::_physics_interpolated_changed() {
200
RenderingServer::get_singleton()->canvas_light_set_interpolated(canvas_light, is_physics_interpolated());
201
}
202
203
void Light2D::_notification(int p_what) {
204
switch (p_what) {
205
case NOTIFICATION_ENTER_CANVAS: {
206
RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, get_canvas());
207
_update_light_visibility();
208
} break;
209
210
case NOTIFICATION_TRANSFORM_CHANGED: {
211
RS::get_singleton()->canvas_light_set_transform(canvas_light, get_global_transform());
212
} break;
213
214
case NOTIFICATION_VISIBILITY_CHANGED: {
215
_update_light_visibility();
216
} break;
217
218
case NOTIFICATION_RESET_PHYSICS_INTERPOLATION: {
219
if (is_visible_in_tree() && is_physics_interpolated_and_enabled()) {
220
// Explicitly make sure the transform is up to date in RenderingServer before
221
// resetting. This is necessary because NOTIFICATION_TRANSFORM_CHANGED
222
// is normally deferred, and a client change to transform will not always be sent
223
// before the reset, so we need to guarantee this.
224
RS::get_singleton()->canvas_light_set_transform(canvas_light, get_global_transform());
225
RS::get_singleton()->canvas_light_reset_physics_interpolation(canvas_light);
226
}
227
} break;
228
229
case NOTIFICATION_EXIT_CANVAS: {
230
RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, RID());
231
_update_light_visibility();
232
} break;
233
}
234
}
235
236
void Light2D::set_shadow_smooth(real_t p_amount) {
237
shadow_smooth = p_amount;
238
RS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth);
239
}
240
241
real_t Light2D::get_shadow_smooth() const {
242
return shadow_smooth;
243
}
244
245
void Light2D::_validate_property(PropertyInfo &p_property) const {
246
if (!Engine::get_singleton()->is_editor_hint()) {
247
return;
248
}
249
if (shadow && p_property.name == "shadow_filter_smooth" && shadow_filter == SHADOW_FILTER_NONE) {
250
p_property.usage = PROPERTY_USAGE_NO_EDITOR;
251
}
252
}
253
254
void Light2D::_bind_methods() {
255
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Light2D::set_enabled);
256
ClassDB::bind_method(D_METHOD("is_enabled"), &Light2D::is_enabled);
257
258
ClassDB::bind_method(D_METHOD("set_editor_only", "editor_only"), &Light2D::set_editor_only);
259
ClassDB::bind_method(D_METHOD("is_editor_only"), &Light2D::is_editor_only);
260
261
ClassDB::bind_method(D_METHOD("set_color", "color"), &Light2D::set_color);
262
ClassDB::bind_method(D_METHOD("get_color"), &Light2D::get_color);
263
264
ClassDB::bind_method(D_METHOD("set_energy", "energy"), &Light2D::set_energy);
265
ClassDB::bind_method(D_METHOD("get_energy"), &Light2D::get_energy);
266
267
ClassDB::bind_method(D_METHOD("set_z_range_min", "z"), &Light2D::set_z_range_min);
268
ClassDB::bind_method(D_METHOD("get_z_range_min"), &Light2D::get_z_range_min);
269
270
ClassDB::bind_method(D_METHOD("set_z_range_max", "z"), &Light2D::set_z_range_max);
271
ClassDB::bind_method(D_METHOD("get_z_range_max"), &Light2D::get_z_range_max);
272
273
ClassDB::bind_method(D_METHOD("set_layer_range_min", "layer"), &Light2D::set_layer_range_min);
274
ClassDB::bind_method(D_METHOD("get_layer_range_min"), &Light2D::get_layer_range_min);
275
276
ClassDB::bind_method(D_METHOD("set_layer_range_max", "layer"), &Light2D::set_layer_range_max);
277
ClassDB::bind_method(D_METHOD("get_layer_range_max"), &Light2D::get_layer_range_max);
278
279
ClassDB::bind_method(D_METHOD("set_item_cull_mask", "item_cull_mask"), &Light2D::set_item_cull_mask);
280
ClassDB::bind_method(D_METHOD("get_item_cull_mask"), &Light2D::get_item_cull_mask);
281
282
ClassDB::bind_method(D_METHOD("set_item_shadow_cull_mask", "item_shadow_cull_mask"), &Light2D::set_item_shadow_cull_mask);
283
ClassDB::bind_method(D_METHOD("get_item_shadow_cull_mask"), &Light2D::get_item_shadow_cull_mask);
284
285
ClassDB::bind_method(D_METHOD("set_shadow_enabled", "enabled"), &Light2D::set_shadow_enabled);
286
ClassDB::bind_method(D_METHOD("is_shadow_enabled"), &Light2D::is_shadow_enabled);
287
288
ClassDB::bind_method(D_METHOD("set_shadow_smooth", "smooth"), &Light2D::set_shadow_smooth);
289
ClassDB::bind_method(D_METHOD("get_shadow_smooth"), &Light2D::get_shadow_smooth);
290
291
ClassDB::bind_method(D_METHOD("set_shadow_filter", "filter"), &Light2D::set_shadow_filter);
292
ClassDB::bind_method(D_METHOD("get_shadow_filter"), &Light2D::get_shadow_filter);
293
294
ClassDB::bind_method(D_METHOD("set_shadow_color", "shadow_color"), &Light2D::set_shadow_color);
295
ClassDB::bind_method(D_METHOD("get_shadow_color"), &Light2D::get_shadow_color);
296
297
ClassDB::bind_method(D_METHOD("set_blend_mode", "mode"), &Light2D::set_blend_mode);
298
ClassDB::bind_method(D_METHOD("get_blend_mode"), &Light2D::get_blend_mode);
299
300
ClassDB::bind_method(D_METHOD("set_height", "height"), &Light2D::set_height);
301
ClassDB::bind_method(D_METHOD("get_height"), &Light2D::get_height);
302
303
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
304
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only");
305
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
306
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy");
307
ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Add,Subtract,Mix"), "set_blend_mode", "get_blend_mode");
308
ADD_GROUP("Range", "range_");
309
ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_min", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_min", "get_z_range_min");
310
ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_max", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_max", "get_z_range_max");
311
ADD_PROPERTY(PropertyInfo(Variant::INT, "range_layer_min", PROPERTY_HINT_RANGE, itos(RS::CANVAS_LAYER_MIN) + "," + itos(RS::CANVAS_LAYER_MAX) + ",1"), "set_layer_range_min", "get_layer_range_min");
312
ADD_PROPERTY(PropertyInfo(Variant::INT, "range_layer_max", PROPERTY_HINT_RANGE, itos(RS::CANVAS_LAYER_MIN) + "," + itos(RS::CANVAS_LAYER_MAX) + ",1"), "set_layer_range_max", "get_layer_range_max");
313
ADD_PROPERTY(PropertyInfo(Variant::INT, "range_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_cull_mask", "get_item_cull_mask");
314
315
ADD_GROUP("Shadow", "shadow_");
316
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled", PROPERTY_HINT_GROUP_ENABLE), "set_shadow_enabled", "is_shadow_enabled");
317
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color");
318
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None (Fast),PCF5 (Average),PCF13 (Slow)"), "set_shadow_filter", "get_shadow_filter");
319
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth");
320
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask");
321
322
BIND_ENUM_CONSTANT(SHADOW_FILTER_NONE);
323
BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF5);
324
BIND_ENUM_CONSTANT(SHADOW_FILTER_PCF13);
325
326
BIND_ENUM_CONSTANT(BLEND_MODE_ADD);
327
BIND_ENUM_CONSTANT(BLEND_MODE_SUB);
328
BIND_ENUM_CONSTANT(BLEND_MODE_MIX);
329
}
330
331
Light2D::Light2D() {
332
canvas_light = RenderingServer::get_singleton()->canvas_light_create();
333
set_notify_transform(true);
334
}
335
336
Light2D::~Light2D() {
337
ERR_FAIL_NULL(RenderingServer::get_singleton());
338
RenderingServer::get_singleton()->free(canvas_light);
339
}
340
341
//////////////////////////////
342
343
#ifdef TOOLS_ENABLED
344
Dictionary PointLight2D::_edit_get_state() const {
345
Dictionary state = Node2D::_edit_get_state();
346
state["offset"] = get_texture_offset();
347
return state;
348
}
349
350
void PointLight2D::_edit_set_state(const Dictionary &p_state) {
351
Node2D::_edit_set_state(p_state);
352
set_texture_offset(p_state["offset"]);
353
}
354
355
void PointLight2D::_edit_set_pivot(const Point2 &p_pivot) {
356
set_position(get_transform().xform(p_pivot));
357
set_texture_offset(get_texture_offset() - p_pivot);
358
}
359
360
Point2 PointLight2D::_edit_get_pivot() const {
361
return Vector2();
362
}
363
364
bool PointLight2D::_edit_use_pivot() const {
365
return true;
366
}
367
#endif // TOOLS_ENABLED
368
369
#ifdef DEBUG_ENABLED
370
Rect2 PointLight2D::_edit_get_rect() const {
371
if (texture.is_null()) {
372
return Rect2();
373
}
374
375
Size2 s = texture->get_size() * _scale;
376
return Rect2(texture_offset - s / 2.0, s);
377
}
378
379
bool PointLight2D::_edit_use_rect() const {
380
return texture.is_valid();
381
}
382
#endif // DEBUG_ENABLED
383
384
Rect2 PointLight2D::get_anchorable_rect() const {
385
if (texture.is_null()) {
386
return Rect2();
387
}
388
389
Size2 s = texture->get_size() * _scale;
390
return Rect2(texture_offset - s / 2.0, s);
391
}
392
393
void PointLight2D::set_texture(const Ref<Texture2D> &p_texture) {
394
texture = p_texture;
395
if (texture.is_valid()) {
396
#ifdef DEBUG_ENABLED
397
if (
398
p_texture->is_class("AnimatedTexture") ||
399
p_texture->is_class("AtlasTexture") ||
400
p_texture->is_class("CameraTexture") ||
401
p_texture->is_class("CanvasTexture") ||
402
p_texture->is_class("MeshTexture") ||
403
p_texture->is_class("Texture2DRD") ||
404
p_texture->is_class("ViewportTexture")) {
405
WARN_PRINT(vformat("%s cannot be used as a PointLight2D texture (%s). As a workaround, assign the value returned by %s's `get_image()` instead.", p_texture->get_class(), get_path(), p_texture->get_class()));
406
}
407
#endif
408
409
RS::get_singleton()->canvas_light_set_texture(_get_light(), texture->get_rid());
410
} else {
411
RS::get_singleton()->canvas_light_set_texture(_get_light(), RID());
412
}
413
414
update_configuration_warnings();
415
}
416
417
Ref<Texture2D> PointLight2D::get_texture() const {
418
return texture;
419
}
420
421
void PointLight2D::set_texture_offset(const Vector2 &p_offset) {
422
texture_offset = p_offset;
423
RS::get_singleton()->canvas_light_set_texture_offset(_get_light(), texture_offset);
424
item_rect_changed();
425
}
426
427
Vector2 PointLight2D::get_texture_offset() const {
428
return texture_offset;
429
}
430
431
PackedStringArray PointLight2D::get_configuration_warnings() const {
432
PackedStringArray warnings = Light2D::get_configuration_warnings();
433
434
if (texture.is_null()) {
435
warnings.push_back(RTR("A texture with the shape of the light must be supplied to the \"Texture\" property."));
436
}
437
438
return warnings;
439
}
440
441
void PointLight2D::set_texture_scale(real_t p_scale) {
442
_scale = p_scale;
443
// Avoid having 0 scale values, can lead to errors in physics and rendering.
444
if (_scale == 0) {
445
_scale = CMP_EPSILON;
446
}
447
RS::get_singleton()->canvas_light_set_texture_scale(_get_light(), _scale);
448
item_rect_changed();
449
}
450
451
real_t PointLight2D::get_texture_scale() const {
452
return _scale;
453
}
454
455
#ifndef DISABLE_DEPRECATED
456
bool PointLight2D::_set(const StringName &p_name, const Variant &p_value) {
457
if (p_name == "mode" && p_value.is_num()) { // Compatibility with Godot 3.x.
458
set_blend_mode((BlendMode)(int)p_value);
459
return true;
460
}
461
462
return false;
463
}
464
#endif // DISABLE_DEPRECATED
465
466
void PointLight2D::_bind_methods() {
467
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &PointLight2D::set_texture);
468
ClassDB::bind_method(D_METHOD("get_texture"), &PointLight2D::get_texture);
469
470
ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &PointLight2D::set_texture_offset);
471
ClassDB::bind_method(D_METHOD("get_texture_offset"), &PointLight2D::get_texture_offset);
472
473
ClassDB::bind_method(D_METHOD("set_texture_scale", "texture_scale"), &PointLight2D::set_texture_scale);
474
ClassDB::bind_method(D_METHOD("get_texture_scale"), &PointLight2D::get_texture_scale);
475
476
// Only allow texture types that display correctly.
477
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D,-AnimatedTexture,-AtlasTexture,-CameraTexture,-CanvasTexture,-MeshTexture,-Texture2DRD,-ViewportTexture"), "set_texture", "get_texture");
478
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "set_texture_offset", "get_texture_offset");
479
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale");
480
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1024,1,or_greater,suffix:px"), "set_height", "get_height");
481
}
482
483
PointLight2D::PointLight2D() {
484
RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_POINT);
485
set_hide_clip_children(true);
486
}
487
488
//////////
489
490
void DirectionalLight2D::set_max_distance(real_t p_distance) {
491
max_distance = p_distance;
492
RS::get_singleton()->canvas_light_set_directional_distance(_get_light(), max_distance);
493
}
494
495
real_t DirectionalLight2D::get_max_distance() const {
496
return max_distance;
497
}
498
499
void DirectionalLight2D::_bind_methods() {
500
ClassDB::bind_method(D_METHOD("set_max_distance", "pixels"), &DirectionalLight2D::set_max_distance);
501
ClassDB::bind_method(D_METHOD("get_max_distance"), &DirectionalLight2D::get_max_distance);
502
503
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "height", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_height", "get_height");
504
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_RANGE, "0,16384.0,1.0,or_greater,suffix:px"), "set_max_distance", "get_max_distance");
505
}
506
507
DirectionalLight2D::DirectionalLight2D() {
508
RS::get_singleton()->canvas_light_set_mode(_get_light(), RS::CANVAS_LIGHT_MODE_DIRECTIONAL);
509
set_max_distance(max_distance); // Update RenderingServer.
510
set_hide_clip_children(true);
511
}
512
513