Source files
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1,86 @@
|
||||
#############################################################################################
|
||||
:: macro init_parameter_random(param_name, input_offset, additive = false, no_export = false)
|
||||
|
||||
p_{{ param_name }} = uniform_ab({{ param_name }} - {{ param_name }} * {{ param_name }}_random, {{ param_name }})
|
||||
|
||||
:: if input_offset > -1
|
||||
|
||||
map_sample = samplelum(p_position, {{ input_offset }}, 1)
|
||||
:: if not additive
|
||||
p_{{ param_name }} = p_{{ param_name }} * map_sample if use_{{ param_name }}_map and not dynamic_{{ param_name }}_map else p_{{ param_name }}
|
||||
:: else
|
||||
p_{{ param_name }} = p_{{ param_name }} + map_sample if use_{{ param_name }}_map and not dynamic_{{ param_name }}_map else p_{{ param_name }}
|
||||
::endif
|
||||
|
||||
:: if not no_export
|
||||
export(p_{{ param_name }})
|
||||
:: endif
|
||||
|
||||
:: endif
|
||||
|
||||
:: endmacro
|
||||
|
||||
#############################################################################################
|
||||
:: macro init_parameter_var(param_name, input_offset, additive = false, no_export = false)
|
||||
p_{{ param_name }} = uniform_ab({{ param_name }} - {{ param_name }}_var, {{ param_name }} + {{ param_name }}_var)
|
||||
|
||||
:: if input_offset > -1
|
||||
|
||||
map_sample = samplelum(p_position, {{ input_offset }}, 1)
|
||||
:: if not additive
|
||||
p_{{ param_name }} = p_{{ param_name }} * map_sample if use_{{ param_name }}_map and not dynamic_{{ param_name }}_map else p_{{ param_name }}
|
||||
:: else
|
||||
p_{{ param_name }} = p_{{ param_name }} + map_sample if use_{{ param_name }}_map and not dynamic_{{ param_name }}_map else p_{{ param_name }}
|
||||
::endif
|
||||
|
||||
:: if not no_export
|
||||
export(p_{{ param_name }})
|
||||
:: endif
|
||||
|
||||
:: endif
|
||||
|
||||
:: endmacro
|
||||
|
||||
#############################################################################################
|
||||
:: macro calculate_modifier_sample()
|
||||
outp_size = get_float2("$size")
|
||||
frag_size = 1.0 / outp_size.x
|
||||
modifier_sample = vector2(frag_size / 2.0 + norm_life * (1.0 - frag_size), 0.5)
|
||||
glob_lifetime = get_int("lifetime")
|
||||
glob_life = n / (tofloat(glob_lifetime) - 1.0) if glob_lifetime > 1 else 0.0
|
||||
modifier_sample_global = vector2(frag_size / 2.0 + glob_life * (1.0 - frag_size), 0.5)
|
||||
:: endmacro
|
||||
|
||||
#############################################################################################
|
||||
:: macro apply_modifiers(param_name, input_offset, additive = false)
|
||||
|
||||
param_mod_sample = modifier_sample_global if {{ param_name }}_modifier_mode else modifier_sample
|
||||
modifier = samplelum(param_mod_sample, {{ 16 + input_offset }}, 0)
|
||||
|
||||
:: if not additive
|
||||
p_{{ param_name }} = p_{{ param_name }} * modifier if use_{{ param_name }}_modifier else p_{{ param_name }}
|
||||
:: else
|
||||
p_{{ param_name }} = p_{{ param_name }} + modifier if use_{{ param_name }}_modifier else p_{{ param_name }}
|
||||
:: endif
|
||||
|
||||
map_sample = samplelum(p_position, {{ 9 + input_offset }}, 1)
|
||||
:: if not additive
|
||||
p_{{ param_name }} = p_{{ param_name }} * map_sample if use_{{ param_name }}_map and dynamic_{{ param_name }}_map else p_{{ param_name }}
|
||||
:: else
|
||||
p_{{ param_name }} = p_{{ param_name }} + map_sample if use_{{ param_name }}_map and dynamic_{{ param_name }}_map else p_{{ param_name }}
|
||||
:: endif
|
||||
|
||||
:: endmacro
|
||||
|
||||
#############################################################################################
|
||||
:: macro sample_curve(factor, npoints, is_closed, alpha, tension, point_prefix, start_index = 0):
|
||||
catmull_rom_16({{ factor }},
|
||||
{{ npoints }},
|
||||
{{ is_closed }},
|
||||
{{ alpha }},
|
||||
{{ tension }},
|
||||
:: for p_i in range(start_index, start_index + 16):
|
||||
{{ point_prefix }}{{ p_i }},
|
||||
:: endfor
|
||||
)
|
||||
:: endmacro
|
||||
@@ -0,0 +1,71 @@
|
||||
:: macro init_pcloud(cloud_name)
|
||||
{{ cloud_name }}_meta = get_float3("#{{ cloud_name }}_meta")
|
||||
|
||||
{{ cloud_name }}_frag_size = float2(1.0, 1.0) / {{ cloud_name }}_meta.yz
|
||||
{{ cloud_name }}_size_half = {{ cloud_name }}_frag_size / float2(2.0, 2.0)
|
||||
:: endmacro
|
||||
|
||||
:: macro get_pcloud_point(cloud_name, sample_idx, sample_name, cloud_input = 0)
|
||||
row = ({{ sample_idx }} * 2) / toint({{ cloud_name }}_meta.y)
|
||||
column = ({{ sample_idx }} * 2) % toint({{ cloud_name }}_meta.y)
|
||||
|
||||
rc = vector2(tofloat(column), tofloat(row))
|
||||
sample_uv = {{ cloud_name }}_size_half + rc * {{ cloud_name }}_frag_size
|
||||
|
||||
{{ sample_name }} = samplecol(sample_uv, {{ cloud_input }}, 0)
|
||||
{{ sample_name }}_attrib = samplecol(sample_uv + vector2({{ cloud_name }}_frag_size.x, 0.0), {{ cloud_input }}, 0)
|
||||
:: endmacro
|
||||
|
||||
:: macro get_pcloud_point_noattr(cloud_name, sample_idx, sample_name, cloud_input = 0)
|
||||
row = ({{ sample_idx }} * 2) / toint({{ cloud_name }}_meta.y)
|
||||
column = ({{ sample_idx }} * 2) % toint({{ cloud_name }}_meta.y)
|
||||
|
||||
rc = vector2(tofloat(column), tofloat(row))
|
||||
sample_uv = {{ cloud_name }}_size_half + rc * {{ cloud_name }}_frag_size
|
||||
|
||||
{{ sample_name }} = samplecol(sample_uv, {{ cloud_input }}, 0)
|
||||
:: endmacro
|
||||
|
||||
:: macro pcloud_index_uv(uv_name, cloud_name, index)
|
||||
|
||||
pc_row = ({{ index }} * 2) / toint({{ cloud_name }}_meta.y)
|
||||
pc_column = ({{ index }} * 2) % toint({{ cloud_name }}_meta.y)
|
||||
pc_rc = vector2(tofloat(pc_column), tofloat(pc_row))
|
||||
f2_one = float2(1.0, 1.0)
|
||||
|
||||
{{ uv_name }} = {{ cloud_name }}_size_half + pc_rc / ( {{ cloud_name }}_meta.yz - f2_one ) * (f2_one - {{ cloud_name }}_frag_size )
|
||||
|
||||
:: endmacro
|
||||
|
||||
:: macro pp_init()
|
||||
size = get_float2("$size")
|
||||
pos = get_float2("$pos")
|
||||
frag_size = float2(1.0, 1.0) / size
|
||||
frag_size_half = frag_size / float2(2.0, 2.0)
|
||||
pixel_coord = size * (pos - frag_size_half)
|
||||
pixel_index = pixel_coord.y * size.x + pixel_coord.x
|
||||
pixel_index = toint(pixel_index)
|
||||
is_attrib = pixel_index % 2 > 0
|
||||
|
||||
sample = samplecol(pos, 0, 0)
|
||||
attr_offset = vector2(-frag_size.x, 0.0) if is_attrib else vector2(frag_size.x, 0.0)
|
||||
neigh_sample = samplecol(pos + attr_offset, 0, 0)
|
||||
|
||||
point = neigh_sample if is_attrib else sample
|
||||
point_attrib = sample if is_attrib else neigh_sample
|
||||
:: endmacro
|
||||
|
||||
:: macro sample_curve(factor, npoints, is_closed, alpha, tension, point_prefix, start_index = 0):
|
||||
catmull_rom_16({{ factor }},
|
||||
{{ npoints }},
|
||||
{{ is_closed }},
|
||||
{{ alpha }},
|
||||
{{ tension }},
|
||||
:: for p_i in range(start_index, start_index + 16):
|
||||
{{ point_prefix }}{{ p_i }},
|
||||
:: endfor
|
||||
)
|
||||
:: endmacro
|
||||
|
||||
:: set attrib_map = {1:"point.z", 2:"point_attrib.x", 3:"point_attrib.y", 4:"point_attrib.z"}
|
||||
:: set tile_offset = ["0.0, 0.0", "0.0, -1.0", "0.0, 1.0", "-1.0, 0.0", "1.0, 0.0", "1.0, -1.0", "1.0, 1.0", "-1.0, -1.0", "-1.0, 1.0"]
|
||||
@@ -0,0 +1,102 @@
|
||||
:: import "particle_system.sex" as ps
|
||||
:: import "point_cloud.sex" as pc
|
||||
|
||||
declare_inputs("particle_system")
|
||||
|
||||
{{ pc.init_pcloud("pcloud") }}
|
||||
|
||||
lifetime_rand = tofloat(lifetime) * (1.0 - lifetime_random)
|
||||
p_lifetime = toint(uniform_ab(lifetime_rand, tofloat(lifetime)))
|
||||
stop_simulation = 0
|
||||
|
||||
# calculate start position
|
||||
|
||||
emitter_direction = 0.0
|
||||
p_position = start_position
|
||||
|
||||
# calculate line position
|
||||
|
||||
line_vec = end_position - start_position
|
||||
line_pos = start_position + line_vec @ uniform_ab(0.0, 1.0)
|
||||
line_direction = atan2(line_vec) / _2pi()
|
||||
|
||||
# calculate circle position
|
||||
|
||||
circle_rad = uniform_ab(emitter_radius.x, emitter_radius.y)
|
||||
circle_arc = uniform_ab(emitter_arc.x, emitter_arc.y)
|
||||
|
||||
circle_vec = vector2(-circle_rad, 0.0)
|
||||
circle_vec = rotate_vec2(circle_vec, -circle_arc, float2(0.0, 0.0))
|
||||
|
||||
circle_pos = start_position + circle_vec
|
||||
circle_direction = circle_arc
|
||||
|
||||
# sample point cloud
|
||||
|
||||
sample_idx = toint(uniform_ab(0.0, pcloud_meta.x ))
|
||||
sample_idx = toint(get_float("$number")) if emitter_type == 3 and pcloud_random else sample_idx
|
||||
|
||||
{{ pc.get_pcloud_point("pcloud", "sample_idx", "point", 23) }}
|
||||
|
||||
cloud_direction = point.z
|
||||
|
||||
# set start position
|
||||
|
||||
p_position = line_pos if emitter_type == 1 else p_position
|
||||
p_position = circle_pos if emitter_type == 2 else p_position
|
||||
p_position = point.xy if emitter_type == 3 else p_position
|
||||
|
||||
emitter_direction = line_direction if emitter_type == 1 else emitter_direction
|
||||
emitter_direction = circle_direction if emitter_type == 2 else emitter_direction
|
||||
emitter_direction = cloud_direction if emitter_type == 3 else emitter_direction
|
||||
|
||||
# offset start position by random offset
|
||||
unit_rand = rotate_vec2(float2(1.0, 0.0), uniform_ab(0.0, 1.0), float2(0.0, 0.0))
|
||||
pos_offset = uniform_ab(0.0, offset_random)
|
||||
p_position = p_position + unit_rand @ pos_offset
|
||||
|
||||
# inititalize parameters
|
||||
{{ ps.init_parameter_random("mass", 0, false, true) }}
|
||||
{{ ps.init_parameter_random("drag", 1, false, true) }}
|
||||
{{ ps.init_parameter_random("color", 2, false, true) }}
|
||||
{{ ps.init_parameter_var("ang_velocity", 3) }}
|
||||
{{ ps.init_parameter_random("size", 4, false, true) }}
|
||||
{{ ps.init_parameter_var("orientation", 5, true) }}
|
||||
{{ ps.init_parameter_random("masking", 6) }}
|
||||
|
||||
{{ ps.init_parameter_var("direction_angle", -1, false, true) }}
|
||||
{{ ps.init_parameter_random("velocity", -1, false, true) }}
|
||||
|
||||
|
||||
p_direction_angle = p_direction_angle + emitter_direction if inherit_direction else p_direction_angle
|
||||
p_color = p_color * point_attrib.y if emitter_type == 3 else p_color
|
||||
p_size = p_size * point_attrib.x if emitter_type == 3 else p_size
|
||||
|
||||
p_mass = p_mass * p_size if mass_mult == 1 else p_mass
|
||||
p_mass = p_mass * p_size * p_size if mass_mult == 1 else p_mass
|
||||
|
||||
p_drag = p_drag * p_size if drag_mult == 1 else p_drag
|
||||
p_drag = p_drag * p_size * p_size if drag_mult == 1 else p_drag
|
||||
|
||||
export(p_mass)
|
||||
export(p_drag)
|
||||
export(p_color)
|
||||
export(p_direction_angle)
|
||||
export(p_size)
|
||||
|
||||
p_velocity_vec = vector2(-1.0, 0.0) @ (p_velocity * 0.001)
|
||||
p_velocity_vec = rotate_vec2(p_velocity_vec, -p_direction_angle, float2(0.0, 0.0))
|
||||
|
||||
:: if pcloud_write
|
||||
n = get_float("$number")
|
||||
particle_index = toint(n)
|
||||
_OUT_ = p_lifetime if particle_index < get_int("total_particles") else 1
|
||||
export(particle_index)
|
||||
:: else
|
||||
_OUT_ = p_lifetime
|
||||
:: endif
|
||||
|
||||
export(stop_simulation)
|
||||
export(p_lifetime)
|
||||
export(p_velocity_vec)
|
||||
export(p_position)
|
||||
@@ -0,0 +1,175 @@
|
||||
:: import "particle_system.sex" as ps
|
||||
|
||||
declare_inputs("particle_system")
|
||||
|
||||
n = get_float("$number")
|
||||
ni = toint(n)
|
||||
lifetime = get_int("p_lifetime")
|
||||
lifetime = tofloat(lifetime)
|
||||
glob_lifetime = get_int("lifetime")
|
||||
step_limit = tofloat(glob_lifetime) * particle_step
|
||||
step_limit = toint(step_limit)
|
||||
|
||||
|
||||
total_lifetime = (lifetime - 1.0) if lifetime > 1.0 else 0.0
|
||||
itotal_lifetime = toint(total_lifetime)
|
||||
|
||||
:: if pcloud_write
|
||||
cloud_index = get_int("cloud_index")
|
||||
particle_index = get_int("particle_index")
|
||||
:: endif
|
||||
|
||||
norm_life = n / total_lifetime
|
||||
|
||||
p_velocity_vec = get_float2("p_velocity_vec")
|
||||
gravity_vec = get_float2("gravity_vec")
|
||||
p_position = get_float2("p_position")
|
||||
p_size = get_float("p_size")
|
||||
p_color = get_float("p_color")
|
||||
p_mass = get_float("p_mass")
|
||||
p_drag = get_float("p_drag")
|
||||
p_orientation = get_float("p_orientation")
|
||||
p_ang_velocity = get_float("p_ang_velocity")
|
||||
p_masking = get_float("p_masking")
|
||||
stop_simulation = get_int("stop_simulation")
|
||||
|
||||
{{ ps.calculate_modifier_sample() }}
|
||||
|
||||
{{ ps.apply_modifiers("mass", 0) }}
|
||||
{{ ps.apply_modifiers("drag", 1) }}
|
||||
{{ ps.apply_modifiers("color", 2) }}
|
||||
{{ ps.apply_modifiers("ang_velocity", 3) }}
|
||||
{{ ps.apply_modifiers("size", 4) }}
|
||||
{{ ps.apply_modifiers("orientation", 5, true) }}
|
||||
{{ ps.apply_modifiers("masking", 6) }}
|
||||
|
||||
# calculate velocity coeffs
|
||||
#p_velocity_vec = rotate_vec2(p_velocity_vec, p_ang_velocity * 0.001, float2(0.0, 0.0))
|
||||
p_velocity_norm = normalize_vec2(p_velocity_vec)
|
||||
p_direction = atan2(p_velocity_vec) / _2pi()
|
||||
p_v = length_vec2(p_velocity_vec)
|
||||
|
||||
# update position (excluding first frame)
|
||||
p_position = p_position + p_velocity_vec if n > 0.0 else p_position
|
||||
|
||||
# calculate forces
|
||||
force = samplecol(p_position, 8, 1)
|
||||
force = force.xy @ 2.0 - float2(1.0, 1.0) if use_force_map else float2(0.0, 0.0)
|
||||
force = float2(0.0, 0.0) if length_vec2(force) < 0.00001 else force
|
||||
|
||||
# drag force
|
||||
drag_force = p_velocity_norm @ (-1.0 * p_v * p_v * p_drag)
|
||||
force = force + drag_force
|
||||
|
||||
gravity_from_map = samplecol(p_position, 25, 1)
|
||||
gravity_from_map = gravity_from_map.xy @ 2.0 - float2(1.0, 1.0) if use_gravity_map else float2(0.0, 0.0)
|
||||
total_gravity = gravity_from_map @ gravity_scalar if use_gravity_map else gravity_vec
|
||||
|
||||
# apply forces
|
||||
p_velocity_vec = p_velocity_vec + force @ ( 1.0 / p_mass) + total_gravity
|
||||
|
||||
# clamp velocity
|
||||
max_velocity = max_velocity * 0.001
|
||||
p_velocity_norm = normalize_vec2(p_velocity_vec)
|
||||
p_v = length_vec2(p_velocity_vec)
|
||||
p_v = p_v if p_v < max_velocity else max_velocity
|
||||
p_velocity_vec = p_velocity_vec + p_velocity_norm @ p_v - p_velocity_vec if clamp_velocity else p_velocity_vec
|
||||
|
||||
p_velocity_vec = rotate_vec2(p_velocity_vec, p_ang_velocity * 0.001, float2(0.0, 0.0))
|
||||
|
||||
p_size_out = vector2(p_size, p_size)
|
||||
|
||||
stop_mask = samplelum(p_position, 24, 0)
|
||||
stop_simulation = stop_simulation + 1 if stop_mask > stop_threshold and stop_sim_at_black else stop_simulation
|
||||
simulation_halted = stop_simulation > 1
|
||||
simulation_halted = True if stop_simulation > 0 and ni == 0 else simulation_halted
|
||||
|
||||
masked = uniform_ab(0.0, 1.0) > p_masking
|
||||
masked = False if output_mode == 1 else masked
|
||||
|
||||
p_color = 0.0 if masked else p_color
|
||||
p_color = 0.0 if output_mode == 0 and ni > step_limit else p_color
|
||||
p_color = 0.0 if ni % trail_quantize > 0 and not output_mode == 1 else p_color
|
||||
|
||||
color_before_trim = p_color
|
||||
|
||||
last_integration = (ni == itotal_lifetime)
|
||||
last_step = ((ni + 1) > step_limit and ni <= step_limit) or (itotal_lifetime <= step_limit and last_integration )
|
||||
simulation_first_stop = stop_simulation == 1 and ni <= step_limit
|
||||
last_step = simulation_first_stop or (last_step and stop_simulation < 1)
|
||||
|
||||
:: if not pcloud_write
|
||||
p_color = 0.0 if simulation_halted else p_color
|
||||
p_color = 0.0 if output_mode == 1 and not last_step else p_color
|
||||
:: endif
|
||||
|
||||
p_orientation_out = p_orientation + p_direction if velocity_orient else p_orientation
|
||||
|
||||
# write simulation to pcloud
|
||||
|
||||
:: if pcloud_write
|
||||
|
||||
cloud_img_size = get_int2("cloud_img_size")
|
||||
fsize = get_float2("fsize")
|
||||
out_fragment_size = get_float2("out_fragment_size")
|
||||
|
||||
p_orientation_out = 0.0
|
||||
|
||||
# current frame
|
||||
cloud_masked = uniform_ab(0.0, 1.0) < pc_mask
|
||||
cloud_mask_sample = modifier_sample if point_cloud_type == 1 else modifier_sample_global
|
||||
cloud_mask = samplelum(cloud_mask_sample, 25, 0)
|
||||
cloud_masked = cloud_masked or uniform_ab(0.0, 1.0) >= cloud_mask
|
||||
|
||||
write_to_cloud = True
|
||||
write_to_cloud = write_to_cloud and not cloud_masked
|
||||
pcloud_quant = True if last_step else ni % pcloud_quantize == 0
|
||||
write_to_cloud = write_to_cloud and pcloud_quant
|
||||
write_to_cloud = write_to_cloud and not simulation_halted
|
||||
|
||||
# check capacity
|
||||
write_to_cloud = write_to_cloud and cloud_index <= (cloud_img_size.a * cloud_img_size.b / 2 - 1)
|
||||
alpha = 1.0 if write_to_cloud else 0.0
|
||||
pos_color = merge_float4(p_position.x, p_position.y, p_direction + 0.5, alpha)
|
||||
p_flag = 1.0 if last_step else 0.0
|
||||
p_flag = 2.0 if last_step and stop_simulation > 0 else p_flag
|
||||
p_attribs = merge_float4(p_size, color_before_trim, p_flag, alpha)
|
||||
|
||||
output_row = tofloat((cloud_index * 2) / cloud_img_size.a)
|
||||
output_column = tofloat((cloud_index * 2) % cloud_img_size.a)
|
||||
|
||||
fcloud_index = tofloat(cloud_index)
|
||||
write_index = (particle_index == get_int("total_particles"))
|
||||
|
||||
p_size_out = out_fragment_size
|
||||
p_position_out = out_fragment_size / float2(2.0, 2.0) + vector2(output_column, output_row) / (fsize - float2(1.0, 1.0)) * (float2(1.0, 1.0) - out_fragment_size)
|
||||
|
||||
#pos_color = merge_float4(0.5, 0.5, 0.0, alpha)
|
||||
p_color_out = merge_float4(fcloud_index, fsize.x, fsize.y, 1.0) if write_index else pos_color
|
||||
p_position_out = float2(1.0, 1.0) - out_fragment_size / float2(2.0, 2.0) if write_index else p_position_out
|
||||
|
||||
cloud_index = cloud_index + 1 if write_to_cloud else cloud_index
|
||||
|
||||
export(p_attribs)
|
||||
export(p_color_out)
|
||||
export(cloud_index)
|
||||
|
||||
_OUT_ = 1 if write_index else 2
|
||||
|
||||
:: else
|
||||
|
||||
p_position_out = p_position
|
||||
p_color_out = merge_float4(p_color, p_color, p_color, p_color)
|
||||
export(p_color_out)
|
||||
|
||||
_OUT_ = 0 if simulation_halted else 1
|
||||
|
||||
:: endif
|
||||
|
||||
stop_simulation = stop_simulation + 1 if stop_mask > stop_threshold and stop_sim_at_black else stop_simulation
|
||||
export(stop_simulation)
|
||||
export(p_size_out)
|
||||
export(p_orientation_out)
|
||||
export(p_position)
|
||||
export(p_position_out)
|
||||
export(p_velocity_vec)
|
||||
Reference in New Issue
Block a user