lm_envlight2.sl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /******************************************************************************/
  2. /* */
  3. /* Copyright (c)The 3Delight Team. */
  4. /* All Rights Reserved. */
  5. /* */
  6. /******************************************************************************/
  7. /*
  8. A light source for image based lighting.
  9. PARAMETERS
  10. light_color
  11. : a multiplier on the light from the envmap.
  12. Kenv : intensity multiplier
  13. Kocc : if >0, trace transmission rays to take into account occlusion
  14. by other objects
  15. envmap : the environment map to use
  16. envspace : the coordinate system where to place the environment map
  17. samples : number of samples to use to compute lighting. Setting samples
  18. to 0 will use the SH-based indirectdiffuse approximation
  19. without ray-tracing.
  20. bias : ray-tracing bias.
  21. */
  22. light lm_envlight2(
  23. color light_color = 1;
  24. float Kenv = 1.0;
  25. float Kocc = 0.0;
  26. string envmap = "", envspace = "world";
  27. float samples = 64;
  28. float maxdist = 1e10;
  29. float bias = -1;
  30. string __category = "env";
  31. float __nonspecular = 1;
  32. )
  33. {
  34. uniform string raytype="";
  35. rayinfo( "type", raytype );
  36. uniform string gather_cat = concat("environment:", envmap);
  37. vector envdir = 0;
  38. color envcolor = 0;
  39. float solidangle = 0;
  40. if( raytype == "light" )
  41. {
  42. /* This light is called to cast some photons. Use gather() to give us
  43. the most intersting directions and use a solar() construct to cast
  44. a photon coming from that direction. (The photon casting process
  45. is dealt with automagically inside 3Delight) */
  46. gather(
  47. gather_cat, 0, 0, 0, samples,
  48. "environment:color", envcolor,
  49. "environment:direction", envdir,
  50. "environment:solidangle", solidangle )
  51. {
  52. envdir = vtransform( envspace, "current", envdir );
  53. /* Convert from solid angle to angle */
  54. solar( -envdir, acos( 1-solidangle/(2*PI) ))
  55. {
  56. Cl = envcolor * light_color / (4*PI);
  57. }
  58. }
  59. }
  60. else
  61. {
  62. normal shading_normal = normalize(Ns);
  63. if( samples == 0 )
  64. {
  65. /* Use the SH-based approximation. */
  66. normal tN = ntransform( envspace, shading_normal );
  67. illuminate( Ps + shading_normal ) /* shade all surface points */
  68. {
  69. Cl = Kenv * light_color * indirectdiffuse( envmap, tN ) / (4*PI);
  70. }
  71. }
  72. else
  73. {
  74. uniform float t1 = 0.025 * sqrt(samples);
  75. uniform float t2 = 0.05 * sqrt(samples);
  76. illuminate( Ps + shading_normal ) /* shade all surface points */
  77. {
  78. Cl = 0;
  79. if( Kenv > 0 )
  80. {
  81. vector raydir = 0;
  82. gather(
  83. gather_cat, 0, 0, 0, samples,
  84. "environment:color", envcolor,
  85. "ray:direction", raydir,
  86. "environment:direction", envdir,
  87. "environment:solidangle", solidangle )
  88. {
  89. raydir = vtransform( envspace, "current", raydir );
  90. envdir = vtransform( envspace, "current", envdir );
  91. float atten = max( shading_normal . normalize(envdir), 0 );
  92. float kocc = 1 - smoothstep( t1, t2, solidangle );
  93. kocc *= Kocc;
  94. uniform float diffusedepth = 0;
  95. attribute( "diffusedepth", diffusedepth );
  96. color trs = 1;
  97. if( kocc > 0 && atten > 0 && diffusedepth==0 )
  98. {
  99. trs = transmission(
  100. Ps, Ps + raydir * maxdist, "bias", bias );
  101. trs = 1 - kocc * (1 - trs);
  102. }
  103. Cl += envcolor * trs * atten * light_color / (4*PI);
  104. }
  105. Cl *= Kenv;
  106. }
  107. }
  108. }
  109. }
  110. }