|
| 1 | +module.exports = [ |
| 2 | + '// diffuse just use lambert', |
| 3 | + '', |
| 4 | + 'vec4 BRDF_Diffuse_Lambert(vec4 diffuseColor) {', |
| 5 | + ' return RECIPROCAL_PI * diffuseColor;', |
| 6 | + '}', |
| 7 | + '', |
| 8 | + '// specular use Cook-Torrance microfacet model, http://ruh.li/GraphicsCookTorrance.html', |
| 9 | + '// About RECIPROCAL_PI: referenced by http://www.joshbarczak.com/blog/?p=272', |
| 10 | + '', |
| 11 | + 'vec4 F_Schlick( const in vec4 specularColor, const in float dotLH ) {', |
| 12 | + ' // Original approximation by Christophe Schlick '94', |
| 13 | + ' float fresnel = pow( 1.0 - dotLH, 5.0 );', |
| 14 | + '', |
| 15 | + ' // Optimized variant (presented by Epic at SIGGRAPH '13)', |
| 16 | + ' // float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );', |
| 17 | + '', |
| 18 | + ' return ( 1.0 - specularColor ) * fresnel + specularColor;', |
| 19 | + '}', |
| 20 | + '', |
| 21 | + '// use blinn phong instead of phong', |
| 22 | + 'float D_BlinnPhong( const in float shininess, const in float dotNH ) {', |
| 23 | + ' // ( shininess * 0.5 + 1.0 ), three.js do this, but why ???', |
| 24 | + ' return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );', |
| 25 | + '}', |
| 26 | + '', |
| 27 | + 'float G_BlinnPhong_Implicit( /* const in float dotNL, const in float dotNV */ ) {', |
| 28 | + ' // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v)', |
| 29 | + ' return 0.25;', |
| 30 | + '}', |
| 31 | + '', |
| 32 | + 'vec4 BRDF_Specular_BlinnPhong(vec4 specularColor, vec3 N, vec3 L, vec3 V, float shininess) {', |
| 33 | + ' vec3 H = normalize(L + V);', |
| 34 | + '', |
| 35 | + ' float dotNH = saturate(dot(N, H));', |
| 36 | + ' float dotLH = saturate(dot(L, H));', |
| 37 | + '', |
| 38 | + ' vec4 F = F_Schlick(specularColor, dotLH);', |
| 39 | + '', |
| 40 | + ' float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ );', |
| 41 | + '', |
| 42 | + ' float D = D_BlinnPhong(shininess, dotNH);', |
| 43 | + '', |
| 44 | + ' return F * G * D;', |
| 45 | + '}', |
| 46 | + '', |
| 47 | + '// Microfacet Models for Refraction through Rough Surfaces - equation (33)', |
| 48 | + '// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html', |
| 49 | + '// alpha is "roughness squared" in Disney’s reparameterization', |
| 50 | + 'float D_GGX( const in float alpha, const in float dotNH ) {', |
| 51 | + '', |
| 52 | + ' float a2 = pow2( alpha );', |
| 53 | + '', |
| 54 | + ' float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1', |
| 55 | + '', |
| 56 | + ' return RECIPROCAL_PI * a2 / pow2( denom );', |
| 57 | + '', |
| 58 | + '}', |
| 59 | + '', |
| 60 | + '// Microfacet Models for Refraction through Rough Surfaces - equation (34)', |
| 61 | + '// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html', |
| 62 | + '// alpha is "roughness squared" in Disney’s reparameterization', |
| 63 | + 'float G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {', |
| 64 | + '', |
| 65 | + ' // geometry term = G(l)⋅G(v) / 4(n⋅l)(n⋅v)', |
| 66 | + '', |
| 67 | + ' float a2 = pow2( alpha );', |
| 68 | + '', |
| 69 | + ' float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );', |
| 70 | + ' float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );', |
| 71 | + '', |
| 72 | + ' return 1.0 / ( gl * gv );', |
| 73 | + '', |
| 74 | + '}', |
| 75 | + '', |
| 76 | + '// Moving Frostbite to Physically Based Rendering 2.0 - page 12, listing 2', |
| 77 | + '// http://www.frostbite.com/wp-content/uploads/2014/11/course_notes_moving_frostbite_to_pbr_v2.pdf', |
| 78 | + 'float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {', |
| 79 | + '', |
| 80 | + ' float a2 = pow2( alpha );', |
| 81 | + '', |
| 82 | + ' // dotNL and dotNV are explicitly swapped. This is not a mistake.', |
| 83 | + ' float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );', |
| 84 | + ' float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );', |
| 85 | + '', |
| 86 | + ' return 0.5 / max( gv + gl, EPSILON );', |
| 87 | + '}', |
| 88 | + '', |
| 89 | + '// GGX Distribution, Schlick Fresnel, GGX-Smith Visibility', |
| 90 | + 'vec4 BRDF_Specular_GGX(vec4 specularColor, vec3 N, vec3 L, vec3 V, float roughness) {', |
| 91 | + '', |
| 92 | + ' float alpha = pow2( roughness ); // UE4's roughness', |
| 93 | + '', |
| 94 | + ' vec3 H = normalize(L + V);', |
| 95 | + '', |
| 96 | + ' float dotNL = saturate( dot(N, L) );', |
| 97 | + ' float dotNV = saturate( dot(N, V) );', |
| 98 | + ' float dotNH = saturate( dot(N, H) );', |
| 99 | + ' float dotLH = saturate( dot(L, H) );', |
| 100 | + '', |
| 101 | + ' vec4 F = F_Schlick( specularColor, dotLH );', |
| 102 | + '', |
| 103 | + ' float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );', |
| 104 | + '', |
| 105 | + ' float D = D_GGX( alpha, dotNH );', |
| 106 | + '', |
| 107 | + ' return F * G * D;', |
| 108 | + '', |
| 109 | + '}', |
| 110 | + '', |
| 111 | + '// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile', |
| 112 | + 'vec4 BRDF_Specular_GGX_Environment( const in vec3 N, const in vec3 V, const in vec4 specularColor, const in float roughness ) {', |
| 113 | + '', |
| 114 | + ' float dotNV = saturate( dot( N, V ) );', |
| 115 | + '', |
| 116 | + ' const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );', |
| 117 | + '', |
| 118 | + ' const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );', |
| 119 | + '', |
| 120 | + ' vec4 r = roughness * c0 + c1;', |
| 121 | + '', |
| 122 | + ' float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;', |
| 123 | + '', |
| 124 | + ' vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;', |
| 125 | + '', |
| 126 | + ' return specularColor * AB.x + AB.y;', |
| 127 | + '', |
| 128 | + '}', |
| 129 | + '', |
| 130 | + '// source: http://simonstechblog.blogspot.ca/2011/12/microfacet-brdf.html', |
| 131 | + 'float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {', |
| 132 | + ' return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );', |
| 133 | + '}', |
| 134 | + '', |
| 135 | + 'float BlinnExponentToGGXRoughness( const in float blinnExponent ) {', |
| 136 | + ' return sqrt( 2.0 / ( blinnExponent + 2.0 ) );', |
| 137 | + '}' |
| 138 | +].join('\n'); |
0 commit comments