Material Layers
GuidesWriting LayerShaders

Writing SurfaceShaders

A practical example of a SurfaceShader that outputs PBR textures using LAYER_OUT layer variables.

A SurfaceShader is used in a SurfaceMaterial. It has its own setup macros and layer variables.

See What is a SurfaceShader and the SurfaceShader reference.

A SurfaceShader is used as a base material. It can only output its material properties. It can't read properties from the layer below. It can read the data variables of DataMaterials below it. See What is a DataShader.

Below is a SurfaceShader that samples a set of PBR textures and outputs them using the LAYER_OUT_* layer variables.

The LAYER_OUT_* layer variables are assigned to the default outputs like ALBEDO and ROUGHNESS for material previews.

shader_type spatial;

#include "res://addons/material_layers/shaders/layer_lib.gdshaderinc"

group_uniforms textures;
uniform sampler2D albedoTexture : source_color, filter_linear_mipmap_anisotropic;
uniform sampler2D roughnessTexture : filter_linear_mipmap_anisotropic;
uniform sampler2D normalTexture : filter_linear_mipmap_anisotropic;
uniform sampler2D aoTexture : filter_linear_mipmap_anisotropic;
uniform sampler2D heightTexture : filter_linear_mipmap_anisotropic;

void fragment() {
	SETUP_SURFACE_FRAGMENT;

	vec3 albedo = texture(albedoTexture, UV).rgb;
	float roughness = texture(roughnessTexture, UV).r;
	vec3 normal = texture(normalTexture, UV).rgb;
	float ao = texture(aoTexture, UV).r;
	float height = texture(heightTexture, UV).r;

	// Output the layer attributes
	LAYER_OUT_ALBEDO = albedo;
	LAYER_OUT_ROUGHNESS = roughness;
	LAYER_OUT_NORMAL_MAP = normal;
	LAYER_OUT_AO = ao;
	LAYER_OUT_HEIGHT = height;

	// Default outputs for material previews
	ALBEDO = albedo;
	ROUGHNESS = roughness;
	NORMAL_MAP = normal;
	AO = ao;
}
YoutubePatreonDocsAssetsTwitter

©2026 Foyezes