User Guide Cancel

PBR Material Layering - Shader API | Substance 3D Painter

PBR Material Layering - Shader API

Import from libraries.

import lib-pbr.glsl
import lib-emissive.glsl
import lib-sampler.glsl
import lib-utils.glsl
#define NB_MATERIALS 4
#define NB_MASKS (NB_MATERIALS - 1)
//: metadata {
//: "custom-ui": "material-layering/custom-ui.qml"
//: }
//: materials [
//: {
//: "id": "Material1",
//: "label": "Material 1",
//: "default": "",
//: "size": 1024,
//: "default_color": [0.5, 0.5, 0.5]
//: },
//: {
//: "id": "Material2",
//: "label": "Material 2",
//: "default": "",
//: "size": 1024,
//: "default_color": [0.5, 0.5, 0.5]
//: },
//: {
//: "id": "Material3",
//: "label": "Material 3",
//: "default": "",
//: "size": 1024,
//: "default_color": [0.5, 0.5, 0.5]
//: },
//: {
//: "id": "Material4",
//: "label": "Material 4",
//: "default": "",
//: "size": 1024,
//: "default_color": [0.5, 0.5, 0.5]
//: }
//: ]
//: stacks [
//: {
//: "id": "Mask",
//: "channels":
//: [
//: {"id": "blendingmask"}
//: ]
//: },
//: {
//: "id": "Mask2",
//: "channels":
//: [
//: {"id": "blendingmask"}
//: ]
//: },
//: {
//: "id": "Mask3",
//: "channels":
//: [
//: {"id": "blendingmask"}
//: ]
//: }
//: ]
//: param custom { "default": false, "label": "Debug Mode" }
uniform bool DebugMode;
//: param custom {
//: "default": 0,
//: "label": "Debug channel",
//: "widget": "combobox",
//: "values": {
//: "BaseColor": 0,
//: "Roughness": 1,
//: "Metallic": 2,
//: "Normal (Material)": 3,
//: "Normal (Masks)": 4,
//: "Normal (Combined)": 5,
//: "Mask 1": 6,
//: "Mask 2": 7,
//: "Mask 3": 8
//: }
//: }
uniform int DebugChannel;
//: param custom { "default": false, "label": "Normal from Masks" }
uniform bool UseNormalFromMask;
import lib-pbr.glsl import lib-emissive.glsl import lib-sampler.glsl import lib-utils.glsl #define NB_MATERIALS 4 #define NB_MASKS (NB_MATERIALS - 1) //: metadata { //: "custom-ui": "material-layering/custom-ui.qml" //: } //: materials [ //: { //: "id": "Material1", //: "label": "Material 1", //: "default": "", //: "size": 1024, //: "default_color": [0.5, 0.5, 0.5] //: }, //: { //: "id": "Material2", //: "label": "Material 2", //: "default": "", //: "size": 1024, //: "default_color": [0.5, 0.5, 0.5] //: }, //: { //: "id": "Material3", //: "label": "Material 3", //: "default": "", //: "size": 1024, //: "default_color": [0.5, 0.5, 0.5] //: }, //: { //: "id": "Material4", //: "label": "Material 4", //: "default": "", //: "size": 1024, //: "default_color": [0.5, 0.5, 0.5] //: } //: ] //: stacks [ //: { //: "id": "Mask", //: "channels": //: [ //: {"id": "blendingmask"} //: ] //: }, //: { //: "id": "Mask2", //: "channels": //: [ //: {"id": "blendingmask"} //: ] //: }, //: { //: "id": "Mask3", //: "channels": //: [ //: {"id": "blendingmask"} //: ] //: } //: ] //: param custom { "default": false, "label": "Debug Mode" } uniform bool DebugMode; //: param custom { //: "default": 0, //: "label": "Debug channel", //: "widget": "combobox", //: "values": { //: "BaseColor": 0, //: "Roughness": 1, //: "Metallic": 2, //: "Normal (Material)": 3, //: "Normal (Masks)": 4, //: "Normal (Combined)": 5, //: "Mask 1": 6, //: "Mask 2": 7, //: "Mask 3": 8 //: } //: } uniform int DebugChannel; //: param custom { "default": false, "label": "Normal from Masks" } uniform bool UseNormalFromMask;
import lib-pbr.glsl 
import lib-emissive.glsl 
import lib-sampler.glsl 
import lib-utils.glsl 
 
#define NB_MATERIALS 4 
#define NB_MASKS     (NB_MATERIALS - 1) 
 
//: metadata { 
//:   "custom-ui": "material-layering/custom-ui.qml" 
//: } 
 
//: materials [ 
//:   { 
//:      "id": "Material1", 
//:      "label": "Material 1", 
//:      "default": "", 
//:      "size": 1024, 
//:      "default_color": [0.5, 0.5, 0.5] 
//:   }, 
//:   { 
//:      "id": "Material2", 
//:      "label": "Material 2", 
//:      "default": "", 
//:      "size": 1024, 
//:      "default_color": [0.5, 0.5, 0.5] 
//:   }, 
//:   { 
//:      "id": "Material3", 
//:      "label": "Material 3", 
//:      "default": "", 
//:      "size": 1024, 
//:      "default_color": [0.5, 0.5, 0.5] 
//:   }, 
//:   { 
//:      "id": "Material4", 
//:      "label": "Material 4", 
//:      "default": "", 
//:      "size": 1024, 
//:      "default_color": [0.5, 0.5, 0.5] 
//:   } 
//: ] 
 
 
//: stacks [ 
//:   { 
//:     "id": "Mask", 
//:     "channels": 
//:  [ 
//:   {"id": "blendingmask"} 
//:  ] 
//:   }, 
//:   { 
//:     "id": "Mask2", 
//:     "channels": 
//:  [ 
//:   {"id": "blendingmask"} 
//:  ] 
//:   }, 
//:   { 
//:     "id": "Mask3", 
//:     "channels": 
//:  [ 
//:   {"id": "blendingmask"} 
//:  ] 
//:   } 
//: ] 
 
 
 
//: param custom { "default": false, "label": "Debug Mode" } 
uniform bool DebugMode; 
 
//: param custom { 
//:   "default": 0, 
//:   "label": "Debug channel", 
//:   "widget": "combobox", 
//:   "values": { 
//:     "BaseColor": 0, 
//:     "Roughness": 1, 
//:     "Metallic": 2, 
//:     "Normal (Material)": 3, 
//:     "Normal (Masks)": 4, 
//:     "Normal (Combined)": 5, 
//:     "Mask 1": 6, 
//:     "Mask 2": 7, 
//:     "Mask 3": 8 
//:   } 
//: } 
uniform int DebugChannel; 
 
 
//: param custom { "default": false, "label": "Normal from Masks" } 
uniform bool UseNormalFromMask;

Channels needed for metal/rough workflow are bound here.

//: param auto texture_normal;
uniform sampler2D mesh_normal_texture;
//: param custom { "default": 5, "label": "Material 1 coords", "min": 0.01, "max": 128.0, "group" : "Material 1" }
uniform float u_coords1;
//: param custom { "default": 5, "label": "Material 2 coords", "min": 0.01, "max": 128.0, "group" : "Material 2" }
uniform float u_coords2;
//: param custom { "default": 5, "label": "Material 3 coords", "min": 0.01, "max": 128.0, "group" : "Material 3" }
uniform float u_coords3;
//: param custom { "default": 5, "label": "Material 4 coords", "min": 0.01, "max": 128.0, "group" : "Material 4" }
uniform float u_coords4;
//: param custom { "default": 1, "label": "Normal Intensity 1", "min": 0.0, "max": 1.0, "group" : "Material 1" }
uniform float normal_intensity1;
//: param custom { "default": 1, "label": "Normal Intensity 2", "min": 0.0, "max": 1.0, "group" : "Material 2" }
uniform float normal_intensity2;
//: param custom { "default": 1, "label": "Normal Intensity 3", "min": 0.0, "max": 1.0, "group" : "Material 3" }
uniform float normal_intensity3;
//: param custom { "default": 1, "label": "Normal Intensity 4", "min": 0.0, "max": 1.0, "group" : "Material 4" }
uniform float normal_intensity4;
//: param custom { "default": 0, "label": "Normal from Mask Intensity 2", "min": -10.0, "max": 10.0, "group" : "Material 2" }
uniform float mask_normal_intensity1;
//: param custom { "default": 0, "label": "Normal from Mask Intensity 3", "min": -10.0, "max": 10.0, "group" : "Material 3" }
uniform float mask_normal_intensity2;
//: param custom { "default": 0, "label": "Normal from Mask Intensity 4", "min": -10.0, "max": 10.0, "group" : "Material 4" }
uniform float mask_normal_intensity3;
//: param custom { "default": 0.1, "label": "Normal from Mask 1 Offset", "min": 0.0, "max": 1, "group" : "Material 2" }
uniform float mask_normal_offset1;
//: param custom { "default": 0.1, "label": "Normal from Mask 2 Offset", "min": 0.0, "max": 1, "group" : "Material 3" }
uniform float mask_normal_offset2;
//: param custom { "default": 0.1, "label": "Normal from Mask 3 Offset", "min": 0.0, "max": 1, "group" : "Material 4" }
uniform float mask_normal_offset3;
//: param auto Material1.channel_basecolor
uniform sampler2D color1;
//: param auto Material1.channel_roughness
uniform sampler2D rough1;
//: param auto Material1.channel_metallic
uniform sampler2D metal1;
//: param auto Material1.channel_normal
uniform sampler2D normal1;
//: param auto Material2.channel_basecolor
uniform sampler2D color2;
//: param auto Material2.channel_roughness
uniform sampler2D rough2;
//: param auto Material2.channel_metallic
uniform sampler2D metal2;
//: param auto Material2.channel_normal
uniform sampler2D normal2;
//: param auto Material3.channel_basecolor
uniform sampler2D color3;
//: param auto Material3.channel_roughness
uniform sampler2D rough3;
//: param auto Material3.channel_metallic
uniform sampler2D metal3;
//: param auto Material3.channel_normal
uniform sampler2D normal3;
//: param auto Material4.channel_basecolor
uniform sampler2D color4;
//: param auto Material4.channel_roughness
uniform sampler2D rough4;
//: param auto Material4.channel_metallic
uniform sampler2D metal4;
//: param auto Material4.channel_normal
uniform sampler2D normal4;
//: param auto Mask.channel_blendingmask
uniform SamplerSparse mask;
//: param auto Mask2.channel_blendingmask
uniform SamplerSparse mask2;
//: param auto Mask3.channel_blendingmask
uniform SamplerSparse mask3;
/////////////////////////////////////////
////////// BLENDING FUNCTIONS ///////////
/////////////////////////////////////////
float mixGrayscale(
float channelSampled[NB_MATERIALS],
float Masks[NB_MASKS])
{
float result = channelSampled[0];
for (int i = 0; i < NB_MASKS; i++)
result = mix(result, channelSampled[i + 1], Masks[i]);
return result;
}
vec3 mixColor(
vec3 channelSampled[NB_MATERIALS],
float Masks[NB_MASKS])
{
vec3 result = channelSampled[0];
for (int i = 0; i < NB_MASKS; i++)
result = mix(result, channelSampled[i + 1], Masks[i]);
return result;
}
vec3 mixNormal(
vec3 channelSampled[NB_MATERIALS],
float Masks[NB_MASKS],
float NormalIntensity[NB_MATERIALS])
{
vec3 result = NormalIntensity[0] * channelSampled[0];
for (int i = 0; i < NB_MASKS; i++)
result = mix(result, NormalIntensity[i + 1] * channelSampled[i + 1], Masks[i]);
return result;
}
vec3 NormalFromMask(SamplerSparse Mask, float Offset, float Intensity, SparseCoord UVs, float refMask)
{
vec4 results[2];
vec2 offsets[2] = vec2[2](
vec2(Offset * 0.001, 0.0),
vec2(0.0, Offset * 0.001)
);
textureSparseOffsets(Mask, UVs, offsets, results);
float Channel1 = results[0].r - refMask;
float Channel2 = results[1].r - refMask;
return vec3(-Intensity * Channel1, -Intensity * Channel2, 1.0);
}
vec3 NormalFromMasks(
vec3 normalFromMaskSampled[NB_MASKS],
float Masks[NB_MASKS])
{
vec3 result = normalFromMaskSampled[0];
for (int i = 1; i < NB_MASKS; i++)
result = mix(result, normalFromMaskSampled[i], Masks[i]);
return result;
}
void shade(V2F inputs)
{
//: param auto texture_normal; uniform sampler2D mesh_normal_texture; //: param custom { "default": 5, "label": "Material 1 coords", "min": 0.01, "max": 128.0, "group" : "Material 1" } uniform float u_coords1; //: param custom { "default": 5, "label": "Material 2 coords", "min": 0.01, "max": 128.0, "group" : "Material 2" } uniform float u_coords2; //: param custom { "default": 5, "label": "Material 3 coords", "min": 0.01, "max": 128.0, "group" : "Material 3" } uniform float u_coords3; //: param custom { "default": 5, "label": "Material 4 coords", "min": 0.01, "max": 128.0, "group" : "Material 4" } uniform float u_coords4; //: param custom { "default": 1, "label": "Normal Intensity 1", "min": 0.0, "max": 1.0, "group" : "Material 1" } uniform float normal_intensity1; //: param custom { "default": 1, "label": "Normal Intensity 2", "min": 0.0, "max": 1.0, "group" : "Material 2" } uniform float normal_intensity2; //: param custom { "default": 1, "label": "Normal Intensity 3", "min": 0.0, "max": 1.0, "group" : "Material 3" } uniform float normal_intensity3; //: param custom { "default": 1, "label": "Normal Intensity 4", "min": 0.0, "max": 1.0, "group" : "Material 4" } uniform float normal_intensity4; //: param custom { "default": 0, "label": "Normal from Mask Intensity 2", "min": -10.0, "max": 10.0, "group" : "Material 2" } uniform float mask_normal_intensity1; //: param custom { "default": 0, "label": "Normal from Mask Intensity 3", "min": -10.0, "max": 10.0, "group" : "Material 3" } uniform float mask_normal_intensity2; //: param custom { "default": 0, "label": "Normal from Mask Intensity 4", "min": -10.0, "max": 10.0, "group" : "Material 4" } uniform float mask_normal_intensity3; //: param custom { "default": 0.1, "label": "Normal from Mask 1 Offset", "min": 0.0, "max": 1, "group" : "Material 2" } uniform float mask_normal_offset1; //: param custom { "default": 0.1, "label": "Normal from Mask 2 Offset", "min": 0.0, "max": 1, "group" : "Material 3" } uniform float mask_normal_offset2; //: param custom { "default": 0.1, "label": "Normal from Mask 3 Offset", "min": 0.0, "max": 1, "group" : "Material 4" } uniform float mask_normal_offset3; //: param auto Material1.channel_basecolor uniform sampler2D color1; //: param auto Material1.channel_roughness uniform sampler2D rough1; //: param auto Material1.channel_metallic uniform sampler2D metal1; //: param auto Material1.channel_normal uniform sampler2D normal1; //: param auto Material2.channel_basecolor uniform sampler2D color2; //: param auto Material2.channel_roughness uniform sampler2D rough2; //: param auto Material2.channel_metallic uniform sampler2D metal2; //: param auto Material2.channel_normal uniform sampler2D normal2; //: param auto Material3.channel_basecolor uniform sampler2D color3; //: param auto Material3.channel_roughness uniform sampler2D rough3; //: param auto Material3.channel_metallic uniform sampler2D metal3; //: param auto Material3.channel_normal uniform sampler2D normal3; //: param auto Material4.channel_basecolor uniform sampler2D color4; //: param auto Material4.channel_roughness uniform sampler2D rough4; //: param auto Material4.channel_metallic uniform sampler2D metal4; //: param auto Material4.channel_normal uniform sampler2D normal4; //: param auto Mask.channel_blendingmask uniform SamplerSparse mask; //: param auto Mask2.channel_blendingmask uniform SamplerSparse mask2; //: param auto Mask3.channel_blendingmask uniform SamplerSparse mask3; ///////////////////////////////////////// ////////// BLENDING FUNCTIONS /////////// ///////////////////////////////////////// float mixGrayscale( float channelSampled[NB_MATERIALS], float Masks[NB_MASKS]) { float result = channelSampled[0]; for (int i = 0; i < NB_MASKS; i++) result = mix(result, channelSampled[i + 1], Masks[i]); return result; } vec3 mixColor( vec3 channelSampled[NB_MATERIALS], float Masks[NB_MASKS]) { vec3 result = channelSampled[0]; for (int i = 0; i < NB_MASKS; i++) result = mix(result, channelSampled[i + 1], Masks[i]); return result; } vec3 mixNormal( vec3 channelSampled[NB_MATERIALS], float Masks[NB_MASKS], float NormalIntensity[NB_MATERIALS]) { vec3 result = NormalIntensity[0] * channelSampled[0]; for (int i = 0; i < NB_MASKS; i++) result = mix(result, NormalIntensity[i + 1] * channelSampled[i + 1], Masks[i]); return result; } vec3 NormalFromMask(SamplerSparse Mask, float Offset, float Intensity, SparseCoord UVs, float refMask) { vec4 results[2]; vec2 offsets[2] = vec2[2]( vec2(Offset * 0.001, 0.0), vec2(0.0, Offset * 0.001) ); textureSparseOffsets(Mask, UVs, offsets, results); float Channel1 = results[0].r - refMask; float Channel2 = results[1].r - refMask; return vec3(-Intensity * Channel1, -Intensity * Channel2, 1.0); } vec3 NormalFromMasks( vec3 normalFromMaskSampled[NB_MASKS], float Masks[NB_MASKS]) { vec3 result = normalFromMaskSampled[0]; for (int i = 1; i < NB_MASKS; i++) result = mix(result, normalFromMaskSampled[i], Masks[i]); return result; } void shade(V2F inputs) {
//: param auto texture_normal; 
uniform sampler2D mesh_normal_texture; 
 
//: param custom { "default": 5, "label": "Material 1 coords", "min": 0.01, "max": 128.0, "group" : "Material 1" } 
uniform float u_coords1; 
 
//: param custom { "default": 5, "label": "Material 2 coords", "min": 0.01, "max": 128.0, "group" : "Material 2" } 
uniform float u_coords2; 
 
//: param custom { "default": 5, "label": "Material 3 coords", "min": 0.01, "max": 128.0, "group" : "Material 3" } 
uniform float u_coords3; 
 
//: param custom { "default": 5, "label": "Material 4 coords", "min": 0.01, "max": 128.0, "group" : "Material 4" } 
uniform float u_coords4; 
 
 
//: param custom { "default": 1, "label": "Normal Intensity 1", "min": 0.0, "max": 1.0, "group" : "Material 1" } 
uniform float normal_intensity1; 
 
//: param custom { "default": 1, "label": "Normal Intensity 2", "min": 0.0, "max": 1.0, "group" : "Material 2" } 
uniform float normal_intensity2; 
 
//: param custom { "default": 1, "label": "Normal Intensity 3", "min": 0.0, "max": 1.0, "group" : "Material 3" } 
uniform float normal_intensity3; 
 
//: param custom { "default": 1, "label": "Normal Intensity 4", "min": 0.0, "max": 1.0, "group" : "Material 4" } 
uniform float normal_intensity4; 
 
 
//: param custom { "default": 0, "label": "Normal from Mask Intensity 2", "min": -10.0, "max": 10.0, "group" : "Material 2" } 
uniform float mask_normal_intensity1; 
 
//: param custom { "default": 0, "label": "Normal from Mask Intensity 3", "min": -10.0, "max": 10.0, "group" : "Material 3" } 
uniform float mask_normal_intensity2; 
 
//: param custom { "default": 0, "label": "Normal from Mask Intensity 4", "min": -10.0, "max": 10.0, "group" : "Material 4" } 
uniform float mask_normal_intensity3; 
 
 
//: param custom { "default": 0.1, "label": "Normal from Mask 1 Offset", "min": 0.0, "max": 1, "group" : "Material 2" } 
uniform float mask_normal_offset1; 
 
//: param custom { "default": 0.1, "label": "Normal from Mask 2 Offset", "min": 0.0, "max": 1, "group" : "Material 3" } 
uniform float mask_normal_offset2; 
 
//: param custom { "default": 0.1, "label": "Normal from Mask 3 Offset", "min": 0.0, "max": 1, "group" : "Material 4" } 
uniform float mask_normal_offset3; 
 
 
//: param auto Material1.channel_basecolor 
uniform sampler2D color1; 
 
//: param auto Material1.channel_roughness 
uniform sampler2D rough1; 
 
//: param auto Material1.channel_metallic 
uniform sampler2D metal1; 
 
//: param auto Material1.channel_normal 
uniform sampler2D normal1; 
 
 
//: param auto Material2.channel_basecolor 
uniform sampler2D color2; 
 
//: param auto Material2.channel_roughness 
uniform sampler2D rough2; 
 
//: param auto Material2.channel_metallic 
uniform sampler2D metal2; 
 
//: param auto Material2.channel_normal 
uniform sampler2D normal2; 
 
 
//: param auto Material3.channel_basecolor 
uniform sampler2D color3; 
 
//: param auto Material3.channel_roughness 
uniform sampler2D rough3; 
 
//: param auto Material3.channel_metallic 
uniform sampler2D metal3; 
 
//: param auto Material3.channel_normal 
uniform sampler2D normal3; 
 
 
//: param auto Material4.channel_basecolor 
uniform sampler2D color4; 
 
//: param auto Material4.channel_roughness 
uniform sampler2D rough4; 
 
//: param auto Material4.channel_metallic 
uniform sampler2D metal4; 
 
//: param auto Material4.channel_normal 
uniform sampler2D normal4; 
 
 
//: param auto Mask.channel_blendingmask 
uniform SamplerSparse mask; 
 
//: param auto Mask2.channel_blendingmask 
uniform SamplerSparse mask2; 
 
//: param auto Mask3.channel_blendingmask 
uniform SamplerSparse mask3; 
 
///////////////////////////////////////// 
////////// BLENDING FUNCTIONS /////////// 
///////////////////////////////////////// 
 
float mixGrayscale( 
 float channelSampled[NB_MATERIALS], 
 float Masks[NB_MASKS]) 
{ 
 float result = channelSampled[0]; 
 for (int i = 0; i < NB_MASKS; i++) 
  result = mix(result, channelSampled[i + 1], Masks[i]); 
 
 return result; 
} 
 
vec3 mixColor( 
 vec3 channelSampled[NB_MATERIALS], 
 float Masks[NB_MASKS]) 
{ 
 vec3 result = channelSampled[0]; 
 for (int i = 0; i < NB_MASKS; i++) 
  result = mix(result, channelSampled[i + 1], Masks[i]); 
 
 return result; 
} 
 
vec3 mixNormal( 
 vec3 channelSampled[NB_MATERIALS], 
 float Masks[NB_MASKS], 
 float NormalIntensity[NB_MATERIALS]) 
{ 
 vec3 result = NormalIntensity[0] * channelSampled[0]; 
 for (int i = 0; i < NB_MASKS; i++) 
  result = mix(result, NormalIntensity[i + 1] * channelSampled[i + 1], Masks[i]); 
 
 return result; 
} 
 
vec3 NormalFromMask(SamplerSparse Mask, float Offset, float Intensity, SparseCoord UVs, float refMask) 
{ 
 vec4 results[2]; 
 vec2 offsets[2] = vec2[2]( 
  vec2(Offset * 0.001, 0.0), 
  vec2(0.0, Offset * 0.001) 
 ); 
 textureSparseOffsets(Mask, UVs, offsets, results); 
 
 float Channel1 = results[0].r - refMask; 
 float Channel2 = results[1].r - refMask; 
 
 return vec3(-Intensity * Channel1, -Intensity * Channel2, 1.0); 
} 
 
vec3 NormalFromMasks( 
 vec3 normalFromMaskSampled[NB_MASKS], 
 float Masks[NB_MASKS]) 
{ 
 vec3 result = normalFromMaskSampled[0]; 
 for (int i = 1; i < NB_MASKS; i++) 
  result = mix(result, normalFromMaskSampled[i], Masks[i]); 
 
 return result; 
} 
 
 
void shade(V2F inputs) 
{

//Global textures
//Global textures
 //Global textures

// Get detail (ambient occlusion) and global (shadow) occlusion factors
float occlusion = getAO(inputs.sparse_coord) * getShadowFactor();
vec3 mesh_normal = normalUnpack(textureSparse(base_normal_texture, inputs.sparse_coord), base_normal_y_coeff);
// Get detail (ambient occlusion) and global (shadow) occlusion factors float occlusion = getAO(inputs.sparse_coord) * getShadowFactor(); vec3 mesh_normal = normalUnpack(textureSparse(base_normal_texture, inputs.sparse_coord), base_normal_y_coeff);
 // Get detail (ambient occlusion) and global (shadow) occlusion factors 
 float occlusion = getAO(inputs.sparse_coord) * getShadowFactor(); 
 vec3 mesh_normal = normalUnpack(textureSparse(base_normal_texture, inputs.sparse_coord), base_normal_y_coeff);

//Materials Masks
//Materials Masks
 //Materials Masks

float UVscale[NB_MATERIALS] = float[NB_MATERIALS](
u_coords1, u_coords2, u_coords3, u_coords4);
float NormalIntensity[NB_MATERIALS] = float[NB_MATERIALS](
normal_intensity1, normal_intensity2, normal_intensity3, normal_intensity4);
float MaskNormalOffset[NB_MASKS] = float[NB_MASKS](
mask_normal_offset1, mask_normal_offset2, mask_normal_offset3);
float MaskNormalIntensity[NB_MASKS] = float[NB_MASKS](
mask_normal_intensity1, mask_normal_intensity2, mask_normal_intensity3);
float Masks[NB_MASKS] = float[NB_MASKS](
textureSparse(mask , inputs.sparse_coord).r,
textureSparse(mask2, inputs.sparse_coord).r,
textureSparse(mask3, inputs.sparse_coord).r);
float roughSampled[NB_MATERIALS] = float[NB_MATERIALS](
getRoughness(rough1, inputs.tex_coord*UVscale[0]),
getRoughness(rough2, inputs.tex_coord*UVscale[1]),
getRoughness(rough3, inputs.tex_coord*UVscale[2]),
getRoughness(rough4, inputs.tex_coord*UVscale[3])
);
float metallicSampled[NB_MATERIALS] = float[NB_MATERIALS](
getMetallic(metal1, inputs.tex_coord*UVscale[0]),
getMetallic(metal2, inputs.tex_coord*UVscale[1]),
getMetallic(metal3, inputs.tex_coord*UVscale[2]),
getMetallic(metal4, inputs.tex_coord*UVscale[3])
);
vec3 basecolorSampled[NB_MATERIALS] = vec3[NB_MATERIALS](
getBaseColor(color1, inputs.tex_coord*UVscale[0]),
getBaseColor(color2, inputs.tex_coord*UVscale[1]),
getBaseColor(color3, inputs.tex_coord*UVscale[2]),
getBaseColor(color4, inputs.tex_coord*UVscale[3])
);
vec3 normalSampled[NB_MATERIALS] = vec3[NB_MATERIALS](
normalUnpack(texture(normal1, inputs.tex_coord*UVscale[0])),
normalUnpack(texture(normal2, inputs.tex_coord*UVscale[1])),
normalUnpack(texture(normal3, inputs.tex_coord*UVscale[2])),
normalUnpack(texture(normal4, inputs.tex_coord*UVscale[3]))
);
float UVscale[NB_MATERIALS] = float[NB_MATERIALS]( u_coords1, u_coords2, u_coords3, u_coords4); float NormalIntensity[NB_MATERIALS] = float[NB_MATERIALS]( normal_intensity1, normal_intensity2, normal_intensity3, normal_intensity4); float MaskNormalOffset[NB_MASKS] = float[NB_MASKS]( mask_normal_offset1, mask_normal_offset2, mask_normal_offset3); float MaskNormalIntensity[NB_MASKS] = float[NB_MASKS]( mask_normal_intensity1, mask_normal_intensity2, mask_normal_intensity3); float Masks[NB_MASKS] = float[NB_MASKS]( textureSparse(mask , inputs.sparse_coord).r, textureSparse(mask2, inputs.sparse_coord).r, textureSparse(mask3, inputs.sparse_coord).r); float roughSampled[NB_MATERIALS] = float[NB_MATERIALS]( getRoughness(rough1, inputs.tex_coord*UVscale[0]), getRoughness(rough2, inputs.tex_coord*UVscale[1]), getRoughness(rough3, inputs.tex_coord*UVscale[2]), getRoughness(rough4, inputs.tex_coord*UVscale[3]) ); float metallicSampled[NB_MATERIALS] = float[NB_MATERIALS]( getMetallic(metal1, inputs.tex_coord*UVscale[0]), getMetallic(metal2, inputs.tex_coord*UVscale[1]), getMetallic(metal3, inputs.tex_coord*UVscale[2]), getMetallic(metal4, inputs.tex_coord*UVscale[3]) ); vec3 basecolorSampled[NB_MATERIALS] = vec3[NB_MATERIALS]( getBaseColor(color1, inputs.tex_coord*UVscale[0]), getBaseColor(color2, inputs.tex_coord*UVscale[1]), getBaseColor(color3, inputs.tex_coord*UVscale[2]), getBaseColor(color4, inputs.tex_coord*UVscale[3]) ); vec3 normalSampled[NB_MATERIALS] = vec3[NB_MATERIALS]( normalUnpack(texture(normal1, inputs.tex_coord*UVscale[0])), normalUnpack(texture(normal2, inputs.tex_coord*UVscale[1])), normalUnpack(texture(normal3, inputs.tex_coord*UVscale[2])), normalUnpack(texture(normal4, inputs.tex_coord*UVscale[3])) );
 float UVscale[NB_MATERIALS] = float[NB_MATERIALS]( 
  u_coords1, u_coords2, u_coords3, u_coords4); 
 
 float NormalIntensity[NB_MATERIALS] = float[NB_MATERIALS]( 
  normal_intensity1, normal_intensity2, normal_intensity3, normal_intensity4); 
 
 float MaskNormalOffset[NB_MASKS] = float[NB_MASKS]( 
  mask_normal_offset1, mask_normal_offset2, mask_normal_offset3); 
 
 float MaskNormalIntensity[NB_MASKS] = float[NB_MASKS]( 
  mask_normal_intensity1, mask_normal_intensity2, mask_normal_intensity3); 
 
 float Masks[NB_MASKS] = float[NB_MASKS]( 
  textureSparse(mask , inputs.sparse_coord).r, 
  textureSparse(mask2, inputs.sparse_coord).r, 
  textureSparse(mask3, inputs.sparse_coord).r); 
 
 float roughSampled[NB_MATERIALS] = float[NB_MATERIALS]( 
  getRoughness(rough1, inputs.tex_coord*UVscale[0]), 
  getRoughness(rough2, inputs.tex_coord*UVscale[1]), 
  getRoughness(rough3, inputs.tex_coord*UVscale[2]), 
  getRoughness(rough4, inputs.tex_coord*UVscale[3]) 
 ); 
 
 float metallicSampled[NB_MATERIALS] = float[NB_MATERIALS]( 
  getMetallic(metal1, inputs.tex_coord*UVscale[0]), 
  getMetallic(metal2, inputs.tex_coord*UVscale[1]), 
  getMetallic(metal3, inputs.tex_coord*UVscale[2]), 
  getMetallic(metal4, inputs.tex_coord*UVscale[3]) 
 ); 
 
 vec3 basecolorSampled[NB_MATERIALS] = vec3[NB_MATERIALS]( 
  getBaseColor(color1, inputs.tex_coord*UVscale[0]), 
  getBaseColor(color2, inputs.tex_coord*UVscale[1]), 
  getBaseColor(color3, inputs.tex_coord*UVscale[2]), 
  getBaseColor(color4, inputs.tex_coord*UVscale[3]) 
 ); 
 
 vec3 normalSampled[NB_MATERIALS] = vec3[NB_MATERIALS]( 
  normalUnpack(texture(normal1, inputs.tex_coord*UVscale[0])), 
  normalUnpack(texture(normal2, inputs.tex_coord*UVscale[1])), 
  normalUnpack(texture(normal3, inputs.tex_coord*UVscale[2])), 
  normalUnpack(texture(normal4, inputs.tex_coord*UVscale[3])) 
 );

//Mixing
//Mixing
 //Mixing

float roughness = mixGrayscale(roughSampled, Masks);
float metallic = mixGrayscale(metallicSampled, Masks);
vec3 basecolor = mixColor(basecolorSampled, Masks);
vec3 diffColor = generateDiffuseColor(basecolor, metallic);
vec3 specColor = generateSpecularColor(basecolor, metallic);
float specOcclusion = specularOcclusionCorrection(occlusion, metallic, roughness);
//Normal channel
vec3 normal = mixNormal(normalSampled, Masks, NormalIntensity);
normal = normalize( vec3(normal.xy + mesh_normal.xy, mesh_normal.z) ); //UDN combine method
vec3 finalNormal = normal;
vec3 normalMask = vec3(0.0, 0.0, 1.0);
if( UseNormalFromMask )
{
vec3 normalFromMaskSampled[NB_MASKS] = vec3[NB_MASKS](
NormalFromMask(mask , MaskNormalOffset[0], MaskNormalIntensity[0], inputs.sparse_coord, Masks[0]),
NormalFromMask(mask2, MaskNormalOffset[1], MaskNormalIntensity[1], inputs.sparse_coord, Masks[1]),
NormalFromMask(mask3, MaskNormalOffset[2], MaskNormalIntensity[2], inputs.sparse_coord, Masks[2])
);
normalMask = NormalFromMasks(normalFromMaskSampled, Masks);
finalNormal = normalize( vec3(finalNormal.xy + normalMask.xy, finalNormal.z) ); //UDN combine method
}
float roughness = mixGrayscale(roughSampled, Masks); float metallic = mixGrayscale(metallicSampled, Masks); vec3 basecolor = mixColor(basecolorSampled, Masks); vec3 diffColor = generateDiffuseColor(basecolor, metallic); vec3 specColor = generateSpecularColor(basecolor, metallic); float specOcclusion = specularOcclusionCorrection(occlusion, metallic, roughness); //Normal channel vec3 normal = mixNormal(normalSampled, Masks, NormalIntensity); normal = normalize( vec3(normal.xy + mesh_normal.xy, mesh_normal.z) ); //UDN combine method vec3 finalNormal = normal; vec3 normalMask = vec3(0.0, 0.0, 1.0); if( UseNormalFromMask ) { vec3 normalFromMaskSampled[NB_MASKS] = vec3[NB_MASKS]( NormalFromMask(mask , MaskNormalOffset[0], MaskNormalIntensity[0], inputs.sparse_coord, Masks[0]), NormalFromMask(mask2, MaskNormalOffset[1], MaskNormalIntensity[1], inputs.sparse_coord, Masks[1]), NormalFromMask(mask3, MaskNormalOffset[2], MaskNormalIntensity[2], inputs.sparse_coord, Masks[2]) ); normalMask = NormalFromMasks(normalFromMaskSampled, Masks); finalNormal = normalize( vec3(finalNormal.xy + normalMask.xy, finalNormal.z) ); //UDN combine method }
 float roughness = mixGrayscale(roughSampled, Masks); 
 float metallic = mixGrayscale(metallicSampled, Masks); 
 vec3 basecolor = mixColor(basecolorSampled, Masks); 
 vec3 diffColor = generateDiffuseColor(basecolor, metallic); 
 vec3 specColor = generateSpecularColor(basecolor, metallic); 
 float specOcclusion = specularOcclusionCorrection(occlusion, metallic, roughness); 
 
 //Normal channel 
 vec3 normal = mixNormal(normalSampled, Masks, NormalIntensity); 
 normal = normalize( vec3(normal.xy + mesh_normal.xy, mesh_normal.z) ); //UDN combine method 
 
 vec3 finalNormal = normal; 
 vec3 normalMask = vec3(0.0, 0.0, 1.0); 
 
 if( UseNormalFromMask ) 
 { 
  vec3 normalFromMaskSampled[NB_MASKS] = vec3[NB_MASKS]( 
   NormalFromMask(mask , MaskNormalOffset[0], MaskNormalIntensity[0], inputs.sparse_coord, Masks[0]), 
   NormalFromMask(mask2, MaskNormalOffset[1], MaskNormalIntensity[1], inputs.sparse_coord, Masks[1]), 
   NormalFromMask(mask3, MaskNormalOffset[2], MaskNormalIntensity[2], inputs.sparse_coord, Masks[2]) 
  ); 
 
  normalMask = NormalFromMasks(normalFromMaskSampled, Masks); 
  finalNormal = normalize( vec3(finalNormal.xy + normalMask.xy, finalNormal.z) ); //UDN combine method 
 }

//Final
//Final
 //Final

//Debug mode display result of combined channels or Masks
if( !DebugMode ) {
vec3 finalNormalWorldSpace = normalize(
finalNormal.x * inputs.tangent +
finalNormal.y * inputs.bitangent +
finalNormal.z * inputs.normal);
// Feed parameters for a physically based BRDF integration.
LocalVectors vectors = computeLocalFrame(inputs, finalNormalWorldSpace, 0.0);
emissiveColorOutput(pbrComputeEmissive(emissive_tex, inputs.sparse_coord));
diffuseShadingOutput(occlusion * pbrComputeDiffuse(vectors.normal, diffColor));
specularShadingOutput(specOcclusion * pbrComputeSpecular(vectors, specColor, roughness));
} else {
vec3 result;
//BaseColor combined
if( DebugChannel == 0 ) {
result = basecolor;
}
//Roughness combined
else if( DebugChannel == 1 ) {
result = vec3(roughness);
}
//Metallic combined
else if( DebugChannel == 2 ) {
result = vec3(metallic);
}
//Normal combined
else if( DebugChannel == 3) {
normal = 0.5 * normal + vec3(0.5);
result = sRGB2linear(normal);
}
//Combined masks as Normal
else if( DebugChannel == 4 ) {
normalMask = 0.5 * normalMask + vec3(0.5);
result = sRGB2linear(normalMask);
}
//Final Normal
else if( DebugChannel == 5 ) {
finalNormal = 0.5 * finalNormal + vec3(0.5);
result = sRGB2linear(finalNormal);
}
//Mask(s)
else {
result = vec3(sRGB2linear(Masks[DebugChannel - 6]));
}
diffuseShadingOutput(result);
}
}
//Debug mode display result of combined channels or Masks if( !DebugMode ) { vec3 finalNormalWorldSpace = normalize( finalNormal.x * inputs.tangent + finalNormal.y * inputs.bitangent + finalNormal.z * inputs.normal); // Feed parameters for a physically based BRDF integration. LocalVectors vectors = computeLocalFrame(inputs, finalNormalWorldSpace, 0.0); emissiveColorOutput(pbrComputeEmissive(emissive_tex, inputs.sparse_coord)); diffuseShadingOutput(occlusion * pbrComputeDiffuse(vectors.normal, diffColor)); specularShadingOutput(specOcclusion * pbrComputeSpecular(vectors, specColor, roughness)); } else { vec3 result; //BaseColor combined if( DebugChannel == 0 ) { result = basecolor; } //Roughness combined else if( DebugChannel == 1 ) { result = vec3(roughness); } //Metallic combined else if( DebugChannel == 2 ) { result = vec3(metallic); } //Normal combined else if( DebugChannel == 3) { normal = 0.5 * normal + vec3(0.5); result = sRGB2linear(normal); } //Combined masks as Normal else if( DebugChannel == 4 ) { normalMask = 0.5 * normalMask + vec3(0.5); result = sRGB2linear(normalMask); } //Final Normal else if( DebugChannel == 5 ) { finalNormal = 0.5 * finalNormal + vec3(0.5); result = sRGB2linear(finalNormal); } //Mask(s) else { result = vec3(sRGB2linear(Masks[DebugChannel - 6])); } diffuseShadingOutput(result); } }
 //Debug mode display result of combined channels or Masks 
 if( !DebugMode ) { 
  vec3 finalNormalWorldSpace = normalize( 
   finalNormal.x * inputs.tangent + 
   finalNormal.y * inputs.bitangent + 
   finalNormal.z * inputs.normal); 
  // Feed parameters for a physically based BRDF integration. 
  LocalVectors vectors = computeLocalFrame(inputs, finalNormalWorldSpace, 0.0); 
  emissiveColorOutput(pbrComputeEmissive(emissive_tex, inputs.sparse_coord)); 
  diffuseShadingOutput(occlusion * pbrComputeDiffuse(vectors.normal, diffColor)); 
  specularShadingOutput(specOcclusion * pbrComputeSpecular(vectors, specColor, roughness)); 
 } else { 
  vec3 result; 
 
  //BaseColor combined 
  if( DebugChannel == 0 ) { 
   result = basecolor; 
  } 
 
  //Roughness combined 
  else if( DebugChannel == 1 ) { 
   result = vec3(roughness); 
  } 
 
  //Metallic combined 
  else if( DebugChannel == 2 ) { 
   result = vec3(metallic); 
  } 
 
  //Normal combined 
  else if( DebugChannel == 3) { 
   normal = 0.5 * normal + vec3(0.5); 
   result = sRGB2linear(normal); 
  } 
 
  //Combined masks as Normal 
  else if( DebugChannel == 4 ) { 
   normalMask = 0.5 * normalMask + vec3(0.5); 
   result = sRGB2linear(normalMask); 
  } 
 
  //Final Normal 
  else if( DebugChannel == 5 ) { 
   finalNormal = 0.5 * finalNormal + vec3(0.5); 
   result = sRGB2linear(finalNormal); 
  } 
 
  //Mask(s) 
  else { 
   result = vec3(sRGB2linear(Masks[DebugChannel - 6])); 
  } 
 
  diffuseShadingOutput(result); 
 } 
} 
 

Get help faster and easier

New user?