@@ -29,27 +29,47 @@ extends MultiMeshInstance3D
29
29
@export var player_radius := 0.5 : set = _on_set_player_radius
30
30
@export_color_no_alpha var albedo := Color .WHITE : set = _on_set_albedo
31
31
@export var texture_albedo : Texture = load ("res://addons/simplegrasstextured/textures/grassbushcc008.png" ) : set = _on_set_texture_albedo
32
- @export var alpha_scissor_threshold := 0.5 : set = _on_set_alpha_scissor_threshold
32
+ @export_range ( 0.0 , 1.0 ) var alpha_scissor_threshold := 0.5 : set = _on_set_alpha_scissor_threshold
33
33
@export var scale_h := 1.0 : set = _on_set_scale_h
34
34
@export var scale_w := 1.0 : set = _on_set_scale_w
35
35
@export var scale_var := - 0.25 : set = _on_set_scale_var
36
36
@export_range (0.0 , 1.0 ) var grass_strength := 0.8 : set = _on_set_grass_strength
37
37
@export var wind_dir := Vector3 .RIGHT : set = _on_set_wind_dir
38
- @export var wind_strength := 0.03 : set = _on_set_wind_strength
39
- @export var wind_speed := 1.0 : set = _on_set_wind_speed
38
+ @export var wind_strength := 0.15 : set = _on_set_wind_strength
39
+ @export var wind_turbulence := 1.0 : set = _on_set_wind_turbulence
40
+ @export var wind_pattern : Texture = load ("res://addons/simplegrasstextured/images/win_pattern.png" ) : set = _on_set_wind_pattern
41
+ @export_group ("Optimization" )
40
42
@export var optimization_by_distance := false : set = _on_set_optimization_by_distance
41
43
@export var optimization_level := 7.0 : set = _on_set_optimization_level
44
+ @export var optimization_dist_min := 10.0 : set = _on_set_optimization_dist_min
45
+ @export var optimization_dist_max := 50.0 : set = _on_set_optimization_dist_max
42
46
43
- var dist_min : float = 0.0
47
+ var sgt_radius := 2.0
48
+ var sgt_density := 25
49
+ var sgt_scale := 1.0
50
+ var sgt_rotation := 0.0
51
+ var sgt_rotation_rand := 1.0
52
+ var sgt_dist_min := 0.0
53
+ var sgt_follow_normal := false
44
54
45
55
var _default_mesh : Mesh = null
46
56
var _buffer_add : Array [Transform3D ] = []
47
57
var _material := load ("res://addons/simplegrasstextured/materials/grass.material" ).duplicate () as ShaderMaterial
48
58
var _force_update_multimesh := false
59
+ var _properties = []
49
60
50
61
51
62
func _init ():
52
63
_default_mesh = _build_default_mesh ()
64
+ if Engine .is_editor_hint ():
65
+ for var_i in get_property_list ():
66
+ if not var_i .name .begins_with ("sgt_" ):
67
+ continue
68
+ _properties .append ({
69
+ "name" : var_i .name ,
70
+ "type" : var_i .type ,
71
+ "usage" : PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_SCRIPT_VARIABLE ,
72
+ })
53
73
54
74
55
75
func _ready ():
@@ -58,7 +78,7 @@ func _ready():
58
78
else :
59
79
set_process (false )
60
80
if not has_meta ("SimpleGrassTextured" ):
61
- # Update for previous version, now shader needs vertex color
81
+ # Update for previous version, 1.0.2 needs vertex color
62
82
set_meta ("SimpleGrassTextured" , "1.0.2" )
63
83
_force_update_multimesh = true
64
84
if multimesh != null :
@@ -86,9 +106,12 @@ func _ready():
86
106
_on_set_grass_strength (grass_strength )
87
107
_on_set_wind_dir (wind_dir )
88
108
_on_set_wind_strength (wind_strength )
89
- _on_set_wind_speed (wind_speed )
109
+ _on_set_wind_turbulence (wind_turbulence )
110
+ _on_set_wind_pattern (wind_pattern )
90
111
_on_set_optimization_by_distance (optimization_by_distance )
91
112
_on_set_optimization_level (optimization_level )
113
+ _on_set_optimization_dist_min (optimization_dist_min )
114
+ _on_set_optimization_dist_max (optimization_dist_max )
92
115
93
116
94
117
func _process (_delta : float ):
@@ -97,15 +120,30 @@ func _process(_delta : float):
97
120
_update_multimesh ()
98
121
99
122
100
- func add_grass (pos : Vector3 , normal : Vector3 , scale : Vector3 ):
123
+ func _get_property_list () -> Array :
124
+ if _properties == null :
125
+ return []
126
+ return _properties
127
+
128
+
129
+ func add_grass (pos : Vector3 , normal : Vector3 , scale : Vector3 , rotated : float ):
101
130
var trans := Transform3D ()
102
- trans = trans .rotated (Vector3 .UP , TAU * randf ())
103
- trans .basis .y = normal
131
+ if abs (normal .z ) == 1 :
132
+ trans .basis .x = Vector3 (1 ,0 ,0 )
133
+ trans .basis .y = Vector3 (0 ,0 ,normal .z )
134
+ trans .basis .z = Vector3 (0 ,normal .z ,0 )
135
+ trans .basis = trans .basis .orthonormalized ()
136
+ else :
137
+ trans .basis .y = normal
138
+ trans .basis .x = normal .cross (trans .basis .z )
139
+ trans .basis .z = trans .basis .x .cross (normal )
140
+ trans .basis = trans .basis .orthonormalized ()
141
+ trans = trans .rotated_local (Vector3 .UP , rotated )
104
142
trans = trans .scaled (scale )
105
143
trans = trans .translated (pos )
106
- if dist_min > 0 :
144
+ if sgt_dist_min > 0 :
107
145
for trans_prev in _buffer_add :
108
- if trans .origin .distance_to (trans_prev .origin ) <= dist_min :
146
+ if trans .origin .distance_to (trans_prev .origin ) <= sgt_dist_min :
109
147
return
110
148
_buffer_add .append (trans )
111
149
@@ -141,11 +179,27 @@ func _update_multimesh():
141
179
multi_new .mesh = mesh
142
180
else :
143
181
multi_new .mesh = _default_mesh
144
- if _buffer_add .size () > 0 and dist_min > 0 :
182
+ if _buffer_add .size () > 0 and sgt_dist_min > 0 :
183
+ var pos_min := Vector3 (10000000 , 10000000 , 10000000 )
184
+ var pos_max := pos_min * - 1
185
+ var center := Vector3 .ZERO
186
+ var radius := 0.0
187
+ var r_index := []
188
+ for trans in _buffer_add :
189
+ if pos_min > trans .origin :
190
+ pos_min = trans .origin
191
+ if pos_max < trans .origin :
192
+ pos_max = trans .origin
193
+ center = pos_min + ((pos_max - pos_min ) / 2.0 )
194
+ radius = center .distance_to (pos_min ) + 1.0
145
195
for i in range (multimesh .instance_count ):
196
+ var trans := multimesh .get_instance_transform (i )
197
+ if trans .origin .distance_to (center ) <= radius :
198
+ r_index .append (i )
199
+ for i in r_index :
146
200
var trans := multimesh .get_instance_transform (i )
147
201
for trans_add in _buffer_add :
148
- if trans_add .origin .distance_to (trans .origin ) <= dist_min :
202
+ if trans_add .origin .distance_to (trans .origin ) <= sgt_dist_min :
149
203
_buffer_add .erase (trans_add )
150
204
break
151
205
multi_new .instance_count = count_prev + _buffer_add .size ()
@@ -227,6 +281,11 @@ func _build_default_mesh() -> Mesh:
227
281
228
282
func _on_set_mesh (value : Mesh ):
229
283
mesh = value
284
+ if _material != null :
285
+ if mesh != null :
286
+ _material .set_shader_parameter ("grass_size_y" , mesh .get_aabb ().size .y )
287
+ else :
288
+ _material .set_shader_parameter ("grass_size_y" , 1.0 )
230
289
if Engine .is_editor_hint () and is_inside_tree ():
231
290
_update_multimesh ()
232
291
@@ -297,10 +356,16 @@ func _on_set_wind_strength(value : float):
297
356
_material .set_shader_parameter ("wind_strength" , wind_strength )
298
357
299
358
300
- func _on_set_wind_speed (value : float ):
301
- wind_speed = value
359
+ func _on_set_wind_turbulence (value : float ):
360
+ wind_turbulence = value
361
+ if _material != null :
362
+ _material .set_shader_parameter ("wind_turbulence" , wind_turbulence )
363
+
364
+
365
+ func _on_set_wind_pattern (value : Texture ):
366
+ wind_pattern = value
302
367
if _material != null :
303
- _material .set_shader_parameter ("wind_speed " , wind_speed )
368
+ _material .set_shader_parameter ("wind_pattern " , wind_pattern )
304
369
305
370
306
371
func _on_set_optimization_by_distance (value : bool ):
@@ -313,3 +378,16 @@ func _on_set_optimization_level(value : float):
313
378
optimization_level = value
314
379
if _material != null :
315
380
_material .set_shader_parameter ("optimization_level" , optimization_level )
381
+
382
+
383
+ func _on_set_optimization_dist_min (value : float ):
384
+ optimization_dist_min = value
385
+ if _material != null :
386
+ _material .set_shader_parameter ("optimization_dist_min" , optimization_dist_min )
387
+
388
+
389
+ func _on_set_optimization_dist_max (value : float ):
390
+ optimization_dist_max = value
391
+ if _material != null :
392
+ _material .set_shader_parameter ("optimization_dist_max" , optimization_dist_max )
393
+
0 commit comments