Documentation for Substance 3D Painter is now available on Experience League. After March 14th, HelpX pages will automatically redirect to the equivalent Experience League page.
Refer to the FAQ for more information about which documentation is affected.
- Substance 3D home
- Home
- Getting Started
- Getting Started overview
- Activation and licenses
- System requirements
- Project creation
- Export
- Export overview
- Export window
- Output templates
- Export overview
- Glossary
- Getting Started overview
- Interface
- Interface overview
- Assets
- Substance 3D Assets
- Color picker
- Display settings
- History
- Layer stack
- Main menu
- Project configuration
- Properties
- Settings
- Shader settings
- Texture Set
- Toolbars
- Viewport
- Miscellaneous
- Painting
- Painting overview
- Paint tools
- Path tools
- Path tool overview
- Paint along path
- Ribbon path
- Filled path
- Erase along path
- Smudge along path
- Straight line
- Lazy mouse
- Symmetry
- Fill projections
- Presets
- Presets overview
- Creating and saving presets
- Creating particles presets
- Photoshop brush presets
- Dynamic strokes
- Advanced channel painting
- Vector graphic (.svg & .ai)
- Text resource
- Effects
- Baking
- Content
- Creating custom effects
- Importing assets
- Creating custom effects
- Features
- Automatic resource update
- Automatic UV Unwrapping
- Physical size
- Smart Materials and Masks
- Subsurface Scattering
- Dynamic Material Layering
- UV Reprojection
- UV Tiles
- Color Management
- Post Processing
- Iray Renderer
- Plugins
- Sparse Virtual Textures
- Custom Shaders
- SpaceMouse® by 3Dconnexion
- Universal Scene Description (USD)
- Send to
- Technical Support
- Performance Guidelines
- Configuring Pens and Tablets
- Exporting the log file
- Exporting a DXDiag
- Technical issues
- GPU Issues
- Crash when working with overclocked GPU
- Forcing the external GPU on Mac OS
- GPU drivers compatibility
- GPU drivers crash with long computations (TDR crash)
- GPU has outdated drivers
- GPU is not recognized
- GPU is not recognized and is mentionned as GDI Generic
- Issues with Nvidia GPUs on recent Mac OS versions
- Multi/Bi-GPU
- Running on integrated GPU
- Painter doesn't start on the right GPU
- Startup Issues
- Rendering Issues
- Stability Issues
- Miscellaneous Issues
- GPU Issues
- Workflow Issues
- Export Issues
- Tools Issues
- Project Issues
- Library Issues
- Viewport Issues
- Plugins Issues
- License Issues
- Pipeline and integration
- Installation and preferences
- Configuration
- Resource management
- Scripting and development
- Scripts and plugins
- Shader API Reference
- Shader API overview
- Changelog - Shader API
- Libraries - Shader API
- Lib Alpha - Shader API
- Lib Bayer - Shader API
- Lib Defines - Shader API
- Lib Emissive - Shader API
- Lib Env - Shader API
- Lib Normal - Shader API
- Lib PBR - Shader API
- Lib PBR Aniso - Shader API
- Lib Pom - Shader API
- Lib Random - Shader API
- Lib Sampler - Shader API
- Lib Sparse - Shader API
- Lib SSS - Shader API
- Lib Utils - Shader API
- Lib Vectors - Shader API
- Parameters - Shader API
- Shaders - Shader API
- Release notes
- Release notes overview
- All Changes
- Version 11.1
- Version 11.0
- Version 10.1
- Known issues
- Old versions
- Version 10.0
- Version 9.1
- Version 9.0
- Version 8.3
- Version 8.2
- Version 8.1
- Version 7.4
- Version 7.3
- Version 7.2
- Version 2021.1 (7.1.0)
- Version 2020.2 (6.2.0)
- Version 2020.1 (6.1.0)
- Version 2019.3
- Version 2019.2
- Version 2019.1
- Version 2018.3
- Version 2018.2
- Version 2018.1
- Version 2017.4
- Version 2017.3
- Version 2017.2
- Version 2017.1
- Version 2.6
- Version 2.5
- Version 2.4
- Version 2.3
- Version 2.2
Lib PBR - Shader API
lib-pbr.glsl
Public Functions: normal_distrib fresnel G1 visibility horizonFading pbrComputeDiffuse pbrComputeSpecular pbrComputeBRDF
Number of miplevels in the envmap.
//: param auto environment_max_lod uniform float maxLod;
An int representing the number of samples made for specular contribution computation. The more the higher quality and the performance impact.
//: param custom {
//: "default": 16,
//: "label": "Quality",
//: "widget": "combobox",
//: "values": {
//: "Very low (4 spp)": 4,
//: "Low (16 spp)": 16,
//: "Medium (32 spp)": 32,
//: "High (64 spp)": 64,
//: "Very high (128 spp)": 128,
//: "Ultra (256 spp)": 256
//: },
//: "group": "Common Parameters"
//: }
uniform int nbSamples;
Value used to control specular reflection leaking through the surface.
//: param custom {
//: "default": 1.3,
//: "label": "Horizon Fading",
//: "min": 0.0,
//: "max": 2.0,
//: "group": "Common Parameters"
//: }
uniform float horizonFade;
Import from library, other parameters
import lib-env.glsl import lib-emissive.glsl import lib-random.glsl import lib-vectors.glsl
BRDF related functions
const float EPSILON_COEF = 1e-4;
float normal_distrib(
float ndh,
float Roughness)
{
// use GGX / Trowbridge-Reitz, same as Disney and Unreal 4
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p3
float alpha = Roughness * Roughness;
float tmp = alpha / max(1e-8,(ndh*ndh*(alpha*alpha-1.0)+1.0));
return tmp * tmp * M_INV_PI;
}
vec3 fresnel(
float vdh,
vec3 F0)
{
// Schlick with Spherical Gaussian approximation
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p3
float sphg = exp2((-5.55473*vdh - 6.98316) * vdh);
return F0 + (vec3(1.0) - F0) * sphg;
}
float G1(
float ndw, // w is either Ln or Vn
float k)
{
// One generic factor of the geometry function divided by ndw
// NB : We should have k > 0
return 1.0 / ( ndw*(1.0-k) + k );
}
float visibility(
float ndl,
float ndv,
float Roughness)
{
// Schlick with Smith-like choice of k
// cf http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf p3
// visibility is a Cook-Torrance geometry function divided by (n.l)*(n.v)
float k = max(Roughness * Roughness * 0.5, 1e-5);
return G1(ndl,k)*G1(ndv,k);
}
vec3 cook_torrance_contrib(
float vdh,
float ndh,
float ndl,
float ndv,
vec3 Ks,
float Roughness)
{
// This is the contribution when using importance sampling with the GGX based
// sample distribution. This means ct_contrib = ct_brdf / ggx_probability
return fresnel(vdh,Ks) * (visibility(ndl,ndv,Roughness) * vdh * ndl / ndh );
}
vec3 importanceSampleGGX(vec2 Xi, vec3 T, vec3 B, vec3 N, float roughness)
{
float a = roughness*roughness;
float cosT = sqrt((1.0-Xi.y)/(1.0+(a*a-1.0)*Xi.y));
float sinT = sqrt(1.0-cosT*cosT);
float phi = 2.0*M_PI*Xi.x;
return
T * (sinT*cos(phi)) +
B * (sinT*sin(phi)) +
N * cosT;
}
float probabilityGGX(float ndh, float vdh, float Roughness)
{
return normal_distrib(ndh, Roughness) * ndh / (4.0*vdh);
}
float distortion(vec3 Wn)
{
// Computes the inverse of the solid angle of the (differential) pixel in
// the cube map pointed at by Wn
float sinT = sqrt(1.0-Wn.y*Wn.y);
return sinT;
}
float computeLOD(vec3 Ln, float p)
{
return max(0.0, (maxLod-1.5) - 0.5 * log2(float(nbSamples) * p * distortion(Ln)));
}
Horizon fading trick from https://marmosetco.tumblr.com/post/81245981087
float horizonFading(float ndl, float horizonFade)
{
float horiz = clamp(1.0 + horizonFade * ndl, 0.0, 1.0);
return horiz * horiz;
}
Compute the lambertian diffuse radiance to the viewer's eye
vec3 pbrComputeDiffuse(vec3 normal, vec3 diffColor)
{
return envIrradiance(normal) * diffColor;
}
Compute the microfacets specular reflection to the viewer's eye
vec3 pbrComputeSpecular(LocalVectors vectors, vec3 specColor, float roughness)
{
vec3 radiance = vec3(0.0);
float ndv = dot(vectors.eye, vectors.normal);
for(int i=0; i<nbSamples; ++i)
{
vec2 Xi = fibonacci2D(i, nbSamples);
vec3 Hn = importanceSampleGGX(
Xi, vectors.tangent, vectors.bitangent, vectors.normal, roughness);
vec3 Ln = -reflect(vectors.eye,Hn);
float fade = horizonFading(dot(vectors.vertexNormal, Ln), horizonFade);
float ndl = dot(vectors.normal, Ln);
ndl = max( 1e-8, ndl );
float vdh = max(1e-8, dot(vectors.eye, Hn));
float ndh = max(1e-8, dot(vectors.normal, Hn));
float lodS = roughness < 0.01 ? 0.0 : computeLOD(Ln, probabilityGGX(ndh, vdh, roughness));
radiance += fade * envSampleLOD(Ln, lodS) *
cook_torrance_contrib(vdh, ndh, ndl, ndv, specColor, roughness);
}
// Remove occlusions on shiny reflections
radiance /= float(nbSamples);
return radiance;
}