PlayCanvas PBR material shader code analysis (Pixel shader)

#version 300 es
#define varying in
out highp vec4 pc_fragColor;
#define gl_FragColor pc_fragColor
#define texture2D texture
#define textureCube texture
#define texture2DProj textureProj
#define texture2DLodEXT textureLod
#define texture2DProjLodEXT textureProjLod
#define textureCubeLodEXT textureLod
#define texture2DGradEXT textureGrad
#define texture2DProjGradEXT textureProjGrad
#define textureCubeGradEXT textureGrad
#define GL2
precision highp float;
#ifdef GL2
    precision highp sampler2DShadow;
#endif
varying vec3 vPositionW;
varying vec3 vNormalW;
uniform vec3 view_position;
uniform vec3 light_globalAmbient;
float square(float x) {
    return x*x;
}
float saturate(float x) {
    return clamp(x, 0.0, 1.0);
}
vec3 saturate(vec3 x) {
    return clamp(x, vec3(0.0), vec3(1.0));
}
vec4 dReflection;
vec3 dAlbedo;
vec3 dNormalW;
vec3 dVertexNormalW;
vec3 dViewDirW;
vec3 dReflDirW;
vec3 dDiffuseLight;
vec3 dSpecularLight;
vec3 dSpecularity;
float dGlossiness;
float dAlpha;
void getNormal() {
    dNormalW = normalize(dVertexNormalW);
}
vec3 gammaCorrectInput(vec3 color) {
    return pow(color, vec3(2.2));
}
float gammaCorrectInput(float color) {
    return pow(color, 2.2);
}
vec4 gammaCorrectInput(vec4 color) {
    return vec4(pow(color.rgb, vec3(2.2)), color.a);
}
vec4 texture2DSRGB(sampler2D tex, vec2 uv) {
    vec4 rgba = texture2D(tex, uv);
    rgba.rgb = gammaCorrectInput(rgba.rgb);
    return rgba;
}
vec4 texture2DSRGB(sampler2D tex, vec2 uv, float bias) {
    vec4 rgba = texture2D(tex, uv, bias);
    rgba.rgb = gammaCorrectInput(rgba.rgb);
    return rgba;
}
vec4 textureCubeSRGB(samplerCube tex, vec3 uvw) {
    vec4 rgba = textureCube(tex, uvw);
    rgba.rgb =gammaCorrectInput (rgba.rgb);
     return RGBA; 
} 
Vec3 gammaCorrectOutput (Vec3 Color) { 
    #ifdef the HDR 
        return Color;
     #else 
        Color + = Vec3 ( 0.0000001 );
         return POW (Color, Vec3 ( 0.45 ));
     #endif 
} 
Uniform a float Exposure;
 // linear toneMap overall color brightness adjustment 
Vec3 toneMap (Vec3 color) {
     return color * Exposure; 
} 
Vec3 addFog (Vec3 color) { 
    return color; 
} 
// here RGBM pc decoding engine is specifically modified encoding done pow (0.5) adjusted to 8.0 maximum
 Vec3 decodeRGBM (vec4 RGBM) { 
    Vec3 Color = ( 8.0 * rgbm.a) * rgbm.rgb;
     return Color * Color; 
} 
Vec3 texture2DRGBM (sampler2D TEX, vec2 UV) { 
    return decodeRGBM (texture2D (TEX, UV)); 
} 
Vec3 textureCubeRGBM (samplerCUBE TEX, Vec3 UVW) { 
    return decodeRGBM (TextureCube (TEX, UVW)); 
} 
Vec3 fixSeams (Vec3 VEC, a float mipmapIndex) {
     a float Scale = 1.0 - EXP2 (mipmapIndex) / 128.0 ;
     a float M =max (max (abs (vec.x), abs (vec.y)), abs (vec.z));
    if(abs (vec.x)! = M) + = vec.x scale;
    if (abs (vec.y)! = M) + = vec.y scale;
    if (abs (vec.z)! = M) + = vec.z scale;
    return item; 
} 
Vec3 fixSeams (vec3 case) { 
    float scale = 1.0 - 1.0 / 128.0 ;
    float M = max (max (abs (vec.x), abs (vec.y)), abs (vec.z));
    if (abs (vec.x)! = M) + = vec.x scale;
    if (abs (vec.y)! = M) + = vec.y scale;
    if (abs (vec.z)! = M) + = vec.z scale;
    return item; 
}
vec3 fixSeamsStatic(vec3 vec, float invRecMipSize) {
    float scale = invRecMipSize;
    float M = max(max(abs(vec.x), abs(vec.y)), abs(vec.z));
    if (abs(vec.x) != M) vec.x *= scale;
    if (abs(vec.y) != M) vec.y *= scale;
    if (abs(vec.z) != M) vec.z *= scale;
    return vec;
}
vec3 cubeMapProject(vec3 dir) {
    return dir;
}
vec3 processEnvironment(vec3 color) {
    return color;
}
#undef MAPFLOAT

#undef MAPCOLOR

#undef MAPVERTEX

#undef MAPTEXTURE
#ifdef MAPCOLOR
    uniform vec3 material_diffuse;
#endif
#ifdef MAPTEXTURE
    uniform sampler2D texture_diffuseMap;
#endif
// 获取基础色
void getAlbedo() {
    dAlbedo = vec3(1.0);
    #ifdef MAPCOLOR
        dAlbedo *= material_diffuse.rgb;
    #endif
    #ifdef MAPTEXTURE
        dAlbedo *= texture2DSRGB(texture_diffuseMap, UV).CH;
    #endif
    #ifdef MAPVERTEX
        dAlbedo *= gammaCorrectInput(saturate(vVertexColor.VC));
    #endif
}
#undef MAPFLOAT

#undef MAPCOLOR
#define MAPCOLOR

#undef MAPVERTEX

#undef MAPTEXTURE
#ifdef MAPCOLOR
    uniform vec3 material_emissive;
#endif
#ifdef MAPFLOAT
    uniform float material_emissiveIntensity;
#endif
#ifdef MAPTEXTURE
    uniform sampler2D texture_emissiveMap;
#endif
// 获取自发光颜色
vec3 getEmission() {
    vec3 emission = vec3(1.0);
    #ifdef MAPFLOAT
        emission *= material_emissiveIntensity;
    #endif
    #ifdef MAPCOLOR
        emission *= material_emissive;
    #endif
    #ifdef MAPTEXTURE
        emission *= texture2DSAMPLE(texture_emissiveMap, UV).CH;
    #endif
    #ifdef MAPVERTEX
        emission *= gammaCorrectInput(saturate(vVertexColor.VC));
    #endif
    return emission;
}
float antiAliasGlossiness(float power) {
    return power;
}
#undef MAPFLOAT
#define MAPFLOAT

#undef mapcolor #undef MAPVERTEX #undef MAPTEXTURE
 // by the metallic mirror reflection intensity coefficient calculating individual color channels, adjust brightness of the color base color void processMetalness ( a float metalness) {
     const a float dielectricF0 = 0.04 ; 
    dSpecularity = Mix (Vec3 (dielectricF0), dAlbedo, metalness); 
    dAlbedo * = 1.0 - metalness; 
} 
#ifdef MAPFLOAT 
    Uniform a float material_metalness;
 #endif 
#ifdef MAPTEXTURE 
    Uniform sampler2D texture_metalnessMap; #endif //




 

 Get the specular reflection intensity coefficient 
void getSpecularity() {
    float metalness = 1.0;
    #ifdef MAPFLOAT
        metalness *= material_metalness;
    #endif
    #ifdef MAPTEXTURE
        metalness *= texture2D(texture_metalnessMap, UV).CH;
    #endif
    #ifdef MAPVERTEX
        metalness *= saturate(vVertexColor.VC);
    #endif
    processMetalness(metalness);
}
#undef MAPFLOAT
#define MAPFLOAT

#undef MAPCOLOR

#undef MAPVERTEX

#undef MAPTEXTURE
#ifdef MAPFLOAT
    uniform float material_shininess;
#endif
#ifdef MAPTEXTURE
    uniform sampler2D texture_glossMap;
#endif
// 计算光泽度
void getGlossiness() {
    dGlossiness = 1.0;
    #ifdef MAPFLOAT
        dGlossiness *= material_shininess;
    #endif
    #ifdef MAPTEXTURE
        dGlossiness *= texture2D(texture_glossMap, UV).CH;
    #endif
    #ifdef MAPVERTEX
        dGlossiness *= saturate(vVertexColor.VC);
    #endif
    dGlossiness = + 0.0000001 ; 
} 
// Schlick apos approximation 
Uniform a float material_fresnelFactor; // unused
 // calculate and adjust the Fresnel coefficients of specular reflectance 
void getFresnel () {
     a float Fresnel = 1.0 - max (DOT (dNormalW, dViewDirW), 0.0 );
     a float fresnel2 * = Fresnel Fresnel; 
    Fresnel * * = fresnel2 fresnel2; 
    Fresnel * * = dGlossiness dGlossiness; 
    dSpecularity = dSpecularity + ( 1.0 - dSpecularity) * Fresnel; 
} 
#ifndef PMREM4
    #define PMREM4
    uniform samplerCube texture_prefilteredCubeMap128;
#endif
uniform float material_reflectivity;
// 添加ibl全局光镜面反射颜色
void addReflection() {
    float bias = saturate(1.0 - dGlossiness) * 5.0; // multiply by max mip level
    
    #ifdef ENABLE_ENVROT
        vec3 fixedReflDir = fixSeams(cubeMapProject(environmentRotate(dReflDirW)), bias);
    #else
        vec3 fixedReflDir = fixSeams(cubeMapProject(dReflDirW), bias);
    #endif
    fixedReflDir.x *= -1.0 ; 
    Vec3 REFL = processEnvironment (decodeRGBM (textureCubeLodEXT (texture_prefilteredCubeMap128, fixedReflDir, BIAS)) .rgb); 
    dReflection + = vec4 (REFL, material_reflectivity); 
} 
// Diffuse color base * * (1.0 - specular reflection intensity ) + (+ ambient reflected specular reflection) * specular reflection intensity
 // here directly diffusely reflected light contains light + IBL global 
Vec3 combineColor () {
     return Mix (dAlbedo * dDiffuseLight, dSpecularLight * + dReflection.rgb dReflection.a, dSpecularity) ; 
} 
#ifndef PMREM4 
    #define PMREM4 
    Uniform samplerCUBE texture_prefilteredCubeMap128; 
#endif 

// Get global light diffuse color ibl
 void addAmbient() {
    #ifdef ENABLE_ENVROT
        vec3 fixedReflDir = fixSeamsStatic(environmentRotate(dNormalW), 1.0 - 1.0 / 4.0);
    #else
        vec3 fixedReflDir = fixSeamsStatic(dNormalW, 1.0 - 1.0 / 4.0);
    #endif
    fixedReflDir.x *= -1.0;
    dDiffuseLight += processEnvironment(decodeRGBM( textureCubeLodEXT(texture_prefilteredCubeMap128, fixedReflDir, 5.0) ).rgb);
}
// 获取V向量
void getViewDir() {
    dViewDirWThe normalize = (view_position - vPositionW); 
} 
// Get R vector 
void getReflDir () { 
    dReflDirW = the normalize (- the reflect (dViewDirW, dNormalW)); 
} 
void main ( void ) {
     // diffuse color 
    dDiffuseLight = Vec3 ( 0 ) ;
     // specular color 
    dSpecularLight = Vec3 ( 0 );
     // IBL global environment reflection 
    dReflection = vec4 ( 0 );
     // specular reflection intensity coefficient 
    dSpecularity = Vec3 ( 0 );
     // vertex world space normal 
    dVertexNormalW =vNormalW; 
    dAlpha = 1.0 ; 
    getViewDir (); // calculate View - POS 
    getNormal (); // computing world space normal 
    getReflDir (); // calculate the reflectance direction 
    getAlbedo (); // calculate base color, generally take diffuseMap, vertex color, diffuse color of the material taken directly 
    getSpecularity (); // calculate the intensity of the specular reflection coefficient, the intensity of the specular reflection coefficient calculated by the metal, the metal is stronger the larger the intensity of the reflected diffusely reflected weaker, the weaker the intensity of reflective metal the stronger the small diffuse color, specular reflection and diffuse reflection and thus energy conservation comply 
    getGlossiness (); // calculate gloss (roughness corresponding to the contrary, it is called) to the material by an external factor or set down gloss texture acquisition 
    getFresnel ( );   // calculate Fresnel effect 
    addAmbient (); // calculate the color of the ambient light (indirect light diffuse color)
    addReflection (); // calculate the reflection of ambient light (indirect light specular highlight color) 
    gl_FragColor.rgb combineColor = (); // a combination of diffuse reflection, base color, the specular reflection output color 
    gl_FragColor.rgb getEmission + = (); // accumulated since emission color 
    gl_FragColor.rgb = addFog (gl_FragColor.rgb); // atomization calculated 
    #ifndef the HDR 
        gl_FragColor.rgb = toneMap (gl_FragColor.rgb); // tonemap calculating 
        gl_FragColor.rgb = gammaCorrectOutput (gl_FragColor.rgb); / / Gamma correction color space back gama 
    #endif 
    gl_FragColor.a = 1.0 ; 
}

 

Guess you like

Origin www.cnblogs.com/zzatp/p/11497020.html