Understanding Allegorithmic Substance Designer custom shader.1


How to you would customizing for Allegorithmic Designer additional shaders.

Resource path at below...
C:\Program Files\Allegorithmic\Substance\Designer\4.x\resources\view3d\shaders

and we have to understand data structure.
This shader package struckture has XML format container with each type glsl shader code for example like physically_based.glslfx is xml data defined data and then fs.glsl with vs.glsl from physically_based sub folder.

concatenation link.
http://leegoonz.blogspot.kr/2014/04/wip-tutorialsunderstanding.html

below code is physically_based.glslfx that is like xml data format style.
It is just defined scripting code.
this sample code is C:\Program Files\Allegorithmic\Substance\Designer\4.x\resources\view3d\shaders\physically_based



    
    
        
        
        
        
        
        
        
        
    

    
    
    
    
    
    

    
    
    
    
    
    
    
    
    
    

    
    
    
    
    
    
    
    

    
    
    
    
    
    
    
    

    
    
    
    

    
    
    
    
    




Vertex Shader.

/////////////////////////////// Vertex shader
#version 120

attribute vec4 iVS_Position;
attribute vec4 iVS_Normal;
attribute vec2 iVS_UV;
attribute vec4 iVS_Tangent;
attribute vec4 iVS_Binormal;

varying vec3 iFS_Normal;
varying vec2 iFS_UV;
varying vec3 iFS_Tangent;
varying vec3 iFS_Binormal;
varying vec3 iFS_PointWS;

uniform mat4 worldMatrix;
uniform mat4 worldViewProjMatrix;
uniform mat4 worldInverseTransposeMatrix;

void main()
{
    gl_Position = worldViewProjMatrix * iVS_Position;
    iFS_Normal = (worldInverseTransposeMatrix * iVS_Normal).xyz;
    iFS_UV = iVS_UV;
    iFS_Tangent = (worldInverseTransposeMatrix * iVS_Tangent).xyz;
    iFS_Binormal = (worldInverseTransposeMatrix * iVS_Binormal).xyz;
    iFS_PointWS = (worldMatrix * iVS_Position).xyz;
}




and then glsl code at below.
Fragment shader

//////////////////////////////// Fragment shader
#version 120
#extension GL_ARB_shader_texture_lod : require


#define M_PI     3.1415926535897932384626433832795
#define M_INV_PI 0.31830988618379067153776752674503
#define M_INV_LOG2 1.4426950408889634073599246810019

varying vec3 iFS_Normal;
varying vec2 iFS_UV;
varying vec3 iFS_Tangent;
varying vec3 iFS_Binormal;
varying vec3 iFS_PointWS;

uniform vec3 Lamp0Pos = vec3(0.0,0.0,70.0);
uniform vec3 Lamp0Color = vec3(1.0,1.0,1.0);
uniform float Lamp0Intensity = 1.0;
uniform vec3 Lamp1Pos = vec3(70.0,0.0,0.0);
uniform vec3 Lamp1Color = vec3(0.198,0.198,0.198);
uniform float Lamp1Intensity = 1.0;

//uniform vec3 AmbiColor;
uniform float AmbiIntensity = 1.0;

uniform float envRotation = 0.0;
uniform float Depth = 0.0;
uniform bool flipY = true;

uniform sampler2D heightMap;
uniform sampler2D normalMap;
uniform sampler2D baseColorMap;
uniform sampler2D metallicMap;
uniform sampler2D roughnessMap;
uniform sampler2D aoMap;
uniform sampler2D environmentMap;

uniform mat4 viewInverseMatrix;

// Number of miplevels in the envmap
uniform float maxLod = 12.0;

// Maximum number of samples in the table
const int maxNbSamples = 256;
// Actual number of samples in the table
uniform int nbSamples = 16;
// Sample table
uniform vec2 hammersley[maxNbSamples];

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 / (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 = pow(2.0, (-5.55473*vdh - 6.98316) * vdh);
 return F0 + (vec3(1.0, 1.0, 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 = Roughness * Roughness * 0.5;
 return G1(ndl,k)*G1(ndv,k);
}

vec3 cook_torrance_brdf(
 vec3 Nn,
 vec3 Ln,
 vec3 Vn,
 vec3 Ks,
 float Roughness)
{
 vec3 Hn = normalize(Vn + Ln);
 float vdh = max( 0.0, dot(Vn, Hn) );
 float ndh = max( 0.0, dot(Nn, Hn) );
 float ndl = max( 0.0, dot(Nn, Ln) );
 float ndv = max( 0.0, dot(Nn, Vn) );
 return fresnel(vdh,Ks) *
  ( normal_distrib(ndh,Roughness) * visibility(ndl,ndv,Roughness) / 4.0 );
}

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 diffuse_brdf(
 vec3 Nn,
 vec3 Ln,
 vec3 Vn,
 vec3 Kd)
{
 return Kd;
}

vec3 fixNormalSample(vec3 v)
{
 vec3 res = (v - vec3(0.5,0.5,0.5))*2.0;
 res.y = flipY ? -res.y : res.y;
 return res;
}

float ray_intersect_rm(    // use linear and binary search
 in sampler2D bumpmap,
 in vec2 dp,
 in vec2 ds)
{
 const int linear_search_steps=200;
 const int binary_search_steps=50;

 // current size of search window
 float size = 1.0/float(linear_search_steps);
 // current depth position
 float depth = 0.0;
 // search front to back for first point inside object
 for( int i=0;i0.0000001) ? dir.x / n : 0.0, dir.y);
 pos = acos(pos)*M_INV_PI;
 pos.x = (dir.z < 0.0) ? pos.x*0.5 : 1.0-(pos.x*0.5);
 pos.y = 1.0-pos.y;
        return texture2DLod(map, pos, lod).rgb;
}

void main()
{
 vec3 cameraPosWS = viewInverseMatrix[3].xyz;
 vec3 pointToLight0DirWS = normalize(Lamp0Pos - iFS_PointWS);
 vec3 pointToLight1DirWS = normalize(Lamp1Pos - iFS_PointWS);
 vec3 pointToCameraDirWS = normalize(cameraPosWS - iFS_PointWS);

 // ------------------------------------------
 // Update UV
 vec2 uv = iFS_UV;
 if (Depth > 0.0)
 {
  float a = dot(iFS_Normal,-pointToCameraDirWS);
  vec3 s  = vec3(
   dot(pointToCameraDirWS,iFS_Tangent),
   dot(pointToCameraDirWS,iFS_Binormal),
   a);
  s *= Depth/a*0.1;
  vec2 ds = s.xy;
  vec2 dp = uv;
  float d  = ray_intersect_rm(heightMap,dp,ds);
  uv = dp+ds*d;
 }

 // ------------------------------------------
 // Add Normal from normalMap
 vec3 fixedNormalOS = iFS_Normal;  // HACK for empty normal textures
 vec3 normalTS = texture2D(normalMap,uv).xyz;
 if(length(normalTS)>0.0001)
 {
  normalTS = fixNormalSample(normalTS);
  fixedNormalOS = normalize(
   normalTS.x*iFS_Tangent +
   normalTS.y*iFS_Binormal +
   normalTS.z*iFS_Normal );
 }

 vec3 fixedNormalWS = fixedNormalOS;

 // ------------------------------------------
 // Compute material model (diffuse, specular & roughness)
 const vec3 dielectricColor = vec3(0.04, 0.04, 0.04);
 const float minRoughness=1e-4;
 vec3 baseColor = texture2D(baseColorMap,uv).rgb;
 float metallic = texture2D(metallicMap,uv).r;
 float roughness = max(minRoughness, texture2D(roughnessMap,uv).r);

 vec3 diffColor = baseColor * (1.0 - metallic);
 vec3 specColor = mix(dielectricColor, baseColor, metallic);

 // ------------------------------------------
 // Compute point lights contributions
 vec3 contrib0 = max(dot(fixedNormalWS,pointToLight0DirWS), 0.0) * ( (
  diffuse_brdf(
   fixedNormalWS,
   pointToLight0DirWS,
   pointToCameraDirWS,
   diffColor)
  + cook_torrance_brdf(
   fixedNormalWS,
   pointToLight0DirWS,
   pointToCameraDirWS,
   specColor,
   roughness) ) *Lamp0Color*Lamp0Intensity );

 vec3 contrib1 = max(dot(fixedNormalWS,pointToLight1DirWS), 0.0) * ( (
  diffuse_brdf(
   fixedNormalWS,
   pointToLight1DirWS,
   pointToCameraDirWS,
   diffColor)
  + cook_torrance_brdf(
   fixedNormalWS,
   pointToLight1DirWS,
   pointToCameraDirWS,
   specColor,
   roughness) ) *Lamp1Color*Lamp1Intensity );

 // ------------------------------------------
 // Compute environment map contribution

 vec3 Tp = normalize(iFS_Tangent
  - fixedNormalWS*dot(iFS_Tangent, fixedNormalWS)); // local tangent
 vec3 Bp = normalize(iFS_Binormal
  - fixedNormalWS*dot(iFS_Binormal,fixedNormalWS)
  - Tp*dot(iFS_Binormal, Tp)); // local bitangent

 float ndv = max( 0.0, dot( pointToCameraDirWS, fixedNormalWS ) );

 vec3 contribE = vec3(0.0,0.0,0.0);
 for(int i=0; i0.0)
  {
   float vdh = max( 0.0, dot(pointToCameraDirWS, Hn) );
   float ndh = max( 0.0, dot(fixedNormalWS, Hn) );

   float lodS = roughness < 0.01 ? 0.0 : computeLOD(Ln,
    probabilityGGX(ndh, vdh, roughness));
   contribE +=
    samplePanoramicLOD(environmentMap,rotate(Ln,envRotation),lodS) *
    cook_torrance_contrib(
     vdh, ndh, ndl, ndv,
     specColor,
     roughness);
  }
 }
 contribE /= nbSamples;

 // Scale environment contribution
 contribE *= AmbiIntensity * texture2D(aoMap,uv).r;

 // ------------------------------------------

 vec3 finalColor = contrib0 + contrib1 + contribE;

 // Final Color
 gl_FragColor = vec4(finalColor, 1.0);
}






Game Developer Leegoon copyright all right reserved since 2010.

Comments

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Your Post Is Really So Amazing And Great Thanks...Substance Designer

    ReplyDelete

Post a Comment

덧글쓰기 기능 있는거 아시죠? ㅋㅋ

Popular Posts