Face Swap Shader

Made for the sort of thing where you display a pixel-art face on a 3D model. It lets you set the current frame using an instance uniform.

 

You can change the current frame in code using somthing like:

mesh_instance_3d.set_instance_shader_parameter("frame", 2)

Or you can animate the frame as a Property Track with an AnimationPlayer

Shader code
shader_type spatial;
// made for the sort of thing where you display a pixel-art face overtop of a 3D model


render_mode unshaded; // you can remove this if you do want shading 

// extrude along normals slightly to 
uniform float extrude_amount = 0.001;

// a collection of different faces you want to be able to swap between, in a grid
// If you make separate meshes for eyes and mouth you can mix and match
uniform sampler2D sprite_texture:source_color, repeat_disable, filter_nearest, hint_default_transparent;

// number of columns and rows the sprite texture will be divided into
uniform int columns = 4;
uniform int rows = 4;

// which frame in the sprite texture to show
instance uniform int frame = 0;

void vertex() {
	// converts UV assuming original would display the face nicely if it was a single image rather than a grid
	vec2 tilesize = vec2(1.0 / float(columns), 1.0 / float(rows));
	vec2 frame_offset = vec2(float(frame % columns), float(frame / columns));
	UV = (UV + frame_offset) * tilesize;
	// extrudes so you can avoid z-fighting even if you reused the same mesh
	VERTEX += NORMAL * extrude_amount;
}

void fragment() {
	vec4 sample = texture(sprite_texture, UV);
	ALBEDO = sample.rgb;
	ALPHA = sample.a;
	ALPHA_SCISSOR_THRESHOLD = 0.5;
}
Live Preview
Tags
face
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from rrh

Related shaders

guest

0 Comments
Oldest
Newest Most Voted