Surface Embedded Sprites

A technique originally developed by Valve for Portal 2’s gels: https://steamcdn-a.akamaihd.net/apps/valve/2011/gdc_2011_grimes_nonstandard_textures.pdf (see slides 65-86)

UV islands are mapped out in the RG channels of uv_map, and the alpha channel is used for masking. Parallax offset is applied to give the surface a bit more depth. You can find my example textures here.

Sidenote – the original presentation describes the transformation matrix being constructed in the vertex shader, but it turns out this looks really bad on low-poly geometry and the final game actually does it in the pixel shader (thanks DETOX for sleuthing).

Shader code
shader_type spatial;

uniform sampler2D albedo : source_color;
uniform vec2 tiling = vec2(1.0);
uniform vec2 offset = vec2(0.0);

group_uniforms sprite_mapping;
uniform sampler2D uv_map;
uniform sampler2D sprite : source_color, repeat_disable;
uniform vec2 uv_tiling = vec2(1.0);
uniform vec2 uv_offset = vec2(0.0);
uniform float depth = 0.0;

void fragment() {
	// Construct sprite transformation matrix
	mat3 tangent_view_matrix = mat3(TANGENT, -BINORMAL, NORMAL);
	mat3 sprite_matrix = mat3(vec3(1, 0, 0) * tangent_view_matrix, vec3(0), -VIEW * tangent_view_matrix);
	sprite_matrix[1] = normalize(cross(sprite_matrix[0], sprite_matrix[2]));
	sprite_matrix[0] = cross(sprite_matrix[2], sprite_matrix[1]);
	
	// Apply UV map and parallax
	vec4 sprite_uv_map = texture(uv_map, UV * uv_tiling + uv_offset);
	vec2 sprite_uv = sprite_uv_map.xy;
	sprite_uv -= sprite_matrix[2].xy / sprite_matrix[2].z * depth;
	
	// Rotate UV coordinates
	sprite_uv -= 0.5;
	vec2 transformed_uv = vec2(dot(sprite_matrix[0].xy, sprite_uv), dot(sprite_matrix[1].xy, sprite_uv));
	transformed_uv += 0.5;
	
	vec4 surface_embedded_sprite = texture(sprite, transformed_uv);
	float sprite_mask = sprite_uv_map.a * surface_embedded_sprite.a;
	ALBEDO = texture(albedo, UV * tiling + offset).rgb;
	ALBEDO = mix(ALBEDO, surface_embedded_sprite.rgb, sprite_mask);
}
Tags
sprite, uv
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 tentabrobpy

N64 Style Skybox

Local Screen Space UV

Related shaders

Cast Texture To Surface

PSX Style Water Surface – Pixelation, Waves, Scrolling Textures

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments