GuidesWriting LayerShaders
Writing MaskShaders
A practical example of a MaskShader that blends the Blend and Base inputs using a mask.
A MaskShader is used in a MaskMaterial. It has its own setup macros and layer variables.
See What is a MaskShader and the MaskShader reference.
A MaskShader blends LayerMaterials using a mask. The mask can be anything you want.
Below is a MaskShader that blends the Blend and Base inputs using a simple mask.
shader_type spatial;
#include "res://addons/material_layers/shaders/layer_lib.gdshaderinc"
// Helper functions
float getChannel(vec4 tex, int ch) {
if (ch == 0) return tex.r;
if (ch == 1) return tex.g;
if (ch == 2) return tex.b;
if (ch == 3) return tex.a;
return 1.0;
}
float heightBlend(float h1, float h2, float height_offset, float contrast, float mask){
height_offset = 1.0 - height_offset;
float add1 = h1 + height_offset;
float subtract1 = h2 - height_offset;
float add2 = subtract1 + mask;
float max1 = max(add1, add2);
float subtract2 = max1 - add1;
float multiply1 = subtract2 * (contrast * 30.0);
float result = clamp(multiply1, 0.0, 1.0);
return result;
}
vec3 normalCombine(vec3 n1, vec3 n2, float mask){
vec2 blendedXY = n1.rg + (n2.rg - 0.5) * mask;
float blendedZ = mix(n1.z, n1.z * n2.z, mask);
return vec3(blendedXY, blendedZ);
}
//-----------------------------------------
group_uniforms heightBlending;
uniform int vertexColor : hint_enum("Red", "Green", "Blue", "Alpha", "None") = 0;
uniform float heightOffset : hint_range(0.0, 1.0) = 0.2;
uniform float heightContrast : hint_range(0.0, 1.0) = 0.2;
uniform bool invertHeight;
void fragment() {
SETUP_MASK_FRAGMENT;
float vertex_color = getChannel(COLOR, vertexColor);
float mask = heightBlend(
mix(1.0 - LAYER_BASE_HEIGHT,
LAYER_BASE_HEIGHT, float(invertHeight)),
LAYER_BLEND_HEIGHT, heightOffset,
heightContrast, vertex_color);
// Blend BASE and BLEND inputs with a mask and output the result
LAYER_OUT_ALBEDO = mix(LAYER_BASE_ALBEDO, LAYER_BLEND_ALBEDO, mask);
LAYER_OUT_ROUGHNESS = mix(LAYER_BASE_ROUGHNESS, LAYER_BLEND_ROUGHNESS, mask);
LAYER_OUT_NORMAL_MAP = normalCombine(LAYER_BASE_NORMAL_MAP, LAYER_BLEND_NORMAL_MAP, mask);
LAYER_OUT_AO = LAYER_BASE_AO * mix(1.0, LAYER_BLEND_AO, mask);
LAYER_OUT_HEIGHT = LAYER_BASE_HEIGHT;
ALBEDO = vec3(mask);
}