Advertisement
Guest User

Untitled

a guest
Jan 25th, 2015
958
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 26.83 KB | None | 0 0
  1.  
  2.  
  3. uniform lowp sampler2D uTexture0; // decal
  4. uniform lowp sampler2D uTexture1; // normal
  5. uniform lowp sampler2D uTexture2; // specular
  6. uniform lowp sampler2D uTexture3; // gloss
  7. uniform lowp sampler2D uTexture4; // height
  8. uniform lowp sampler2D uTexture5; // ao
  9.  
  10. uniform lowp samplerCube uTexture6; // cube
  11.  
  12. uniform lowp vec4 uMaterialGloss; // { x = uGlossBias, y = uGlossHorizonSmooth }
  13. uniform lowp vec4 uMaterialPhong; // { x = uPhongBrightness, y = uPhongHorizonFade }
  14. uniform lowp vec4 uMaterialSpecularColor; // uSpecularColor
  15. uniform lowp vec4 uMaterialSpecularFrensel; // uSpecularFresnel
  16. uniform lowp vec4 uMaterialAO; //{ x = uAmbientOcclusionStrength }
  17. uniform lowp vec4 uMaterialParallax; // { xy = uParallaxDepthOffset
  18. uniform lowp vec4 uMaterialAnisotropic; // { x = uAnisoBrightness, y = uAnisoHorizonFade, z = uAnisoSpread
  19. uniform lowp vec4 uMaterialMicrofiber; //x = uAnisoBrightness, y = uMicrofiberScatter, z = uAnisoSpread
  20.  
  21. varying mediump vec3 outUV0;
  22. varying mediump vec3 outNormal;
  23. varying mediump vec3 outTangent;
  24. varying mediump vec3 outPosition;
  25. varying mediump vec3 outWorldNormal;
  26.  
  27. uniform highp vec3 uLightPos;
  28. uniform highp vec3 uLightColor;
  29. uniform highp vec3 uLightAtten;
  30. uniform highp vec3 uEyePos;
  31. uniform highp vec3 uLightDiffuseSphere[9];
  32.  
  33. #define SPECULAR_IMPORTANCE_SAMPLES 32
  34. uniform highp vec4 uPhongRands[SPECULAR_IMPORTANCE_SAMPLES];
  35.  
  36. #if USE_MATERIAL_PARAM
  37. #define uGlossBias uMaterialGloss.x
  38. #define uGlossHorizonSmooth uMaterialGloss.y
  39. #define uPhongBrightness uMaterialPhong.x
  40. #define uPhongHorizonFade uMaterialPhong.y
  41. #define uSpecularColor uMaterialSpecularColor.xyz
  42. #define uSpecularFresnel uMaterialSpecularFrensel.xyz
  43. #define uAmbientOcclusionStrength uMaterialAO.x
  44. #define uParallaxDepthOffset uMaterialParallax
  45. #define uAnisoBrightness uMaterialAnisotropic.x
  46. #define uAnisoHorizonFade uMaterialAnisotropic.y
  47. #define uAnisoSpread uMaterialAnisotropic.z
  48. #define uMicrofiberColor uMaterialMicrofiber.x
  49. #define uMicrofiberScatter uMaterialMicrofiber.y
  50. #define uMicrofiberOcc uMaterialMicrofiber.z
  51. #else
  52. const mediump float uPhongBrightness = 1.0;
  53. const mediump float uPhongHorizonFade = 1.0;
  54. const mediump float uGlossHorizonSmooth = 0.5;
  55. const mediump float uGlossBias = 1.0;//0.7
  56. const mediump vec3 uSpecularColor = vec3(1.0, 1.0, 1.0);
  57. const mediump vec3 uSpecularFresnel = vec3(1.0, 1.0, 1.0);
  58. //const vec2    uParallaxDepthOffset = vec2(0.037, 0.5);
  59. const mediump vec2  uParallaxDepthOffset = vec2(0.1, 1.0);
  60. const mediump float uAmbientOcclusionStrength = 1.0;
  61. const mediump float uAnisoBrightness = 1.0;
  62. const mediump float uAnisoHorizonFade = 1.0;
  63. const mediump float uAnisoSpread = 1.0;
  64. const mediump float uMicrofiberScatter = 0.777;
  65. const mediump float uMicrofiberOcc = 0.5;
  66. const mediump float uMicrofiberColor = 1.0;
  67. #endif
  68.  
  69.  
  70. const mediump float uMaskWithGloss = 0.0;
  71. const mediump vec3  uAnisoDirectionMapScale = vec3(2.0,2.0,2.0);
  72. const mediump vec3  uAnisoDirectionMapBias = vec3(-1.0,-1.0,-1.0);
  73. const mediump float uAnisoDirectionMapSwizzle = 0.0;
  74. const mediump vec3  uAnisoDirectionConst = vec3(1.0, 0.0, 0.0);
  75.  
  76.  
  77. //
  78. //
  79. #define uAnisoRands uPhongRands
  80.  
  81. mediump float saturate(mediump float x)
  82. {
  83.     return clamp(x, 0.0, 1.0);
  84. }
  85.  
  86. mediump vec3 saturate(mediump vec3 x)
  87. {
  88.     return clamp(x, 0.0, 1.0);
  89. }
  90.  
  91.  
  92. const lowp vec3 fvLightColor = vec3(255.0/255.0, 165.0/255.0, 79.0/255.0);
  93. //const lowp vec3 fvLightColor = vec3(1.0, 1.0, 1.0);
  94. const lowp vec3 fvLightShadow = vec3(1.0, 1.0, 1.0);
  95. //const lowp vec3 fvReflectivity = vec3(0.5, 0.5, 0.5);
  96. const lowp vec3 fvReflectivity = vec3(1.0, 1.0, 1.0);
  97. const lowp vec3 fvFresnel = vec3(1.0, 1.0, 1.0);
  98.  
  99. mediump float wrapLight(mediump float DP, mediump float scatter)
  100. {
  101.     mediump float res = saturate( DP*(1.0-scatter) + scatter );
  102.     return res;
  103. }
  104.  
  105. mediump vec3 wrapLight3(mediump float DP, mediump vec3 scatter)
  106. {
  107.     mediump vec3 res = saturate( DP*(vec3(1.0,1.0,1.0)-scatter) + scatter );
  108.     return res;
  109. }
  110.  
  111. mediump float wrapLightIntegral(mediump float scatter)
  112. {
  113.     return (1.0 / 3.14159) * (1.0 - scatter);
  114. }
  115.  
  116. mediump vec3 wrapLightIntegral3(mediump vec3 scatter)
  117. {
  118.     return (1.0 / 3.14159) * (vec3(1.0,1.0,1.0)-scatter);
  119. }
  120.  
  121. mediump float diffuseFresnel(mediump float eyeDP, mediump float scatter, mediump float occ, mediump float occWeight)
  122. {
  123.     eyeDP = 1.0 - eyeDP;
  124.     mediump float dp4 = eyeDP * eyeDP; dp4 *= dp4;
  125.     eyeDP = mix(dp4, eyeDP*0.4, scatter);       //0.4 is energy conserving integral
  126.     return mix(eyeDP, eyeDP*occ, occWeight);    //occlude with occ term
  127. }
  128.  
  129. mediump vec3 diffuseFresnel3(mediump float eyeDP, mediump float scatter, mediump vec3 occ, mediump float occWeight)
  130. {
  131.     eyeDP = 1.0 - eyeDP;
  132.     mediump float dp4 = eyeDP * eyeDP; dp4 *= dp4;
  133.     eyeDP = mix(dp4, eyeDP*0.4, scatter);       //0.4 is energy conserving integral
  134.     return mix(vec3(eyeDP,eyeDP,eyeDP), eyeDP*occ, occWeight);  //occlude with occ term
  135. }
  136.  
  137. #if 0
  138.  
  139. vec3 DirectLightingFuncGGX(float gloss, vec3 N, vec3 V, vec3 L, vec3 H, float LAtten)
  140. {
  141.     //roughness
  142.     float roughness = 1.0 - gloss;
  143.     float a = max( roughness * roughness, 2e-3 );
  144.     float a2 = a * a;
  145.  
  146.     //light params
  147.     //LightParams l = getLight( s.vertexPosition );
  148.     //adjustAreaLightSpecular( l, reflect( -s.vertexEye, s.normal ), rcp(3.141592 * a2) );
  149.  
  150.     //various dot products
  151.     //vec3 H = normalize(L + V);
  152.     float NdotH = saturate(dot(N,H));
  153.     float VdotN = saturate(dot(V,N));
  154.     float LdotN = saturate(dot(L,N));
  155.     float VdotH = saturate(dot(V,H));
  156.    
  157.     //horizon
  158.     float atten = LAtten;
  159.     float horizon = 1.0 - LdotN;
  160.     horizon *= horizon; horizon *= horizon;
  161.     atten = atten - atten * horizon;
  162.    
  163.     //incident light
  164.     vec3 spec = fvLightColor * fvLightShadow * (atten * LdotN);
  165.    
  166.     //microfacet distribution
  167.     float d = ( NdotH * a2 - NdotH ) * NdotH + 1.0;
  168.           d *= d;
  169.     float D = a2 / (3.141593 * d);
  170.  
  171.     //geometric / visibility
  172.     float k = a * 0.5;
  173.     float G_SmithL = LdotN * (1.0 - k) + k;
  174.     float G_SmithV = VdotN * (1.0 - k) + k;
  175.     float G = 0.25 / ( G_SmithL * G_SmithV );
  176.    
  177.     //fresnel
  178.     vec3 reflectivity = fvReflectivity;
  179.     vec3 fresn = fvFresnel;
  180.     vec3 F = reflectivity + (fresn - fresn*reflectivity) * exp2( (-5.55473 * VdotH - 6.98316) * VdotH );
  181.  
  182.     return (D * G) * (F * spec);
  183.    
  184.     //return vec3(LAtten);
  185.     //return vec3((G) * (F * spec));
  186.     //return vec3((D * G) * (F));
  187.     //return vec3(F);
  188. }
  189.  
  190. float sRGB_gamma_correct(float c)
  191. {
  192.     const float a = 0.055;
  193.     if(c < 0.0031308)
  194.         return 12.92*c;
  195.     else
  196.         return (1.0+a)*pow(c, 1.0/2.4) - a;
  197. }
  198. #endif
  199. mediump float rcp(mediump float x)
  200. {
  201.     return 1.0 / x;
  202. }
  203.  
  204. // constant that are used to adjust lighting
  205. const mediump float C1 = 0.429043;
  206. const mediump float C2 = 0.511664;
  207. const mediump float C3 = 0.743125;
  208. const mediump float C4 = 0.886227;
  209. const mediump float C5 = 0.247708;
  210.  
  211.  
  212. mediump vec3 toRGBM(mediump vec3 srgb)
  213. {
  214.     return pow(srgb, vec3(1.0/1.2));
  215. }
  216.  
  217. mediump vec3 toRGB(mediump vec3 srgb)
  218. {
  219.     return pow(srgb, vec3(1.0/2.2));
  220. }
  221.  
  222. mediump float tosRGBFloat(mediump float rgba)
  223. {
  224.     mediump float srgb = (rgba*rgba)*(rgba*0.2848 + 0.7152);
  225.     return srgb;
  226. }
  227.  
  228. mediump vec4 tosRGB(mediump vec4 rgba)
  229. {
  230.     mediump vec3 srgb = (rgba.xyz*rgba.xyz)*(rgba.xyz*vec3(0.2848,0.2848,0.2848) + vec3(0.7152,0.7152,0.7152));
  231.     return vec4(srgb, rgba.a);
  232. }
  233.  
  234. mediump vec3 tosRGB(mediump vec3 rgb)
  235. {
  236.     mediump vec3 srgb = (rgb.xyz*rgb.xyz)*(rgb.xyz*vec3(0.2848,0.2848,0.2848) + vec3(0.7152,0.7152,0.7152));
  237.     return srgb;
  238. }
  239.  
  240. mediump float   MicrosurfaceGlossMap(mediump vec2 uv, mediump vec3 N, mediump vec3 V)
  241. {
  242.     //float g = dot( texture2D( uTexture3, uv ), uGlossSwizzle );
  243.     mediump float g = texture2D( uTexture3, uv ).r;
  244.     mediump float gloss = g * uGlossBias;
  245.  
  246.     mediump float h = saturate( dot( N, V ) );
  247.     h = uGlossHorizonSmooth - h * uGlossHorizonSmooth;
  248.     gloss = mix( gloss, 1.0, h*h );
  249.     //return dot( N, V );
  250.     return gloss;
  251. }
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258. #define SPECULAR_IMPORTANCE_SAMPLES 32
  259.  
  260.  
  261. mediump vec3 phongImportanceSample( mediump vec4 r, mediump float specExp )
  262. {
  263.     mediump float cos_theta = pow( r.x, 1.0 / (specExp + 1.0) );
  264.     mediump float sin_theta = sqrt( 1.0 - cos_theta*cos_theta );
  265.     mediump float cos_phi = r.z;
  266.     mediump float sin_phi = r.w;
  267.     return vec3( cos_phi*sin_theta, sin_phi*sin_theta, cos_theta );
  268. }
  269.    
  270. mediump vec3 fix_cube_lookup(mediump vec3 v)
  271. {
  272. mediump float cube_size = 512.0;
  273.  mediump float M = max(max(abs(v.x), abs(v.y)), abs(v.z));
  274.  mediump float scale = (cube_size - 1.0) / cube_size;
  275.  if (abs(v.x) != M) v.x *= scale;
  276.  if (abs(v.y) != M) v.y *= scale;
  277.  if (abs(v.z) != M) v.z *= scale;
  278.  return v;
  279.  }
  280.  
  281.  mediump vec3   fresnel(    mediump float cosTheta,
  282.                     mediump vec3 reflectivity,
  283.                     mediump vec3 fresnelStrength    )
  284. {
  285.     //schlick's fresnel approximation
  286.     mediump float f = saturate( 1.0 - cosTheta );
  287.     mediump float f2 = f*f; f *= f2 * f2;
  288.     return mix( reflectivity, vec3(1.0,1.0,1.0), f*fresnelStrength );
  289. }
  290.  
  291. #if 1
  292.  
  293. #define ANISO_IMPORTANCE_SAMPLES 32
  294.  
  295. void    SampleAnisoTangent(mediump vec3 N, out mediump vec3 tangent, out mediump vec3 bitangent, mediump vec3 vertexTangent, mediump vec3 vertexBitangent, mediump vec3 vertexNormal)
  296. {
  297.     //Direction
  298.     tangent =  vec3(0.5, 0.5, 0.5);  //texture2D( tAnisoDirectionMap, s.vertexTexCoord ).xyz;
  299.     tangent = tangent * 2.0 - 1.0;
  300.  
  301.     //zero if a tangent map is present
  302.     tangent += uAnisoDirectionConst;
  303.  
  304.     //swizzle tangent and binormal directions
  305.     tangent.xy = mix(tangent.xy, tangent.yx, uAnisoDirectionMapSwizzle);
  306.  
  307.     //transform into render space
  308.     tangent = tangent.x * vertexTangent + tangent.y * vertexBitangent + tangent.z * vertexNormal;
  309.    
  310.     //project tangent onto normal plane
  311.     tangent = tangent - N*dot( tangent, N );
  312.     tangent = normalize( tangent );
  313.     bitangent = normalize( cross( N, tangent ) );
  314. }
  315.  
  316. //returns a random hemisphere vector, with probabilty weighted to a pow() lobe of 'specExp'
  317. mediump vec3    anisoImportanceSampleDirection(mediump vec4 r,mediump float specExp )
  318. {      
  319.     mediump float cos_theta = pow( r.x, 1.0 / (specExp + 1.0) );
  320.     mediump float sin_theta = sqrt( 1.0 - cos_theta*cos_theta );
  321.     mediump float cos_phi = r.z;
  322.     mediump float sin_phi = r.w;
  323.     return  vec3( cos_phi*sin_theta, sin_phi*sin_theta, cos_theta );
  324. }
  325.  
  326. mediump float computeAnisoLOD( mediump float specExp, mediump vec3 H, mediump vec3 N )
  327. {
  328.     mediump float pdf = (specExp + 4.0)/(8.0*3.14159) * pow( saturate( dot( H, N ) ), specExp );
  329.     return 0.5 * log2( (256.0*256.0)/float(ANISO_IMPORTANCE_SAMPLES) ) - 0.5 * log2( pdf ) + 0.5;
  330. }
  331.  
  332. //@TODO:!!!
  333. //#extension GL_EXT_gpu_shader4 : enable
  334.  
  335. mediump vec3 Anisotropic(mediump float gloss, mediump vec3 V, mediump vec3 N, mediump vec3 vertexTangent, mediump vec3 vertexBitangent, mediump vec3 vertexNormal, mediump vec3 reflectivity, mediump vec3 fresn)
  336. {
  337.     mediump float anisoSpread = uAnisoSpread;
  338.  
  339.     //determine specular exponent from gloss map & settings
  340.     mediump float specExp = -10.0 / log2( gloss*0.968 + 0.03 );
  341.     specExp *= specExp;
  342.  
  343.     //something happens to the importance samples at exp=16 and there's a noticeable jump --Andres
  344.     specExp = max(16.1,specExp);
  345.  
  346.     //aniso
  347.     mediump vec3 T, B; SampleAnisoTangent( N, T, B, vertexTangent, vertexBitangent, vertexNormal );
  348.     mediump vec3 E = -V;
  349.    
  350.     mediump vec3 R = reflect(E,N);
  351.        
  352.     //sample the reflection map repeatedly, with an importance-based sample distribution
  353.     mediump vec3 basisX = normalize( cross( N, vec3(0.0, 1.0, saturate(N.y*10000.0 - 9999.0) ) ) );
  354.     mediump vec3 basisY = cross( basisX, N );
  355.     mediump vec3 basisZ = N;
  356.  
  357.     mediump vec3 spec = vec3(0.0, 0.0, 0.0);
  358.  
  359.     mediump float anisoExp = 16.0;
  360.     anisoSpread = max(0.01, anisoSpread);  
  361.     mediump float invSampleCount = 1.0/float(ANISO_IMPORTANCE_SAMPLES-1);
  362.  
  363.     mediump vec3 dB = B;
  364.     mediump vec3 dT = T;
  365.  
  366.     //HINT_LOOP
  367.     for(mediump int i=0; i<ANISO_IMPORTANCE_SAMPLES; ++i )
  368.     {
  369.         mediump vec4 r = uAnisoRands[i];
  370.         mediump float ct = 1.0;
  371.         mediump float st = 0.0;
  372.         mediump float cp = 0.0;
  373.         mediump float sp = 1.0;
  374.         mediump vec3 zero = vec3(cp*st, sp*st, ct);
  375.  
  376.         mediump vec3 dirSpec =  anisoImportanceSampleDirection(r, specExp);
  377.         mediump vec3 dirAniso = anisoImportanceSampleDirection(r, anisoExp);
  378.  
  379.         //dir into world-space
  380.         dirSpec =  dirSpec.x*basisX +  dirSpec.y*basisY +  dirSpec.z*basisZ;
  381.         dirAniso = dirAniso.x*basisX + dirAniso.y*basisY + dirAniso.z*basisZ;
  382.        
  383.         mediump vec3 iT = vec3(T.x,B.x,N.x);
  384.         mediump vec3 iB = vec3(T.y,B.y,N.y);
  385.         mediump vec3 iN = vec3(T.z,B.z,N.z);
  386.  
  387.         //dir into tangent space
  388.         mediump vec3 dirCombined;
  389.         dirCombined = iT*dirSpec.x +  iB*dirSpec.y +  iN*dirSpec.z;
  390.         dirAniso =    iT*dirAniso.x + iB*dirAniso.y + iN*dirAniso.z;
  391.        
  392.         //bias the binormal components of dir by anisoSpread
  393.         mediump float lodMix = abs(dirAniso.y - dirCombined.y) * anisoSpread;
  394.         dirCombined.y = mix(dirCombined.y, dirAniso.y, anisoSpread);
  395.  
  396.         //combined dir out of tangent space
  397.         mediump vec3 hAniso = normalize(T*dirCombined.x + B*dirCombined.y + N*dirCombined.z);
  398.         mediump vec3 hSpec = dirSpec;
  399.        
  400.         //compute aniso filtering scale, cannot exceed 0.5 or cubemap borders bleed nonsense into the lookups
  401.         mediump float lodSpec =  computeAnisoLOD(specExp, hSpec, N);
  402.         lodSpec =  min(saturate(lodSpec / 16.0), 0.4);
  403.         mediump float lodAniso = min(0.15*anisoSpread + lodSpec, 0.4);
  404.  
  405.         dirSpec = reflect(E, hSpec);
  406.         dirAniso = reflect(E, hAniso);
  407.         mediump vec3 lookup = dirAniso;
  408.        
  409.         //aniso filtering must happen along axes perpendicular to reflection, which is different every sample
  410.         //TODO: 64x normalize? This is gross >_<!
  411.         dB = normalize(dirAniso-dirSpec);
  412.         dT = normalize(cross(dB,R));
  413.        
  414.         //spec += vec3(lodSpec);
  415.         spec += textureCubeGrad(uTexture6, lookup, dT*lodSpec, dB*lodAniso ).xyz;
  416.         //spec += textureGrad(uTexture6, lookup, dT*lodSpec, dB*lodAniso ).xyz;
  417.     }
  418.     spec *= invSampleCount;
  419.     spec *= uAnisoBrightness;
  420.  
  421.     //fresnel
  422.     mediump float glossAdjust = gloss*gloss;
  423.  
  424.     spec *= fresnel(    dot(V, N),
  425.                         reflectivity,
  426.                         fresn * glossAdjust );
  427.  
  428.     //mask for local reflections
  429.     //spec *= texture2D( tLocalReflectionMap, s.screenTexCoord ).x;
  430.  
  431.     //horizon test, reflection vector should quickly fade once it points under the surface
  432.     mediump vec3 r = reflect( -V, N );
  433.     mediump float horiz = dot( r, vertexNormal );
  434.     horiz = saturate( 1.0 + uAnisoHorizonFade*horiz );
  435.     horiz *= horiz;
  436.     spec *= horiz;
  437.  
  438.     //add our contribution
  439.    
  440.     //spec = vec3(anisoSpread, 0.0, 0.0);
  441.     return spec;
  442. }
  443. #endif
  444.  
  445. #ifdef USE_PHONG
  446.  
  447. mediump vec3 BlinnPhong(mediump float gloss, mediump vec3 V, mediump vec3 N, mediump vec3 vertexNormal, mediump vec3 reflectivity, mediump vec3 fresn )
  448. {
  449.  
  450.     mediump float specExp = -10.0 / log2( gloss*0.968 + 0.03 );
  451.     specExp *= specExp;
  452.  
  453.     //sample the reflection map repeatedly, with an importance-based sample distribution
  454.     mediump vec3 basisX = normalize( cross( N, vec3(0.0, 1.0, saturate(N.y*10000.0 - 9999.0) ) ) );
  455.     mediump vec3 basisY = cross( basisX, N );
  456.     mediump vec3 basisZ = N;
  457.     mediump vec3 spec = vec3(0.0, 0.0, 0.0);
  458.    
  459.     for(mediump int i=0; i<SPECULAR_IMPORTANCE_SAMPLES; ++i )
  460.     {
  461.         mediump vec4 r = uPhongRands[i];
  462.         mediump vec3 dir = phongImportanceSample(r, specExp);
  463.         mediump vec3 h = dir.x*basisX + dir.y*basisY + dir.z*basisZ;
  464.        
  465.         mediump float pdf = (specExp + 4.0)/(8.0*3.14159) * pow( saturate( dot( h, N ) ), specExp );
  466.         mediump float lod = (0.5 * log2( (256.0*256.0)/float(SPECULAR_IMPORTANCE_SAMPLES) ) + 0.5) - 0.5*log2( pdf );
  467.        
  468.         //vec3 lookup = reflect( -V, N );
  469.         mediump vec3 lookup = reflect( -V, h );
  470.        
  471.         mediump vec3 tcube = textureCubeLod( uTexture6, lookup, lod ).xyz;
  472.         spec += (1.0/float(SPECULAR_IMPORTANCE_SAMPLES)) * tcube;
  473.     }
  474.    
  475.     //return tosRGB(textureCubeLod( uTexture6, vec3(0.5, 0.5, -0.5), 0.0 )).xyz;
  476.  
  477.     spec *= uPhongBrightness;
  478.    
  479.     //fresnel
  480.     mediump float glossAdjust = gloss*gloss;
  481.    
  482.     spec *= fresnel(    dot( V, N ),
  483.                         reflectivity,
  484.                         fresn * glossAdjust );
  485.    
  486.     mediump vec3 r = reflect( -V, N );
  487.     mediump float horiz = dot( r, vertexNormal );
  488.     horiz = saturate( 1.0 + uPhongHorizonFade*horiz );
  489.     horiz *= horiz;
  490.    
  491.     //mask for local reflections
  492.     //spec *= texture2D( tLocalReflectionMap, s.screenTexCoord ).x;
  493.    
  494.     spec *= horiz;
  495.    
  496.     //return vec3(horiz);
  497.     return spec;
  498. }
  499.  
  500. #endif
  501.  
  502. #ifdef USE_PARALLAX
  503. mediump float   ParallaxSample( mediump vec2 c )
  504. {
  505.     c.y = 1.0 - c.y;
  506.     return 1.0 - texture2DLod( uTexture4, c, 0.0 ).r;
  507. }
  508.  
  509.  
  510. void    SurfaceParallaxMap(inout mediump vec2 uv0, mediump vec3 V, mediump vec3 vertexTangent, mediump vec3 vertexBitangent, mediump vec3 vertexNormal)
  511. {  
  512.     mediump vec3 dir =  vec3(   dot( -V, vertexTangent ),
  513.                         dot( -V, vertexBitangent ),
  514.                         dot( -V, vertexNormal ) );
  515.     mediump vec2 maxOffset = dir.xy * (uParallaxDepthOffset.x / (abs(dir.z) + 0.001));
  516.    
  517.     mediump float minSamples = 16.0;
  518.     mediump float maxSamples = 128.0;
  519.     mediump float samples = saturate( 3.0*length(maxOffset) );
  520.     mediump float incr = rcp( mix( minSamples, maxSamples, samples ) );
  521.  
  522.     mediump vec2 tc0 = uv0 - (1.0-uParallaxDepthOffset.y)*maxOffset;
  523.     mediump float h0 = ParallaxSample( tc0 );
  524.     //HINT_LOOP
  525.     for(mediump  float i=incr; i<=1.0; i+=incr )
  526.     {
  527.         mediump vec2 tc = tc0 + maxOffset * i;
  528.         mediump float h1 = ParallaxSample( tc );
  529.         if( i >= h1 )
  530.         {
  531.             //hit! now interpolate
  532.             mediump float r1 = i, r0 = i-incr;
  533.             mediump float t = (h0-r0)/((h0-r0)+(-h1+r1));
  534.             mediump float r = (r0-t*r0) + t*r1;
  535.             uv0 = tc0 + r*maxOffset;
  536.             break;
  537.         }
  538.         h0 = h1;
  539.     }
  540.    
  541.     //uv0.x = h0;
  542.  
  543.     //standard normal mapping
  544.     //SurfaceNormalMap(s);
  545. }
  546. #endif
  547.  
  548. mediump vec3 GetNormal(mediump vec2 uv, inout mediump vec3 vertexTangent, inout mediump vec3 vertexBitangent, inout mediump vec3 vertexNormal)
  549. {
  550. #if 0
  551.     return normalize(vertexNormal);
  552. #else
  553.     //sample and scale/bias the normal map
  554.     //vec3 n = vec3(0.0, 1.0, 0.0);
  555.     mediump vec3 n = texture2D(uTexture1, uv).xyz * 2.0 - 1.0;
  556.     //TODO: invert normals
  557.     //n.xy = -n.xy;
  558.     //n.y = -n.y;
  559.    
  560.     mediump vec3 T = vertexTangent;
  561.     mediump vec3 N = vertexNormal;
  562.     mediump vec3 B = vertexBitangent;
  563.    
  564.  
  565.     //ortho-normalization
  566.     mediump float renormalize = 1.0;
  567.     mediump float orthogonalize = 1.0;
  568.     mediump float regenBitangent = 1.0;
  569.    
  570.    
  571.    
  572.     N = mix( N, normalize(N), renormalize );
  573.     T -= (orthogonalize * dot(T,N)) * N;
  574.     T = mix( T, normalize(T), renormalize );
  575.     B -= orthogonalize * (dot(B,N)*N + dot(B,T)*T);
  576.     B = mix( B, normalize(B), renormalize );
  577.  
  578.     //regenerate bitangent
  579.     mediump vec3 B2 = cross( N, T );
  580.     B2 = dot(B2,B) < 0.0 ? -B2 : B2;
  581.     B = mix( B, B2, regenBitangent );
  582.    
  583.     vertexTangent = T;
  584.     vertexBitangent = B;
  585.     vertexNormal = N;
  586.    
  587.     //store our results
  588.     return normalize( n.x*T + n.y*B + n.z*N );
  589. #endif
  590. }
  591.  
  592. mediump vec3 GetSHLight(mediump vec3 N)
  593. {
  594.     return (C1 *  uLightDiffuseSphere[8] * (N.x*N.x - N.y*N.y)
  595.             +  C3 *  uLightDiffuseSphere[6] * N.z*N.z
  596.             +  C4 *  uLightDiffuseSphere[0]
  597.             -  C5 *  uLightDiffuseSphere[6]
  598.             + 2.0 * C1 * (uLightDiffuseSphere[4]*N.x*N.y + uLightDiffuseSphere[7]*N.x*N.z + uLightDiffuseSphere[5]*N.y*N.z)
  599.             + 2.0 * C2 * (uLightDiffuseSphere[3]*N.x + uLightDiffuseSphere[1]*N.y + uLightDiffuseSphere[2]*N.z ));
  600. }
  601.  
  602. mediump vec3 ImageLambert(mediump vec3 N,mediump  vec3 V,mediump  vec3 albedo)
  603. {
  604.     return GetSHLight(N) * albedo;
  605. }
  606.  
  607. #ifdef USE_MICROFIBER
  608.  
  609. mediump vec3 ImageMicrofiber(mediump vec3 N,mediump  vec3 V,mediump  vec3 albedo,mediump  float gloss)
  610. {
  611.     mediump vec3 shLight = GetSHLight(N);
  612.     mediump vec3 diffuseLight = shLight * albedo;
  613.    
  614.     //ambient occlusion
  615.     mediump float AO = 1.0;
  616.     //float AO = sampleOcclusion( s );
  617.     //s.diffuseLight *= AO;
  618.    
  619.     //PEACH-FUZZ
  620.     mediump vec3 fuzzMap = albedo;// texture2D( uTexture0, s.vertexTexCoord );
  621.    
  622.     mediump float eyeDP = dot( V, N );
  623.     mediump vec3 fuzzLight = shLight;
  624.     fuzzLight *= diffuseFresnel( eyeDP, uMicrofiberScatter, AO, uMicrofiberOcc );
  625.     mediump float wet = saturate(1.0 - gloss*uMaskWithGloss);
  626.     fuzzLight *= wet*wet;
  627.    
  628.     diffuseLight += fuzzLight * uMicrofiberColor * fuzzMap.rgb;
  629.    
  630.     return diffuseLight;
  631. }
  632.  
  633. #endif
  634.  
  635. #if 1
  636. struct  LightParams
  637. {
  638.     mediump vec3    color;          // "colour"
  639.     mediump vec3    toSource;       // vector from shaded point to light
  640.     mediump vec3    direction;      // normalized vector to light
  641.     mediump float   invDistance;    // 1/distance to light
  642.     mediump float   distance;       // distance to light
  643.     mediump float   attenuation;    // dimming (distance and other factors)
  644. };
  645.  
  646. const mediump vec3 uDirectLightColor =  vec3(255.0/255.0, 165.0/255.0, 79.0/255.0);
  647.  
  648.  
  649. mediump vec3 rsqrt(mediump vec3 a)
  650. {
  651.   return pow(a, vec3(-0.5));
  652. }
  653.  
  654. LightParams getLight(mediump vec3 shadedPosition )
  655. {
  656.     LightParams p;
  657.  
  658.     //color
  659.     p.color = uDirectLightColor;
  660.  
  661.     //light vectors
  662.     p.toSource = uLightPos.xyz - shadedPosition * 1.0; //uLightPos.w;
  663.     p.invDistance = 1.0 / sqrt( dot(p.toSource, p.toSource) );
  664.     p.distance = rcp( p.invDistance );
  665.     p.direction = p.toSource * p.invDistance;
  666.  
  667.  
  668.     //distance attenuation
  669.     mediump float a = saturate( p.distance * uLightAtten.z );
  670.     p.attenuation = 1.0 + uLightAtten.x*a + uLightAtten.y*a*a;
  671.  
  672.     return p;
  673. }
  674.  
  675. void adjustAreaLightSpecular( inout LightParams p, mediump vec3 dir, mediump float nrm )
  676. {
  677.     mediump vec3 L = p.toSource;
  678.  
  679.  
  680.     //energy conservation estimate
  681.     mediump float sizeGuess = 0.0;
  682.     mediump float solidAngleGuess = saturate( sizeGuess * p.invDistance );
  683.     p.attenuation *= rcp( 1.0 + nrm * solidAngleGuess );
  684.  
  685.     //export
  686.     p.toSource = L;
  687.     p.direction = normalize( p.toSource );
  688. }
  689.  
  690. mediump vec3 DirectLightingPhong(mediump float gloss, mediump vec3 P, mediump vec3 V, mediump vec3 N, mediump vec3 reflectivity, mediump vec3 fresn)
  691. {
  692.     //determine specular exponent from gloss map & settings
  693.     gloss = min( gloss, 0.995 );
  694.  
  695.     mediump float specExp = -10.0 / log2( gloss*0.968 + 0.03 );
  696.     specExp *= specExp;
  697.  
  698.     //light params
  699.     LightParams l = getLight( P );
  700.     mediump float phongNormalize = (specExp + 4.0)/(8.0*3.141592);
  701.     adjustAreaLightSpecular( l, reflect( -V, N ), phongNormalize );
  702.    
  703.     //blinn-phong term
  704.     mediump vec3 H = normalize( V + l.direction );
  705.     mediump float phong = phongNormalize * pow( saturate( dot(H, N) ), specExp );
  706.    
  707.     //horizon occlusion
  708.     mediump float horizon = 1.0 - saturate( dot( l.direction, N ) );
  709.     horizon *= horizon; horizon *= horizon;
  710.     phong = phong - phong*horizon;
  711.  
  712.     //spec color
  713.     mediump float s_shadow = 1.0;
  714.     mediump vec3 spec = (s_shadow * l.attenuation) *
  715.                 saturate( dot( l.direction, N ) ) *
  716.                 l.color;
  717.  
  718.     //fresnel
  719.     mediump float glossAdjust = gloss*gloss;
  720.    
  721.     spec *= fresnel(    dot( V, N ),
  722.                         reflectivity,
  723.                         fresn * glossAdjust );
  724.  
  725.     //add it on
  726.     return spec * phong;
  727. }
  728.  
  729. mediump vec3    DirectDiffusionLambert(mediump vec3 P, mediump vec3 V, mediump vec3 N, mediump vec3 albedo)
  730. {
  731.     LightParams l = getLight( P );
  732.     //adjustAreaLightDiffuse( l, P );
  733.    
  734.     mediump float lambert = (1.0/3.1415926) * saturate( dot(N, l.direction) );
  735.  
  736.     mediump float s_shadow = 1.0;
  737.     return (lambert * l.attenuation) * (l.color * s_shadow) * albedo;
  738. }
  739.  
  740. mediump vec3    DirectLightingAnisotropic(mediump float gloss, mediump vec3 P, mediump vec3 V, mediump vec3 N, mediump vec3 vertexTangent, mediump vec3 vertexBitangent, mediump vec3 vertexNormal, mediump vec3 reflectivity, mediump vec3 fresn)
  741. {
  742.     LightParams l = getLight( P );
  743.     adjustAreaLightSpecular( l, reflect( -V, N ), 1.0-gloss );
  744.  
  745.     //gloss
  746.     //determine specular exponent from gloss map & settings
  747.     mediump float specExp = -10.0 / log2( gloss*0.968 + 0.03 );
  748.     specExp *= specExp;
  749.     mediump float anisoExp = mix( specExp, 16.0, uAnisoSpread );
  750.  
  751.     //blinn-phong
  752.     mediump vec3 h = normalize( V + l.direction );
  753.    
  754.     //anisotropic projection
  755.     //h is projected onto the B-plane (shared by strand dir and N) to max out the dot-product along the B axis.
  756.     mediump vec3 T, B;
  757.     SampleAnisoTangent( N, T, B, vertexTangent, vertexBitangent, vertexNormal  );
  758.    
  759.     h = normalize(h - B*dot(h,B) * sqrt(uAnisoSpread));
  760.  
  761.     mediump float HdotN = saturate( dot( h, N ) );
  762.     mediump float illum = pow( HdotN, specExp );
  763.     illum *= (specExp + 4.0)/(8.0*3.141592);
  764.     illum *= 1.0 - uAnisoSpread * 0.5;
  765.    
  766.     //horizon
  767.     mediump float horizon = 1.0 - saturate( dot( l.direction, N ) );
  768.     horizon *= horizon; horizon *= horizon;
  769.     illum = illum - illum*horizon;
  770.  
  771.     //spec color
  772.     mediump vec3 spec = (l.attenuation * illum) * l.color;
  773.  
  774.     //fresnel
  775.     mediump float glossAdjust = gloss*gloss;
  776.  
  777.     spec *= fresnel(    dot( V, N ),
  778.                         reflectivity,
  779.                         fresn * glossAdjust );
  780.  
  781.     //add it on
  782.     return spec;// * s.shadow;
  783. }
  784. #endif
  785.  
  786. void main (void)
  787. {  
  788.     mediump vec3 toLightSource = (uLightPos - outPosition);
  789.     mediump float toSourceInvLen = inversesqrt(dot(toLightSource, toLightSource));
  790.     mediump float toLightDist = rcp(toSourceInvLen);
  791.     mediump float a = saturate(toLightDist * uLightAtten.z);
  792.     mediump float toLightAtten = 1.0 + uLightAtten.x*a + uLightAtten.y*a*a;
  793.  
  794.    
  795.     mediump vec3 L = toLightSource * toSourceInvLen;
  796.     mediump vec3 V = normalize(uEyePos - outPosition);
  797.  
  798.     mediump vec3 vertexNormal = outNormal;// vec3(0.0);
  799.     //vertexNormal.y = -vertexNormal.y;
  800.     mediump vec3 vertexTangent = outTangent;
  801.    
  802.     //note fix outUV0.z: mirror uv
  803.     mediump vec3 vertexBitangent = cross(vertexTangent, vertexNormal)*(-outUV0.z);
  804.     mediump vec2 uv0 = outUV0.xy;
  805. #ifdef USE_PARALLAX
  806.     SurfaceParallaxMap(uv0, V, vertexTangent, vertexBitangent, vertexNormal);
  807. #endif
  808.     uv0.y = 1.0 - uv0.y;
  809.     mediump vec3 N = GetNormal(uv0, vertexTangent, vertexBitangent, vertexNormal);
  810.     mediump vec3 H = normalize(L + V);
  811.    
  812.     mediump float gloss = MicrosurfaceGlossMap(uv0, N, V);
  813.    
  814.     gl_FragColor.rgb = vec3(0.0);
  815.  
  816.    
  817.     mediump vec3 reflectivity = uSpecularColor * tosRGB(texture2D( uTexture2, uv0 ).xyz);
  818.    
  819.     mediump vec3 fresnel = uSpecularFresnel;
  820.    
  821.     mediump vec3 albedo = tosRGB(texture2D(uTexture0, uv0)).xyz;
  822.    
  823.     albedo = albedo - albedo * reflectivity;
  824.    
  825.     mediump vec3 diffuseLight = vec3(0.0);
  826.     mediump vec3 specularLight = vec3(0.0);
  827.    
  828. #ifdef USE_MICROFIBER
  829.     //vec3 N, vec3 V, vec3 albedo, float gloss)
  830.     diffuseLight = ImageMicrofiber(N, V, albedo, gloss);
  831. #else
  832.     diffuseLight = ImageLambert(N, V, albedo);
  833. #endif
  834.  
  835.  
  836. #ifdef USE_PHONG
  837.     specularLight = BlinnPhong(gloss, V, N, vertexNormal, reflectivity, fresnel);
  838. #endif 
  839.  
  840. #ifdef USE_ANISOTROPIC
  841.     specularLight = Anisotropic(gloss, V, N, vertexTangent, vertexBitangent, vertexNormal, reflectivity, fresnel);
  842. #endif
  843.  
  844.     mediump float diff = 1.0;
  845.     mediump float spec = 1.0;
  846.    
  847. #ifdef USE_AO
  848.         //vec2 tc = mix( s.vertexTexCoord, s.vertexTexCoordSecondary, uAmbientOcclusionUseSecondaryUV );
  849.         mediump vec2 tc = uv0;
  850.         mediump float ao = tosRGBFloat(texture2D( uTexture5, tc ).r);
  851.         ao = ao * uAmbientOcclusionStrength + (1.0 - uAmbientOcclusionStrength);
  852.         diff = ao;
  853. #endif
  854.  
  855. #if 1
  856.     diffuseLight *= diff;
  857.     specularLight *= spec;
  858. #endif
  859.  
  860. #if 1
  861.     diffuseLight += DirectDiffusionLambert(outPosition, V, N, albedo)*diff;
  862. #ifdef USE_ANISOTROPIC
  863.     specularLight += DirectLightingAnisotropic(gloss, outPosition, V, N, vertexTangent, vertexBitangent, vertexNormal, reflectivity, fresnel)*spec;
  864. #else
  865.     specularLight += DirectLightingPhong(gloss, outPosition, V, N, reflectivity, fresnel)*spec;
  866. #endif
  867. #endif
  868.  
  869.     gl_FragColor = vec4(diffuseLight*diff + specularLight*spec, 1.0);
  870.    
  871.    
  872.     gl_FragColor.xyz = toRGB(gl_FragColor.xyz);
  873. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement