diff --git a/3d/particles/README.md b/3d/particles/README.md new file mode 100644 index 00000000..b8891eaa --- /dev/null +++ b/3d/particles/README.md @@ -0,0 +1,12 @@ +# 3D Particles + +This project showcases various 3D particle features supported by Godot, for both GPU-based and CPU-based particles. +This includes particle collision, attractors, trails and subemitters. + +Language: GDScript + +Renderer: Vulkan Clustered + +## Screenshots + +![Screenshot](screenshots/3d_particles.png) diff --git a/3d/particles/checker.LICENSE.md b/3d/particles/checker.LICENSE.md new file mode 100644 index 00000000..a7a1e0be --- /dev/null +++ b/3d/particles/checker.LICENSE.md @@ -0,0 +1,7 @@ +# License for `checker.png` + +Copyright (c) 2020 Kenney + +Licensed under CC0 1.0 Universal. + +Downloaded from https://kenney.nl/assets/prototype-textures diff --git a/3d/particles/checker.png b/3d/particles/checker.png new file mode 100644 index 00000000..374a5d06 Binary files /dev/null and b/3d/particles/checker.png differ diff --git a/3d/particles/checker.png.import b/3d/particles/checker.png.import new file mode 100644 index 00000000..f29fbd84 --- /dev/null +++ b/3d/particles/checker.png.import @@ -0,0 +1,36 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://chjqieyps5n5r" +path.s3tc="res://.godot/imported/checker.png-6bb199bedbd039461e4248c1d0b9691d.s3tc.ctex" +path.etc2="res://.godot/imported/checker.png-6bb199bedbd039461e4248c1d0b9691d.etc2.ctex" +metadata={ +"imported_formats": ["s3tc", "etc2"], +"vram_texture": true +} + +[deps] + +source_file="res://checker.png" +dest_files=["res://.godot/imported/checker.png-6bb199bedbd039461e4248c1d0b9691d.s3tc.ctex", "res://.godot/imported/checker.png-6bb199bedbd039461e4248c1d0b9691d.etc2.ctex"] + +[params] + +compress/mode=2 +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/bptc_ldr=0 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/3d/particles/default_env.tres b/3d/particles/default_env.tres new file mode 100644 index 00000000..ddf6bb74 --- /dev/null +++ b/3d/particles/default_env.tres @@ -0,0 +1,7 @@ +[gd_resource type="Environment" load_steps=2 format=2] + +[sub_resource type="Sky" id=1] + +[resource] +background_mode = 2 +sky = SubResource( 1 ) diff --git a/3d/particles/icon.png b/3d/particles/icon.png new file mode 100644 index 00000000..3502a4a0 Binary files /dev/null and b/3d/particles/icon.png differ diff --git a/3d/particles/icon.png.import b/3d/particles/icon.png.import new file mode 100644 index 00000000..22dbec23 --- /dev/null +++ b/3d/particles/icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ejq6pclcuglh" +path="res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=["res://.godot/imported/icon.png-487276ed1e3a0c39cad0279d744ee560.ctex"] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/bptc_ldr=0 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/3d/particles/kenney/smoke_05.png b/3d/particles/kenney/smoke_05.png new file mode 100644 index 00000000..0ac46dcf Binary files /dev/null and b/3d/particles/kenney/smoke_05.png differ diff --git a/3d/particles/kenney/smoke_05.png.import b/3d/particles/kenney/smoke_05.png.import new file mode 100644 index 00000000..4eda9911 --- /dev/null +++ b/3d/particles/kenney/smoke_05.png.import @@ -0,0 +1,36 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://ddp8ek6rswwmc" +path.s3tc="res://.godot/imported/smoke_05.png-7e246e30a4b7ed8644556ad9ae88f0d2.s3tc.ctex" +path.etc2="res://.godot/imported/smoke_05.png-7e246e30a4b7ed8644556ad9ae88f0d2.etc2.ctex" +metadata={ +"imported_formats": ["s3tc", "etc2"], +"vram_texture": true +} + +[deps] + +source_file="res://kenney/smoke_05.png" +dest_files=["res://.godot/imported/smoke_05.png-7e246e30a4b7ed8644556ad9ae88f0d2.s3tc.ctex", "res://.godot/imported/smoke_05.png-7e246e30a4b7ed8644556ad9ae88f0d2.etc2.ctex"] + +[params] + +compress/mode=2 +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/bptc_ldr=0 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=true +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=0 diff --git a/3d/particles/project.godot b/3d/particles/project.godot new file mode 100644 index 00000000..540fdd6b --- /dev/null +++ b/3d/particles/project.godot @@ -0,0 +1,31 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +_global_script_classes=[] +_global_script_class_icons={} + +[application] + +config/name="3D Particles" +config/description="This project showcases various 3D particle features supported by Godot, for both GPU-based and CPU-based particles." +run/main_scene="res://test.tscn" +config/features=PackedStringArray("4.0") +config/icon="res://icon.png" + +[display] + +window/stretch/mode="canvas_items" +window/stretch/aspect="expand" + +[rendering] + +textures/default_filters/anisotropic_filtering_level=4 +quality/screen_filters/msaa=3 +environment/default_environment="res://default_env.tres" diff --git a/3d/particles/screenshots/.gdignore b/3d/particles/screenshots/.gdignore new file mode 100644 index 00000000..e69de29b diff --git a/3d/particles/screenshots/3d_particles.png b/3d/particles/screenshots/3d_particles.png new file mode 100644 index 00000000..4485f419 Binary files /dev/null and b/3d/particles/screenshots/3d_particles.png differ diff --git a/3d/particles/test.GPUParticlesCollisionSDF3D_data.exr b/3d/particles/test.GPUParticlesCollisionSDF3D_data.exr new file mode 100644 index 00000000..b82fb06c Binary files /dev/null and b/3d/particles/test.GPUParticlesCollisionSDF3D_data.exr differ diff --git a/3d/particles/test.GPUParticlesCollisionSDF3D_data.exr.import b/3d/particles/test.GPUParticlesCollisionSDF3D_data.exr.import new file mode 100644 index 00000000..11ed4c2b --- /dev/null +++ b/3d/particles/test.GPUParticlesCollisionSDF3D_data.exr.import @@ -0,0 +1,26 @@ +[remap] + +importer="3d_texture" +type="CompressedTexture3D" +uid="uid://dgnb433rl8hr1" +path="res://.godot/imported/test.GPUParticlesCollisionSDF3D_data.exr-29a2410593f1eebabf1e1d8c3f3a6320.ctex3d" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://test.GPUParticlesCollisionSDF3D_data.exr" +dest_files=["res://.godot/imported/test.GPUParticlesCollisionSDF3D_data.exr-29a2410593f1eebabf1e1d8c3f3a6320.ctex3d"] + +[params] + +compress/mode=3 +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/bptc_ldr=0 +compress/channel_pack=1 +mipmaps/generate=false +mipmaps/limit=-1 +slices/horizontal=1 +slices/vertical=64 diff --git a/3d/particles/test.tscn b/3d/particles/test.tscn new file mode 100644 index 00000000..e4c0c3d1 --- /dev/null +++ b/3d/particles/test.tscn @@ -0,0 +1,969 @@ +[gd_scene load_steps=77 format=3 uid="uid://bo5sv4e5gv8rc"] + +[ext_resource type="Texture2D" uid="uid://ddp8ek6rswwmc" path="res://kenney/smoke_05.png" id="3_pmhp8"] +[ext_resource type="CompressedTexture3D" uid="uid://dgnb433rl8hr1" path="res://test.GPUParticlesCollisionSDF3D_data.exr" id="4_wcrow"] +[ext_resource type="Texture2D" uid="uid://chjqieyps5n5r" path="res://checker.png" id="14"] +[ext_resource type="Script" path="res://tester.gd" id="18"] + +[sub_resource type="ProceduralSkyMaterial" id="9"] + +[sub_resource type="Sky" id="10"] +sky_material = SubResource("9") + +[sub_resource type="Environment" id="11"] +background_mode = 2 +sky = SubResource("10") + +[sub_resource type="Animation" id="Animation_qdnt6"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Testers/GPUParticlesCollisionGlobalCoords/GPUParticles3D:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1.2, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Testers/GPUParticlesCollision/MovingBox:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, -0.45, -0.5)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Testers/GPUParticlesCollisionGlobalCoords/MovingBox:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, -0.45, -0.5)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Testers/CPUParticlesForceField/CPUParticles3D:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 1, 0)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Testers/CPUParticlesForceField/CPUParticles3D:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="12"] +resource_name = "move" +length = 4.0 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Testers/GPUParticlesCollisionGlobalCoords/GPUParticles3D:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 2), +"transitions": PackedFloat32Array(-2, -2), +"update": 0, +"values": [Vector3(0, 1.2, 0), Vector3(0, 4.2, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Testers/GPUParticlesCollision/MovingBox:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 2), +"transitions": PackedFloat32Array(-2, -2), +"update": 0, +"values": [Vector3(0, -0.45, -0.5), Vector3(0, 0.65, -0.5)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Testers/GPUParticlesCollisionGlobalCoords/MovingBox:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 2), +"transitions": PackedFloat32Array(-2, -2), +"update": 0, +"values": [Vector3(0, -0.45, -0.5), Vector3(0, 0.65, -0.5)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Testers/CPUParticlesForceField/CPUParticles3D:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 2), +"transitions": PackedFloat32Array(-2, -2), +"update": 0, +"values": [Vector3(0, 1, 0), Vector3(0, 0, 0)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Testers/CPUParticlesForceField/CPUParticles3D:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 2, 4), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, 3.14159, 0), Vector3(0, 6.28319, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_ecfcr"] +_data = { +"RESET": SubResource("Animation_qdnt6"), +"move": SubResource("12") +} + +[sub_resource type="StandardMaterial3D" id="13"] +diffuse_mode = 1 +albedo_texture = ExtResource("14") +uv1_scale = Vector3(32, 32, 1) +texture_filter = 5 + +[sub_resource type="PlaneMesh" id="14"] +material = SubResource("13") +size = Vector2(128, 128) + +[sub_resource type="Gradient" id="Gradient_ywyk1"] +interpolation_mode = 2 +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture2D" id="GradientTexture2D_4rekb"] +gradient = SubResource("Gradient_ywyk1") +fill = 1 +fill_from = Vector2(0.5, 0.5) +fill_to = Vector2(0.5, 0.01) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ls6ob"] +transparency = 1 +shading_mode = 0 +vertex_color_use_as_albedo = true +albedo_color = Color(1, 2, 3, 0.7) +albedo_texture = SubResource("GradientTexture2D_4rekb") +billboard_mode = 3 +particles_anim_h_frames = 1 +particles_anim_v_frames = 1 +particles_anim_loop = false +proximity_fade_enabled = true +proximity_fade_distance = 2.0 + +[sub_resource type="QuadMesh" id="QuadMesh_7ay8c"] +material = SubResource("StandardMaterial3D_ls6ob") +size = Vector2(0.1, 0.1) + +[sub_resource type="Gradient" id="Gradient_drqcv"] +interpolation_mode = 2 +offsets = PackedFloat32Array(0, 0.289474, 0.542105, 1) +colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 0.92549, 0.235294, 0.317647, 1, 0.564706, 1, 1, 1, 0) + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cgumr"] +transparency = 1 +shading_mode = 0 +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("3_pmhp8") +billboard_mode = 3 +particles_anim_h_frames = 1 +particles_anim_v_frames = 1 +particles_anim_loop = false +proximity_fade_enabled = true +proximity_fade_distance = 0.5 + +[sub_resource type="QuadMesh" id="QuadMesh_0jly8"] +material = SubResource("StandardMaterial3D_cgumr") + +[sub_resource type="Gradient" id="Gradient_or8rt"] +interpolation_mode = 2 +offsets = PackedFloat32Array(0, 0.131579, 0.184211, 0.321053, 0.473684, 0.752632, 1) +colors = PackedColorArray(0.25098, 0.25098, 0.25098, 1, 1, 0.802991, 0.664426, 1, 1, 0.682353, 0, 1, 1, 0.601, 0.37, 1, 1, 0.25, 0.1, 0.447059, 0, 0, 0, 0.184314, 0.25098, 0.25098, 0.25098, 0) + +[sub_resource type="Gradient" id="Gradient_827lf"] +interpolation_mode = 2 +offsets = PackedFloat32Array(0.01875, 0.0722892, 0.433735, 0.716867, 1) +colors = PackedColorArray(0, 0, 0, 1, 0.686275, 0.188235, 0, 1, 1, 0.517647, 0.0784314, 1, 1, 0.0784314, 0, 0.447059, 0.25098, 0.25098, 0.25098, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_2374g"] +gradient = SubResource("Gradient_827lf") + +[sub_resource type="Curve" id="Curve_3eqrx"] +_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="CurveTexture" id="CurveTexture_3g7oh"] +curve = SubResource("Curve_3eqrx") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_wcmum"] +emission_shape = 3 +emission_box_extents = Vector3(0.5, 0, 0.5) +direction = Vector3(0, 1, 0) +spread = 3.5 +gravity = Vector3(0, 0, 0) +initial_velocity_min = 1.0 +initial_velocity_max = 4.0 +angular_velocity_max = 360.0 +damping_min = 2.0 +damping_max = 2.0 +scale_min = 0.1 +scale_max = 0.8 +scale_curve = SubResource("CurveTexture_3g7oh") +color = Color(4, 4, 4, 1) +color_ramp = SubResource("GradientTexture1D_2374g") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_dod7h"] +transparency = 1 +shading_mode = 0 +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("3_pmhp8") +billboard_mode = 3 +particles_anim_h_frames = 1 +particles_anim_v_frames = 1 +particles_anim_loop = false +proximity_fade_enabled = true +proximity_fade_distance = 0.3 + +[sub_resource type="QuadMesh" id="QuadMesh_783ir"] +material = SubResource("StandardMaterial3D_dod7h") + +[sub_resource type="Gradient" id="Gradient_lgkn4"] +offsets = PackedFloat32Array(0, 0.542169, 1) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_l2iq7"] +gradient = SubResource("Gradient_lgkn4") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_a3ot6"] +direction = Vector3(0, 1, 0) +gravity = Vector3(0, -2, 0) +initial_velocity_min = 1.0 +initial_velocity_max = 2.0 +angular_velocity_max = 180.0 +tangential_accel_min = 3.0 +tangential_accel_max = 3.0 +color = Color(0.55, 0.55, 0.55, 1) +color_ramp = SubResource("GradientTexture1D_l2iq7") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_jtphw"] +transparency = 1 +shading_mode = 0 +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("3_pmhp8") +billboard_mode = 3 +particles_anim_h_frames = 1 +particles_anim_v_frames = 1 +particles_anim_loop = false +proximity_fade_enabled = true +proximity_fade_distance = 0.3 + +[sub_resource type="QuadMesh" id="QuadMesh_edvlt"] +material = SubResource("StandardMaterial3D_jtphw") + +[sub_resource type="Gradient" id="Gradient_6585v"] +interpolation_mode = 2 +offsets = PackedFloat32Array(0, 0.674699, 1) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_6ubl1"] +gradient = SubResource("Gradient_6585v") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_4noo4"] +direction = Vector3(0, 1, 0) +gravity = Vector3(0, 0, 0) +initial_velocity_min = 1.0 +initial_velocity_max = 1.0 +color_ramp = SubResource("GradientTexture1D_6ubl1") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_ft0gs"] +emission_shape = 6 +emission_ring_axis = Vector3(0, 1, 0) +emission_ring_height = 0.0 +emission_ring_radius = 0.25 +emission_ring_inner_radius = 0.25 +radial_accel_min = 2.0 +radial_accel_max = 2.0 +collision_mode = 1 +collision_friction = 0.1 +collision_bounce = 0.0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_r4xcu"] +albedo_color = Color(0.521569, 1, 0.776471, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_88317"] +material = SubResource("StandardMaterial3D_r4xcu") +size = Vector3(0.1, 0.1, 0.1) + +[sub_resource type="BoxMesh" id="BoxMesh_3dp4g"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3jlyg"] + +[sub_resource type="Gradient" id="Gradient_yv8jc"] +interpolation_mode = 2 +offsets = PackedFloat32Array(0, 0.0963855, 1) +colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 0.917647, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_bewgf"] +gradient = SubResource("Gradient_yv8jc") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_pe2at"] +emission_shape = 6 +emission_ring_axis = Vector3(0, 1, 0) +emission_ring_height = 0.0 +emission_ring_radius = 1.6 +emission_ring_inner_radius = 0.0 +gravity = Vector3(0, 1, 0) +color = Color(1, 1, 1, 0.25098) +color_ramp = SubResource("GradientTexture1D_bewgf") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_8mtil"] +transparency = 1 +shading_mode = 0 +vertex_color_use_as_albedo = true +proximity_fade_enabled = true +proximity_fade_distance = 0.5 + +[sub_resource type="SphereMesh" id="SphereMesh_rowu5"] +material = SubResource("StandardMaterial3D_8mtil") +radius = 0.4 +height = 0.4 +radial_segments = 16 +rings = 16 + +[sub_resource type="Gradient" id="Gradient_eedjr"] +interpolation_mode = 1 +offsets = PackedFloat32Array(0.25974, 0.376623, 0.948052) +colors = PackedColorArray(1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_0pfio"] +gradient = SubResource("Gradient_eedjr") + +[sub_resource type="Gradient" id="Gradient_nwe6x"] +offsets = PackedFloat32Array(0, 0.168831, 1) +colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_wmonn"] +gradient = SubResource("Gradient_nwe6x") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_bwh6l"] +emission_shape = 3 +emission_box_extents = Vector3(1, 0, 1) +direction = Vector3(0, 1, 0) +spread = 15.0 +initial_velocity_min = 6.0 +initial_velocity_max = 6.0 +radial_accel_min = -2.0 +radial_accel_max = -2.0 +tangential_accel_min = 1.0 +tangential_accel_max = 4.0 +damping_min = 4.0 +damping_max = 4.0 +scale_max = 3.0 +color_ramp = SubResource("GradientTexture1D_wmonn") +color_initial_ramp = SubResource("GradientTexture1D_0pfio") +collision_mode = 1 +collision_friction = 0.0 +collision_bounce = 0.25 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_asab0"] +transparency = 1 +shading_mode = 0 +vertex_color_use_as_albedo = true +use_particle_trails = true + +[sub_resource type="TubeTrailMesh" id="TubeTrailMesh_slq55"] +material = SubResource("StandardMaterial3D_asab0") +radius = 0.02 +radial_steps = 3 + +[sub_resource type="Gradient" id="Gradient_kdfrx"] +offsets = PackedFloat32Array(0, 0.777108, 1) +colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1, 1, 0.320511, 0, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_3jc0t"] +gradient = SubResource("Gradient_kdfrx") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_87mxs"] +emission_shape = 3 +emission_box_extents = Vector3(1, 1, 1) +direction = Vector3(0, 1, 0) +gravity = Vector3(0, 0, 0) +initial_velocity_min = 1.0 +initial_velocity_max = 1.0 +color_ramp = SubResource("GradientTexture1D_3jc0t") +sub_emitter_mode = 2 +sub_emitter_amount_at_end = 1 +sub_emitter_keep_velocity = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_22a4e"] +transparency = 1 +vertex_color_use_as_albedo = true + +[sub_resource type="BoxMesh" id="BoxMesh_olbrk"] +material = SubResource("StandardMaterial3D_22a4e") +size = Vector3(0.2, 0.2, 0.2) + +[sub_resource type="Curve" id="Curve_hqf7t"] +_data = [Vector2(0.7, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="CurveTexture" id="CurveTexture_d6opd"] +curve = SubResource("Curve_hqf7t") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_tvato"] +gravity = Vector3(0, -5, 0) +scale_curve = SubResource("CurveTexture_d6opd") +collision_mode = 1 +collision_friction = 0.0 +collision_bounce = 0.0 +collision_use_scale = true + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_gxbts"] +metallic = 1.0 +roughness = 0.5 + +[sub_resource type="SphereMesh" id="SphereMesh_g7qur"] +material = SubResource("StandardMaterial3D_gxbts") +radius = 0.1 +height = 0.2 +radial_segments = 16 +rings = 8 + +[sub_resource type="Gradient" id="Gradient_snt4t"] +offsets = PackedFloat32Array(0, 0.987952) +colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_ppbqr"] +gradient = SubResource("Gradient_snt4t") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_b7k7i"] +emission_shape = 3 +emission_box_extents = Vector3(1, 1, 1) +direction = Vector3(0, 1, 0) +initial_velocity_min = 1.0 +initial_velocity_max = 1.0 +color = Color(0.568627, 0.313726, 1, 1) +color_ramp = SubResource("GradientTexture1D_ppbqr") +sub_emitter_mode = 3 +sub_emitter_amount_at_collision = 1 +sub_emitter_keep_velocity = true +collision_mode = 2 + +[sub_resource type="Curve" id="Curve_7mapm"] +_data = [Vector2(0.7, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 2 + +[sub_resource type="CurveTexture" id="CurveTexture_tkl18"] +curve = SubResource("Curve_7mapm") + +[sub_resource type="ParticleProcessMaterial" id="ParticlesMaterial_6htaw"] +gravity = Vector3(0, -5, 0) +scale_curve = SubResource("CurveTexture_tkl18") +collision_mode = 1 +collision_friction = 0.0 +collision_bounce = 0.0 +collision_use_scale = true + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_4f0te"] +emission_shape = 3 +emission_box_extents = Vector3(1, 0, 1) +radial_accel_min = 2.0 +radial_accel_max = 2.0 +collision_mode = 1 +collision_friction = 0.0 +collision_bounce = 0.5 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_xlsok"] +emission_enabled = true +emission = Color(0.25098, 0.568627, 0.882353, 1) +emission_energy_multiplier = 2.0 + +[sub_resource type="SphereMesh" id="SphereMesh_whk10"] +material = SubResource("StandardMaterial3D_xlsok") +radius = 0.025 +height = 0.05 +radial_segments = 8 +rings = 4 + +[sub_resource type="Curve" id="Curve_dnt4m"] +_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(0.2, 0.5), 0.0, 0.0, 0, 0, Vector2(0.5, 0.8), 0.0, 0.0, 0, 0, Vector2(0.8, 0.5), 0.0, 0.0, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0] +point_count = 5 + +[sub_resource type="TubeTrailMesh" id="TubeTrailMesh_rusnm"] +radius = 1.0 +radial_steps = 64 +sections = 15 +curve = SubResource("Curve_dnt4m") + +[sub_resource type="BoxMesh" id="BoxMesh_frpx7"] +size = Vector3(1, 0.1, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_dcd5l"] +size = Vector3(4, 0.1, 4) + +[sub_resource type="SphereMesh" id="SphereMesh_8xbmh"] +material = SubResource("StandardMaterial3D_xlsok") +radius = 0.025 +height = 0.05 +radial_segments = 8 +rings = 4 + +[node name="WorldEnvironment" type="WorldEnvironment"] +environment = SubResource("11") +script = ExtResource("18") + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +autoplay = "move" +libraries = { +"": SubResource("AnimationLibrary_ecfcr") +} + +[node name="Plane" type="MeshInstance3D" parent="."] +layers = 2 +mesh = SubResource("14") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.909487, -0.23874, 0.340349, 0, 0.818672, 0.574262, -0.415733, -0.522284, 0.744571, 3.9506, 3.39961, 3.54442) +shadow_enabled = true +shadow_bias = 0.04 +directional_shadow_mode = 0 +directional_shadow_fade_start = 1.0 +directional_shadow_max_distance = 12.0 + +[node name="CameraHolder" type="Node3D" parent="."] +transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, 0.125, 26) + +[node name="RotationX" type="Node3D" parent="CameraHolder"] + +[node name="Camera3D" type="Camera3D" parent="CameraHolder/RotationX"] +fov = 70.0 + +[node name="Testers" type="Node3D" parent="."] + +[node name="CPUParticlesForceField" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 26) + +[node name="CPUParticles3D" type="CPUParticles3D" parent="Testers/CPUParticlesForceField"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +amount = 750 +lifetime = 5.0 +preprocess = 5.0 +mesh = SubResource("QuadMesh_7ay8c") +emission_shape = 3 +emission_box_extents = Vector3(0.05, 1, 1) +gravity = Vector3(0, 0.05, 0) +tangential_accel_min = -0.04 +tangential_accel_max = 0.04 +scale_amount_min = 0.1 +scale_amount_max = 1.5 +color_ramp = SubResource("Gradient_drqcv") + +[node name="CPUParticlesExplosion" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 22) + +[node name="CPUParticles3D" type="CPUParticles3D" parent="Testers/CPUParticlesExplosion"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +amount = 400 +lifetime = 1.3 +explosiveness = 1.0 +mesh = SubResource("QuadMesh_0jly8") +emission_shape = 2 +emission_sphere_radius = 0.25 +spread = 180.0 +gravity = Vector3(0, 0, 0) +initial_velocity_min = 4.0 +initial_velocity_max = 4.0 +angular_velocity_max = 720.0 +damping_min = 3.25 +damping_max = 3.25 +angle_max = 360.0 +scale_amount_min = 0.0 +color = Color(4, 4, 4, 1) +color_ramp = SubResource("Gradient_or8rt") + +[node name="Decal4" type="Decal" parent="Testers/CPUParticlesExplosion"] +extents = Vector3(2.5, 0.01, 2.5) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="Decal5" type="Decal" parent="Testers/CPUParticlesExplosion"] +transform = Transform3D(0.562646, 0, -0.826698, 0, 1, 0, 0.826698, 0, 0.562646, 0, 0, 0) +extents = Vector3(2.5, 0.01, 2.5) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="Decal6" type="Decal" parent="Testers/CPUParticlesExplosion"] +transform = Transform3D(-0.481494, 0, -0.87645, 0, 1, 0, 0.87645, 0, -0.481494, 0, 0, 0) +extents = Vector3(2.5, 0.01, 2.5) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="GPUParticlesFire" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 18) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesFire"] +amount = 125 +fixed_fps = 0 +interpolate = false +process_material = SubResource("ParticlesMaterial_wcmum") +draw_pass_1 = SubResource("QuadMesh_783ir") + +[node name="Decal" type="Decal" parent="Testers/GPUParticlesFire"] +extents = Vector3(1, 0.01, 1) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="Decal2" type="Decal" parent="Testers/GPUParticlesFire"] +transform = Transform3D(0.562646, 0, -0.826698, 0, 1, 0, 0.826698, 0, 0.562646, 0, 0, 0) +extents = Vector3(1.5, 0.01, 1.1) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="Decal3" type="Decal" parent="Testers/GPUParticlesFire"] +transform = Transform3D(-0.481494, 0, -0.87645, 0, 1, 0, 0.87645, 0, -0.481494, 0, 0, 0) +extents = Vector3(1.6, 0.01, 1.3) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="GPUParticlesSmoke" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 14) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesSmoke"] +amount = 100 +lifetime = 1.5 +fixed_fps = 0 +interpolate = false +draw_order = 1 +process_material = SubResource("ParticlesMaterial_a3ot6") +draw_pass_1 = SubResource("QuadMesh_edvlt") + +[node name="Decal4" type="Decal" parent="Testers/GPUParticlesSmoke"] +extents = Vector3(1, 0.01, 1) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="Decal5" type="Decal" parent="Testers/GPUParticlesSmoke"] +transform = Transform3D(0.562646, 0, -0.826698, 0, 1, 0, 0.826698, 0, 0.562646, 0, 0, 0) +extents = Vector3(1.5, 0.01, 1.1) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="Decal6" type="Decal" parent="Testers/GPUParticlesSmoke"] +transform = Transform3D(-0.481494, 0, -0.87645, 0, 1, 0, 0.87645, 0, -0.481494, 0, 0, 0) +extents = Vector3(1.6, 0.01, 1.3) +texture_albedo = ExtResource("3_pmhp8") +modulate = Color(0, 0, 0, 1) + +[node name="GPUParticlesAttractor" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 10) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesAttractor"] +amount = 300 +lifetime = 5.0 +fixed_fps = 0 +interpolate = false +process_material = SubResource("ParticlesMaterial_4noo4") +draw_pass_1 = SubResource("QuadMesh_7ay8c") + +[node name="GPUParticlesAttractorSphere3D" type="GPUParticlesAttractorSphere3D" parent="Testers/GPUParticlesAttractor"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 1, 0) +strength = 50.0 +radius = 2.0 + +[node name="GPUParticlesCollision" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 6) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesCollision"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0) +amount = 50 +lifetime = 2.0 +fixed_fps = 0 +interpolate = false +collision_base_size = 0.05 +visibility_aabb = AABB(-1.63511, -1.25001, -1.31512, 3.0892, 2.15487, 2.91765) +process_material = SubResource("ParticlesMaterial_ft0gs") +draw_pass_1 = SubResource("BoxMesh_88317") + +[node name="GPUParticlesCollisionBox3D" type="GPUParticlesCollisionBox3D" parent="Testers/GPUParticlesCollision"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) +extents = Vector3(2, 1, 2) + +[node name="MovingBox" type="MeshInstance3D" parent="Testers/GPUParticlesCollision"] +transform = Transform3D(0.707107, 0, -0.707107, 0, 1, 0, 0.707107, 0, 0.707107, 0, -0.45, -0.5) +mesh = SubResource("BoxMesh_3dp4g") +skeleton = NodePath("../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_3jlyg") + +[node name="GPUParticlesCollisionBox3D" type="GPUParticlesCollisionBox3D" parent="Testers/GPUParticlesCollision/MovingBox"] +extents = Vector3(0.5, 0.5, 0.5) + +[node name="GPUParticlesCollisionGlobalCoords" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesCollisionGlobalCoords"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0) +extra_cull_margin = 3.0 +amount = 50 +lifetime = 2.0 +fixed_fps = 0 +interpolate = false +collision_base_size = 0.05 +visibility_aabb = AABB(-1.50087, -1.25001, -1.4745, 3.19423, 2.13905, 3.02308) +process_material = SubResource("ParticlesMaterial_ft0gs") +draw_pass_1 = SubResource("BoxMesh_88317") + +[node name="GPUParticlesCollisionBox3D2" type="GPUParticlesCollisionBox3D" parent="Testers/GPUParticlesCollisionGlobalCoords"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) +extents = Vector3(2, 1, 2) + +[node name="MovingBox" type="MeshInstance3D" parent="Testers/GPUParticlesCollisionGlobalCoords"] +transform = Transform3D(0.707107, 0, -0.707107, 0, 1, 0, 0.707107, 0, 0.707107, 0, -0.45, -0.5) +mesh = SubResource("BoxMesh_3dp4g") +skeleton = NodePath("../../..") +surface_material_override/0 = SubResource("StandardMaterial3D_3jlyg") + +[node name="GPUParticlesCollisionBox3D" type="GPUParticlesCollisionBox3D" parent="Testers/GPUParticlesCollisionGlobalCoords/MovingBox"] +extents = Vector3(0.5, 0.5, 0.5) + +[node name="GPUParticles3DFoam" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -2) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticles3DFoam"] +amount = 200 +fixed_fps = 0 +interpolate = false +process_material = SubResource("ParticlesMaterial_pe2at") +draw_pass_1 = SubResource("SphereMesh_rowu5") + +[node name="GPUParticlesTrails" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -6) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesTrails"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0) +amount = 50 +lifetime = 2.0 +fixed_fps = 0 +interpolate = false +collision_base_size = 0.1 +trail_enabled = true +process_material = SubResource("ParticlesMaterial_bwh6l") +draw_passes = 2 +draw_pass_1 = SubResource("TubeTrailMesh_slq55") +draw_pass_2 = null + +[node name="GPUParticlesCollisionBox3D" type="GPUParticlesCollisionBox3D" parent="Testers/GPUParticlesTrails"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) +extents = Vector3(2, 1, 2) + +[node name="GPUParticlesSubemitterAtEnd" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -10) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesSubemitterAtEnd"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2, 0) +amount = 15 +sub_emitter = NodePath("Subemitter") +lifetime = 1.5 +fixed_fps = 0 +interpolate = false +process_material = SubResource("ParticlesMaterial_87mxs") +draw_pass_1 = SubResource("BoxMesh_olbrk") + +[node name="Subemitter" type="GPUParticles3D" parent="Testers/GPUParticlesSubemitterAtEnd/GPUParticles3D"] +emitting = false +amount = 15 +fixed_fps = 0 +interpolate = false +collision_base_size = 0.1 +process_material = SubResource("ParticlesMaterial_tvato") +draw_pass_1 = SubResource("SphereMesh_g7qur") + +[node name="GPUParticlesCollisionBox3D" type="GPUParticlesCollisionBox3D" parent="Testers/GPUParticlesSubemitterAtEnd"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) +extents = Vector3(2, 1, 2) + +[node name="GPUParticlesSubemitterOnCollision" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -14) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesSubemitterOnCollision"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.2, 0) +amount = 15 +sub_emitter = NodePath("Subemitter") +lifetime = 1.5 +fixed_fps = 0 +interpolate = false +collision_base_size = 0.1 +process_material = SubResource("ParticlesMaterial_b7k7i") +draw_pass_1 = SubResource("BoxMesh_olbrk") + +[node name="Subemitter" type="GPUParticles3D" parent="Testers/GPUParticlesSubemitterOnCollision/GPUParticles3D"] +emitting = false +amount = 150 +lifetime = 10.0 +fixed_fps = 0 +interpolate = false +collision_base_size = 0.1 +process_material = SubResource("ParticlesMaterial_6htaw") +draw_pass_1 = SubResource("SphereMesh_g7qur") + +[node name="GPUParticlesCollisionBox3D" type="GPUParticlesCollisionBox3D" parent="Testers/GPUParticlesSubemitterOnCollision"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) +extents = Vector3(2, 1, 2) + +[node name="GPUParticlesCollisionSDF" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -18) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesCollisionSDF"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0) +amount = 150 +lifetime = 1.5 +fixed_fps = 0 +interpolate = false +collision_base_size = 0.04 +visibility_aabb = AABB(-1.63511, -1.25001, -1.31512, 3.0892, 2.15487, 2.91765) +process_material = SubResource("ParticleProcessMaterial_4f0te") +draw_pass_1 = SubResource("SphereMesh_whk10") + +[node name="GPUParticlesCollisionSDF3D" type="GPUParticlesCollisionSDF3D" parent="Testers/GPUParticlesCollisionSDF"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +extents = Vector3(2, 0.5, 2) +texture = ExtResource("4_wcrow") + +[node name="Tube" type="MeshInstance3D" parent="Testers/GPUParticlesCollisionSDF"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0) +mesh = SubResource("TubeTrailMesh_rusnm") +skeleton = NodePath("../../GPUParticlesCollisionHeightfield") + +[node name="Roof" type="MeshInstance3D" parent="Testers/GPUParticlesCollisionSDF"] +transform = Transform3D(0.965926, -0.258819, 0, 0.258819, 0.965926, 0, 0, 0, 1, -1, 0.8, 0) +mesh = SubResource("BoxMesh_frpx7") +skeleton = NodePath("../../GPUParticlesCollisionHeightfield") + +[node name="Slope" type="MeshInstance3D" parent="Testers/GPUParticlesCollisionSDF"] +transform = Transform3D(-4.2222e-08, 1.13133e-08, -1, 0.866025, 0.5, -3.09086e-08, 0.5, -0.866025, -3.09086e-08, -1, 0.1, 0.599998) +mesh = SubResource("BoxMesh_frpx7") +skeleton = NodePath("../../GPUParticlesCollisionHeightfield") + +[node name="Slope2" type="MeshInstance3D" parent="Testers/GPUParticlesCollisionSDF"] +transform = Transform3D(-4.2222e-08, 1.13133e-08, 1, 0.5, 0.866026, 1.13133e-08, -0.866025, 0.5, -4.2222e-08, -1, 0.1, -0.400002) +mesh = SubResource("BoxMesh_frpx7") +skeleton = NodePath("../../GPUParticlesCollisionHeightfield") + +[node name="Floor" type="MeshInstance3D" parent="Testers/GPUParticlesCollisionSDF"] +mesh = SubResource("BoxMesh_dcd5l") +skeleton = NodePath("../../GPUParticlesCollisionHeightfield") + +[node name="GPUParticlesCollisionHeightfield" type="Node3D" parent="Testers"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -22) + +[node name="GPUParticles3D" type="GPUParticles3D" parent="Testers/GPUParticlesCollisionHeightfield"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.2, 0) +amount = 150 +lifetime = 1.5 +fixed_fps = 0 +interpolate = false +collision_base_size = 0.04 +visibility_aabb = AABB(-1.63511, -1.25001, -1.31512, 3.0892, 2.15487, 2.91765) +process_material = SubResource("ParticleProcessMaterial_4f0te") +draw_pass_1 = SubResource("SphereMesh_8xbmh") + +[node name="GPUParticlesCollisionHeightField3D" type="GPUParticlesCollisionHeightField3D" parent="Testers/GPUParticlesCollisionHeightfield"] +extents = Vector3(2, 1, 2) + +[node name="CSGBox3D" type="CSGBox3D" parent="Testers/GPUParticlesCollisionHeightfield"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +size = Vector3(3.5, 1, 3.5) + +[node name="CSGBox3D2" type="CSGBox3D" parent="Testers/GPUParticlesCollisionHeightfield/CSGBox3D"] +transform = Transform3D(1, 0, 0, 0, 0.996064, 0.0886335, 0, -0.0886335, 0.996064, 0, 0.92037, -0.361961) +operation = 2 +size = Vector3(4, 1, 4) + +[node name="CSGBox3D3" type="CSGBox3D" parent="Testers/GPUParticlesCollisionHeightfield/CSGBox3D"] +transform = Transform3D(0.638543, 0.331028, -0.694755, -0.177732, 0.94179, 0.285381, 0.748782, -0.0587477, 0.660207, 0.886086, 0.849547, 0.346458) +operation = 2 +size = Vector3(4, 1, 4) + +[node name="CSGBox3D4" type="CSGBox3D" parent="Testers/GPUParticlesCollisionHeightfield/CSGBox3D"] +transform = Transform3D(0.61798, -0.298242, -0.727428, 0.239637, 0.95268, -0.187014, 0.748782, -0.0587477, 0.660207, -0.249068, 0.868665, 0.346458) +operation = 2 +size = Vector3(4, 1, 4) + +[node name="CSGBox3D5" type="CSGBox3D" parent="Testers/GPUParticlesCollisionHeightfield/CSGBox3D"] +transform = Transform3D(0.453442, 0.771907, -0.44559, -0.483441, 0.633015, 0.604629, 0.748782, -0.0587477, 0.660207, -0.310878, 1.96879, 0.695173) +operation = 2 +size = Vector3(4, 1, 4) + +[node name="TestName" type="Label" parent="."] +anchors_preset = 7 +anchor_left = 0.5 +anchor_top = 1.0 +anchor_right = 0.5 +anchor_bottom = 1.0 +offset_left = -192.0 +offset_top = -58.0 +offset_right = 192.0 +offset_bottom = -24.0 +grow_horizontal = 2 +grow_vertical = 0 +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 5 +theme_override_font_sizes/font_size = 24 +horizontal_alignment = 1 + +[node name="Previous" type="Button" parent="."] +anchors_preset = 2 +anchor_top = 1.0 +anchor_bottom = 1.0 +offset_left = 24.0 +offset_top = -55.0 +offset_right = 135.0 +offset_bottom = -24.0 +grow_vertical = 0 +text = "« Previous" + +[node name="Next" type="Button" parent="."] +anchors_preset = 3 +anchor_left = 1.0 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -107.0 +offset_top = -55.0 +offset_right = -24.0 +offset_bottom = -24.0 +grow_horizontal = 0 +grow_vertical = 0 +text = "Next »" + +[connection signal="pressed" from="Previous" to="." method="_on_previous_pressed"] +[connection signal="pressed" from="Next" to="." method="_on_next_pressed"] diff --git a/3d/particles/tester.gd b/3d/particles/tester.gd new file mode 100644 index 00000000..842cc061 --- /dev/null +++ b/3d/particles/tester.gd @@ -0,0 +1,70 @@ +extends WorldEnvironment + +const ROT_SPEED = 0.003 +const ZOOM_SPEED = 0.125 +const MAIN_BUTTONS = MOUSE_BUTTON_MASK_LEFT | MOUSE_BUTTON_MASK_RIGHT | MOUSE_BUTTON_MASK_MIDDLE + +var tester_index = 0 +var rot_x = deg_to_rad(-22.5) # This must be kept in sync with RotationX. +var rot_y = deg_to_rad(90) # This must be kept in sync with CameraHolder. +var zoom = 2.5 +var base_height = ProjectSettings.get_setting("display/window/size/viewport_height") + +@onready var testers = $Testers +@onready var camera_holder = $CameraHolder # Has a position and rotates on Y. +@onready var rotation_x = $CameraHolder/RotationX +@onready var camera = $CameraHolder/RotationX/Camera3D + + +func _ready(): + camera_holder.transform.basis = Basis.from_euler(Vector3(0, rot_y, 0)) + rotation_x.transform.basis = Basis.from_euler(Vector3(rot_x, 0, 0)) + update_gui() + + +func _unhandled_input(event): + if event.is_action_pressed("ui_left"): + _on_previous_pressed() + if event.is_action_pressed("ui_right"): + _on_next_pressed() + + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_WHEEL_UP: + zoom -= ZOOM_SPEED + if event.button_index == MOUSE_BUTTON_WHEEL_DOWN: + zoom += ZOOM_SPEED + zoom = clamp(zoom, 1.5, 4) + + if event is InputEventMouseMotion and event.button_mask & MAIN_BUTTONS: + # Compensate motion speed to be resolution-independent (based on the window height). + var relative_motion = event.relative * DisplayServer.window_get_size().y / base_height + rot_y -= relative_motion.x * ROT_SPEED + rot_x -= relative_motion.y * ROT_SPEED + rot_x = clamp(rot_x, deg_to_rad(-90), 0) + camera_holder.transform.basis = Basis.from_euler(Vector3(0, rot_y, 0)) + rotation_x.transform.basis = Basis.from_euler(Vector3(rot_x, 0, 0)) + + +func _process(delta): + var current_tester = testers.get_child(tester_index) + # This code assumes CameraHolder's X and Y coordinates are already correct. + var current_position = camera_holder.global_transform.origin.z + var target_position = current_tester.global_transform.origin.z + camera_holder.global_transform.origin.z = lerpf(current_position, target_position, 3 * delta) + camera.position.z = lerpf(camera.position.z, zoom, 10 * delta) + + +func _on_previous_pressed(): + tester_index = max(0, tester_index - 1) + update_gui() + + +func _on_next_pressed(): + tester_index = min(tester_index + 1, testers.get_child_count() - 1) + update_gui() + + +func update_gui(): + $TestName.text = str(testers.get_child(tester_index).name).capitalize() + $Previous.disabled = tester_index == 0 + $Next.disabled = tester_index == testers.get_child_count() - 1