Custom Shaders

It is possible to use custom shaders written in GLSL and use them inside Substance Painter.

You can either :

  • Find already existing shaders on Substance Share.
  • Write your own shader. The documentation to write those shaders is available via the menu Help > Documentation > Shader API menu entry inside Substance Painter.

Shader API Update

Below are important updates that happened to the Shader API.


With the introduction of the Sparse Virtual Textures (SVT) system, shaders have been modified to take into account Sparse Textures. This means sampling textures is now different than before. While older shaders will continue working, old sampling method are considered deprecated and shaders should be updated to the latest API change (otherwise artifacts may appear, see : Mesh flash to white when moving camera ).

Declaring an engine texture (such as channels) was :

//: param auto channel_basecolor
uniform sampler2D basecolor_tex;
Is now :
//: param auto channel_basecolor
uniform SamplerSparse basecolor_tex;

Sampling a texture was :
float roughness = getRoughness(roughness_tex, inputs.tex_coord); //Helper
float roughness = texture(roughness_tex, tex_coord).r; //Direct Sampling
Is now :
float roughness = getRoughness(roughness_tex, inputs.sparse_coord); //Helper
float roughness = textureSparse(roughness_tex,  inputs.sparse_coord).r; //Direct sampling

This change in the way textures are sampled only applies to engine textures (channels provided by Substance Painter), any other textures should be sampled as normal since they are not part of the SVT system.

Example : the mesh maps and channels should use the Sparse sampler, a blue noise texture used to blend effects should use the regular sampling function.

We recommend taking a look at our default shader pbr-metal-rough.glsl for an overview of how the shaders now behave. For further details please consult the new lib-sparse.glsl file as well as the updated lib-sampler.glsl file from the Shader API documentation.

Changelog :

  • Add a new lib-pbr-aniso.glsl library to help visualizing anisotropic specular highlight
  • Add a new lib-sparse.glsl library to help channel sampling by taking care of mipmaps availability
  • Update shader libraries interfaces to take care of this safe sampling
  • Deprecation: The previous functions based on the vec2 texture coordinates and the texture sampler have been deprecated (please use new signatures)
  • lib-pom.glsl: Add a applyParallaxOffset function to simplify to use of parallax occlusion effect
  • lib-sampler.glsl: Split all channel sampling helpers to have both value interpretation and sampling helpers


The main shade() function now returns calls to specific functions rather than a simple vec4. The pbrComputeBRDF() has been replaced by separate functions to compute each term individually.
Take a look at how the default pbr-metal-rough.glsl shader provided with Substance Painter is written to get an overview of the new procedure. For further details refer to the surface-shader.glsl page in the Shader API.

Changelog :

  • Surface shader API change: the shade function signature has changed, see surface-shader.glsl

  • The shadeShadow function is no longer used and can safely be removed from custom surface shaders
  • Add Subsurface Scattering support, see surface-shader.glsl and lib-sss.glsl for details
  • lib-pbr.glsl: the pbrComputeBRDF function has been removed. See pbr-metal-rough.glsl example to know how to use the library now
  • New engine parameters have been added: texture_blue_noiseaspect_ratiocamera_vp_matrix_inverseenvironment_exposureenvironment_rotationfovymain_light and screen_size. See all-engine-params.glsl for details
  • Add the description metadata to provide tooltips for custom shader parameters