Quad Mesh Mask Perspective

Got a couple quad meshes. Wanna mask green child with red parent.

shader_type spatial;

uniform vec4 color: source_color = vec4(1, 1, 1, 1);
uniform vec2 mesh_mask_position = vec2(0, 0);
uniform vec2 mesh_mask_size = vec2(1, 1);

void fragment() {
	vec2 frag_to_parent_xy = VERTEX.xy - mesh_mask_position.xy;
	vec2 abs_distance_xy = abs(frag_to_parent_xy);
	if (any(greaterThan(abs_distance_xy, mesh_mask_size.xy * 0.5))) {
		discard;
	}

	ALBEDO = color.rgb;
	ALPHA = color.a;
}

This shader kinda works but does not account for perspective. The child is forward a bit so looks like it comes past mask edge. How can i account for perspective to align mask with edge? Or maybe a better way idk…

Yes works if ortho cam, or child not forward, but need 3d.

Thanks.

shader_type spatial;

uniform vec4 color: source_color = vec4(1, 1, 1, 1);
uniform vec2 mesh_mask_position = vec2(0, 0);
uniform vec2 mesh_mask_size = vec2(1, 1);

void fragment() {
	vec4 world_pos = INV_VIEW_MATRIX * vec4(VERTEX, 1.0);
	vec2 frag_to_mask = (world_pos.xy - mesh_mask_position) / -VERTEX.z;
	if (any(greaterThan(abs(frag_to_mask), mesh_mask_size * 0.5))) {
		discard;
	}
	ALBEDO = color.rgb;
	ALPHA = color.a;
}

still some issues when moving mask but works better… idk

edit: final form? :slight_smile:

shader_type spatial;

uniform vec4 color: source_color = vec4(1.0);
uniform mat4 mask_transform = mat4(1.0);
uniform vec2 mask_size = vec2(1.0);

varying vec2 mask_min;
varying vec2 mask_max;

const int NUM_CORNERS = 4;

void vertex() {
	mat4 clip_space = PROJECTION_MATRIX * VIEW_MATRIX * mask_transform;
	vec2 half_size = mask_size * 0.5;
	vec4 corners[NUM_CORNERS] = {
		clip_space * vec4(-half_size.x, -half_size.y, 0.0, 1.0),
		clip_space * vec4(half_size.x, -half_size.y, 0.0, 1.0),
		clip_space * vec4(half_size.x, half_size.y, 0.0, 1.0),
		clip_space * vec4(-half_size.x, half_size.y, 0.0, 1.0)
	};
	mask_min = vec2(1.0);
	mask_max = vec2(-1.0);
	for (int i = 0; i < NUM_CORNERS; i++) {
		vec2 corner = corners[i].xy / corners[i].w;
		mask_min = min(mask_min, corner);
		mask_max = max(mask_max, corner);
	}
}

void fragment() {
	vec2 clip_pos = SCREEN_UV * 2.0 - 1.0;
	if (any(lessThan(clip_pos, mask_min)) || any(greaterThan(clip_pos, mask_max))) {
		discard;
	}
	ALBEDO = color.rgb;
	ALPHA = color.a;
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.