Destroy individual particles if they exceed AABB bounds?
Asked Answered
A

14

0

Is it possible (possibly with a particle shader) to destroy particles if they leave the AABB bounds of a box (I'm getting the bounds from a MeshInstance)? I have the AABB of the body I want them to remain in but I’m not sure how to keep individual particles from leaving it, can it be done with a particle shader somehow?

I'm also using an actual material shader on the particles themselves for visual effect, so presumably that would need to be merged with the converted particle shader?

Abrahamsen answered 4/2, 2022 at 11:20 Comment(0)
F
0

Fade particle alpha to zero when it exits the bounding box.

Flitting answered 4/2, 2022 at 11:51 Comment(0)
A
0

@xyz said: Fade particle alpha to zero when it exits the bounding box.

I'm afraid I have no idea how to do this with particle shader code, haha! This would be on all 6 ends? (x, y and z start, x, y and z end)

Abrahamsen answered 4/2, 2022 at 12:10 Comment(0)
F
0

Send aabb extents as a vec3 uniform to shader and step the absolute value of each component of TRANSFORM[3].xyz against the corresponding extent.

Flitting answered 4/2, 2022 at 12:25 Comment(0)
A
0

@xyz said: Send aabb extents as a vec3 uniform to shader and step the absolute value of each component of TRANSFORM[3].xyz against the corresponding extent.

I have something like:

var bounds
func _ready():
	bounds = global_transform.xform(mesh.get_aabb())

This is in my mesh script, but I'm not entirely sure how to actually write all this in shader code. The closest I could find to describing what you mentioned is this part of this video (11:37) :

but I'm lost where to begin with this as shader code isn't my strong point.

Abrahamsen answered 4/2, 2022 at 21:20 Comment(0)
F
0

Here's shader code. Add it at the end of existing vertex() function:

vec3 fade = step(abs(TRANSFORM[3].xyz), aabbExtents);
COLOR.a *= fade.x * fade.y * fade.z;

aabbExtents is vec3 uniform. Add the declaration to the uniform block at the top of shader code. Its components are aabb extents in each direction. Assumption is that aabb center is at particle system's local origin.

Flitting answered 4/2, 2022 at 22:50 Comment(0)
A
0

@xyz said: Here's shader code. Add it at the end of existing vertex() function:

vec3 fade = step(abs(TRANSFORM[3].xyz), aabbExtents);
COLOR.a *= fade.x * fade.y * fade.z;

aabbExtents is vec3 uniform. Add the declaration to the uniform block at the top of shader code. Its components are aabb extents in each direction. Assumption is that aabb center is at particle system's local origin.

Thanks, that helps a lot figuring out the structuring! But won't this fade the particles depending on how close they are from the longest end of the aabb in each axis, rather than being invisible if they exceed lower than the beginning of each axis or higher than the end of each axis?

Abrahamsen answered 5/2, 2022 at 8:6 Comment(0)
F
0

No, it won't. It does exactly what you want. Particle becomes invisible if it exits the bounding box. Btw I don't know what you mean by "longest end of the aabb".

Flitting answered 5/2, 2022 at 11:8 Comment(0)
A
0

@xyz said: No, it won't. It does exactly what you want. Particle becomes invisible if it exits the bounding box. Btw I don't know what you mean by "longest end of the aabb".

uniform vec4 color_value : hint_color;
uniform int trail_divisor;
uniform vec3 gravity;
uniform vec3 aabbExtents;
TRANSFORM[0].xyz *= base_scale;
	TRANSFORM[1].xyz *= base_scale;
	TRANSFORM[2].xyz *= base_scale;
	if (CUSTOM.y > CUSTOM.w) {		ACTIVE = false;
	}
	vec3 fade = step(abs(TRANSFORM[3].xyz), aabbExtents);
	COLOR.a *= fade.x * fade.y * fade.z;

Is this correct? It doesn't appear to be making them invisible. Could it be because I'm also using a draw pass material?

Abrahamsen answered 5/2, 2022 at 19:36 Comment(0)
F
0

Spatial material assigned to particle geometry in the draw pass needs to have flags_transparent and vertex_color_use_as_albedo flags enabled. Otherwise color (and alpha) set in particle process shader will be ignored by the spatial material.

Flitting answered 5/2, 2022 at 20:54 Comment(0)
A
0

@xyz said: Spatial material assigned to particle geometry in the draw pass needs to have flags_transparent and vertex_color_use_as_albedo flags enabled. Otherwise color (and alpha) set in particle process shader will be ignored by the spatial material.

Ah it's a shader material in the draw pass, not a spatial material?

Abrahamsen answered 5/2, 2022 at 21:36 Comment(0)
F
0

Draw pass should use spatial material or shader material with shader type declared as spatial. It's the same thing.

Flitting answered 5/2, 2022 at 22:7 Comment(0)
A
0

@xyz said: Draw pass should use spatial material or shader material with shader type declared as spatial. It's the same thing.

Oh you're right, I'm really sorry but as I said I'm very inexperienced with shaders, haha! Can those be set in shader_type or would it need writing in specifically for the shader? It's a bubble shader (trying to keep the bubbles within the bounds of the water, which is a box):

shader_type spatial;

uniform sampler2D noise_tex;
uniform vec4 bubble_color:hint_color;
uniform float height_multiplier = 0.5;
uniform float noise_sample_size = 0.1;
uniform float animation_speed = 0.1;

varying float height;

float fresnel(vec3 normal, mat4 camera_matrix){
	vec3 view_direction_world = (camera_matrix * vec4(0.0,0.0,1.0,0.0)).xyz;
	vec3 normal_world = (camera_matrix * vec4(normal,0.0)).xyz;
	
	float d = dot(view_direction_world, normal_world);
	d = abs(d);
	d = clamp(d, 0.0, 1.0);
	
	return 1.0 - d;
}

void vertex(){
	height = texture(noise_tex, VERTEX.xz * noise_sample_size + vec2(TIME) * animation_speed).r;
	VERTEX += NORMAL * height * height_multiplier;
}

void fragment(){
	ROUGHNESS = mix(0.05, 0.1, 1.0 - height);
	SPECULAR = height;
	ALPHA = fresnel(NORMAL, CAMERA_MATRIX);
	ALBEDO = bubble_color.rgb;
}
Abrahamsen answered 5/2, 2022 at 22:12 Comment(0)
F
0

Just multiply ALPHA in the fragment shader with COLOR.a

ALPHA = fresnel(NORMAL, CAMERA_MATRIX) * COLOR.a;
Flitting answered 5/2, 2022 at 22:25 Comment(0)
A
0

@xyz said: Just multiply ALPHA in the fragment shader with COLOR.a

ALPHA = fresnel(NORMAL, CAMERA_MATRIX) * COLOR.a;

Wow, you're a genius, haha that worked perfectly, thankyou!!

Abrahamsen answered 5/2, 2022 at 22:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.