NormalMapp_fp.cg 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. struct fragin
  2. {
  3. float2 texcoords : TEXCOORD0;
  4. float4 tangentToEyeMat0 : TEXCOORD4;
  5. float3 tangentToEyeMat1 : TEXCOORD5;
  6. float3 tangentToEyeMat2 : TEXCOORD6;
  7. float3 eyeSpacePosition : TEXCOORD7;
  8. };
  9. // i is the incident ray
  10. // n is the surface normal
  11. // eta is the ratio of indices of refraction
  12. // r is the reflected ray
  13. // t is the transmitted ray
  14. float fresnel( float3 i, float3 n, float eta )
  15. {
  16. float result;
  17. float c1;
  18. float cs2;
  19. float tflag;
  20. float3 t;
  21. // Refraction vector courtesy Paul Heckbert.
  22. c1 = dot(-i,n);
  23. cs2 = 1.0-eta*eta*(1.0-c1*c1);
  24. tflag = (float) (cs2 >= 0.0);
  25. t = tflag * (((eta*c1-sqrt(cs2))*n) + eta*i);
  26. // t is already unit length or (0,0,0)
  27. // Compute Fresnel terms
  28. // (From Global Illumination Compendeum.)
  29. float ndott;
  30. float cosr_div_cosi;
  31. float cosi_div_cosr;
  32. float fs;
  33. float fp;
  34. float kr;
  35. ndott = dot(-n,t);
  36. cosr_div_cosi = ndott / c1;
  37. cosi_div_cosr = c1 / ndott;
  38. fs = (cosr_div_cosi - eta) / (cosr_div_cosi + eta);
  39. fs = fs * fs;
  40. fp = (cosi_div_cosr - eta) / (cosi_div_cosr + eta);
  41. fp = fp * fp;
  42. kr = 0.5 * (fs+fp);
  43. result = tflag*kr + (1-tflag);
  44. return result;
  45. }
  46. float4 main( fragin In,
  47. uniform sampler2D diffuseMap : TEXUNIT0,
  48. uniform sampler2D normalMap : TEXUNIT1,
  49. uniform float3 eyeSpaceLightPosition ) : COLOR
  50. {
  51. float bscale = In.tangentToEyeMat0.w;
  52. float eta = (1.0/1.4); // ratio of indices of refraction (air/skin)
  53. float m = 34; // specular exponent
  54. float4 kd = tex2D( diffuseMap, In.texcoords ); // diffuse color
  55. // Get eye-space eye vector.
  56. float3 v = normalize( -In.eyeSpacePosition );
  57. // Get eye-space light and halfangle vectors.
  58. float3 l = normalize( eyeSpaceLightPosition - In.eyeSpacePosition );
  59. float3 h = normalize( v + l );
  60. // Get tangent-space normal vector from normal map.
  61. // Uncompress vectors ([0, 1] -> [-1, 1])
  62. float3 tangentSpaceNormal = 2.0f * (float3)(tex2D( normalMap, In.texcoords ).rgb - 0.5f);
  63. float3 bumpscale = float3( bscale, bscale, 1.0 );
  64. tangentSpaceNormal = tangentSpaceNormal * bumpscale;
  65. // Transform it into eye-space.
  66. float3 n;
  67. n[0] = dot( In.tangentToEyeMat0.xyz, tangentSpaceNormal );
  68. n[1] = dot( In.tangentToEyeMat1, tangentSpaceNormal );
  69. n[2] = dot( In.tangentToEyeMat2, tangentSpaceNormal );
  70. n = normalize( n );
  71. // Compute the lighting equation coefficients.
  72. float ndotl = max( dot(n,l), 0 ); // clamp 0 to 1
  73. float ndoth = max( dot(n,h), 0 ); // clamp 0 to 1
  74. float flag = (float)(ndotl > 0); // if (ndotl <= 0) specular = 0
  75. // Compute sheen contribution.
  76. // This is basically Blinn model weighted by fresnel reflection coefficient.
  77. // The fresnel increase the effect along the edges and helps model light that
  78. // enters the backside of thin edges and is transmitted toward the front.
  79. // Basically a "rim" lighting technique.
  80. float4 sheen;
  81. float Kr;
  82. Kr = fresnel( -v, n, eta );
  83. Kr = smoothstep( 0.0, 0.5, Kr );
  84. sheen = 1.5 * Kr * ( ndotl * (0.2 + pow( ndoth, m )) );
  85. return sheen + ( kd * ndotl );
  86. }