Matcap Shader

A very simple matcap shader, roughly based on the one uploaded by FireRabbit, but implementing a ‘fix’ demonstrated by Ben Cloward!

A matcap is an image of a ‘sphere’ or circle with details on it, which 3d models then use to determine their color and other information depending on what direction the model’s faces look on a screen-basis. Ie, a face looking to the upper left corner will sample from the upper-left part of this circle texture.

They’re great for quickly and cheaply adding consistent lighting information to an object, similar in vein to a Cubemap in that sense, although not 3d.

I’ve included examples of how to mix your normalmap into the shader within the code itself, as well as how to mix the matcap into your main material, though the base shader is as simple as it can be.

Shader code
// Special thanks to Ben Cloward for the amazing Material tutorial which improved this shader 20x!!
// Video here: https://www.youtube.com/watch?v=osgMB0mf23w
// Thanks to FireRabbit for the base which I pulled apart!

shader_type spatial;
render_mode unshaded; // remove this if you wish to make it shaded

uniform sampler2D matcap : source_color, hint_default_black; // Sampler 2d of the matcap

// Bread and buter: Generates the MatCap's UV's
vec2 generate_matcap_uv(vec3 _normal, vec3 _node_position_view) {
	vec3 cross_space = cross(normalize(_node_position_view), _normal); // cross products the normal with it's base position
	vec2 mat_space = vec2(cross_space.y * 1.0, cross_space.x); // converts to a Vec2 UV, having to switch x and y
	mat_space *= vec2(-0.5, -0.5); // modifies the mat space's size to fit into uv coords, & flips it
	mat_space += vec2(0.5, 0.5); // transforms the mat space into uv coords
	return mat_space; // export the final uv's
}

void fragment(){
	vec2 matcap_uv = (generate_matcap_uv(NORMAL, NODE_POSITION_VIEW)); // Matcap UV's
	vec3 _matcap = texture(matcap, matcap_uv).rgb; // Matcap Texture
	ALBEDO = _matcap; // Sets the albedo to the matcap texture. 
}

//// Additional Information: \\\\\

// NOTE: this shader isn't perfect, sadly. There's still something causing some minor distortion on the material.
// I'll try to update this with the fix if it ever gets found.
// Feel free to improve upon this! Let me know if you do, too!

// If you want to make it make it take your normalmap into account, replace the [vec3 _matcap = ...] with:
//
// vec3 _matcap = texture(matcap, matcap_uv + ((texture([INSERT NORMALMAP], UV).xy - 0.5) * [INFLUENCE])).rgb;
// 
// Replacing the [INSERT NORMALMAP] with your sampler2D normalmap 
// and [INFLUENCE] with a float. 
// 
// The [.xy - 0.5] part maps the normal from vec3 [0 : 1] range into a vec2 [-0.5 : 0.5] range. 
// You can correct it into a [-1 : 1] range by multiplying it by 2, but I found it's not really nessessary here.

// If you want to use a Metalness map or a Roughness map, or both, to influence the matcap:
// insert this to blend between the _matcap and a value like so:
//
// _matcap = mix(vec3(0.0), _matcap, clamp([metalness] + (1 - [roughness]), 0, 1);
//
// The example above is a super simple blend between the metal value, and the inverse rough value. 
// Effectively meaning that the more metallic and more shiny the object, the more matcap it'll have
// You'll want to augment it and make it more complex than that though. It's just a quick example.

// If you want to add onto the default shading, you'll want to add the _matcap 
// to your albedo or emissive layer instead of setting it like it is in this file. IE: 
//
// ALBEDO = texture(albedo, UV)
// ALBEDO += _matcap
// EMISSION += _matcap

// Or multiply it if you want it to be more of a 'flashlight'/'shadow' kind of effect instead of a 
// light.
// ALBEDO = texture(albedo, UV)
// ALBEDO *= _matcap

// or do both at the same time! Mix n Match! It's all up to you now :3
Tags
Anime, base, cartoon, light, lite, matcap, material, mobile, toon
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

XR-Safe Matcap

View-MatCap

View-Matcap Based Fake Vertex Lighting

Subscribe
Notify of
guest

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Firerabbit
8 months ago

Great improvement

artificeofbees
3 months ago
Reply to  nessinby

any updates on this? I’m currently working on a project that could really use a flawless matcap