shading_utils.h 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405
  1. /*
  2. Copyright (c) 2006 soho vfx inc.
  3. Copyright (c) 2006 The 3Delight Team.
  4. */
  5. #ifndef _shading_utils_h
  6. #define _shading_utils_h
  7. #include "utils.h"
  8. #include "global_illumination.h"
  9. #define NEW_BUMP
  10. #define SQR(i) ( (i) * (i) )
  11. #define GET_CL( CL ) { CL = Cl; if( unshadowed != 0 ) \
  12. lightsource("__3dfm_unshadowed_cl", CL); }
  13. /*
  14. ShadingNormal
  15. A wrapper for faceforward which avoids faceforward for single-sided
  16. primitives or when using double-sided shading. This is to prevent artefacts
  17. around silhouette edges caused by the way "Sides 2" is usually shaded. Note
  18. that we don't explicitely check for double-sided shading as it also sets
  19. Sides to 1.
  20. */
  21. normal ShadingNormal( normal i_N )
  22. {
  23. extern vector I;
  24. normal Nf = i_N;
  25. uniform float sides = 2;
  26. attribute("Sides", sides);
  27. if( sides == 2 )
  28. {
  29. Nf = faceforward(Nf, I);
  30. }
  31. else
  32. {
  33. /* This mess is to flip the normals of polygon meshes with reversed
  34. orientation. We only want it when 'N' is attached to the primitive. */
  35. uniform float geometricnormal = 1;
  36. attribute( "geometry:geometricnormal", geometricnormal );
  37. if( geometricnormal == 0 )
  38. {
  39. uniform string orientation;
  40. attribute( "Ri:Orientation", orientation );
  41. if( orientation == "outside" )
  42. Nf = -Nf;
  43. }
  44. }
  45. return Nf;
  46. }
  47. /*
  48. Maya's ambient function
  49. */
  50. color getAmbient( normal i_N; )
  51. {
  52. return ambient();
  53. }
  54. color getAmbientUnshadowed( normal i_N )
  55. {
  56. extern point P;
  57. color amb = 0;
  58. illuminance( P )
  59. {
  60. if( L == 0 )
  61. {
  62. color unshadowed_cl = 0;
  63. lightsource("__3dfm_unshadowed_cl", unshadowed_cl);
  64. amb += unshadowed_cl;
  65. }
  66. }
  67. return amb;
  68. }
  69. /*
  70. Maya's diffuse function
  71. */
  72. color getDiffuse(
  73. normal i_N;
  74. uniform float keyLightsOnly;
  75. uniform float unshadowed; )
  76. {
  77. extern point P;
  78. color C = 0;
  79. illuminance( P, i_N, PI/2 )
  80. {
  81. float isKeyLight = 1;
  82. if( keyLightsOnly != 0 )
  83. {
  84. isKeyLight = 0;
  85. lightsource( "iskeylight", isKeyLight );
  86. }
  87. if( isKeyLight != 0 )
  88. {
  89. float nondiffuse = 0;
  90. lightsource( "__nondiffuse", nondiffuse );
  91. if( nondiffuse < 1 )
  92. {
  93. varying color cur_cl;
  94. GET_CL(cur_cl);
  95. C += cur_cl * normalize(L).i_N * (1-nondiffuse);
  96. }
  97. }
  98. }
  99. if( keyLightsOnly == 0 && unshadowed == 0 )
  100. {
  101. float samples = 16;
  102. option( "user:_3dfm_arealight_samples", samples );
  103. color clight;
  104. trace(
  105. P, i_N,
  106. "type", "transmission",
  107. "hitsides", "reversed",
  108. "samplearealights", 1,
  109. "samples", samples,
  110. "arealightcontribution", clight,
  111. "bsdf", "cosine" );
  112. C += clight;
  113. }
  114. return C;
  115. }
  116. color getTranslucence(
  117. normal i_N;
  118. float i_translucence, i_translucenceDepth, i_translucenceFocus;)
  119. {
  120. extern point P;
  121. extern vector I;
  122. /*
  123. A translucence focus of 1 leads to a division by zero and an effective
  124. focus of 0. Clamping it like this yields about the same result as maya.
  125. */
  126. float focus = min( i_translucenceFocus, 0.99999 );
  127. color C = 0;
  128. if( i_translucence > 0.0 )
  129. {
  130. illuminance( P )
  131. {
  132. float nondiffuse = 0;
  133. lightsource( "__nondiffuse", nondiffuse );
  134. if( nondiffuse < 1 )
  135. {
  136. float costheta = normalize(L).normalize(I);
  137. float a = (1 + costheta) * 0.5;
  138. float trs = pow( pow(a, focus), 1/(1-focus) );
  139. C += Cl * trs * (1-nondiffuse);
  140. }
  141. }
  142. }
  143. return C * i_translucence;
  144. }
  145. color
  146. getBlinn(
  147. normal i_Nf;
  148. float i_eccentricity;
  149. float i_specularRollOff;
  150. uniform float i_keyLightsOnly;
  151. uniform float unshadowed;
  152. )
  153. {
  154. float E;
  155. color C = 0;
  156. vector H, Ln, V, Nn;
  157. float NH, NH2, NHSQR, Dd, Gg, VN, VH, LN, Ff, tmp;
  158. extern point P;
  159. extern vector L, I;
  160. extern color Cl;
  161. if(i_eccentricity != 1)
  162. E = 1 / (SQR(i_eccentricity) - 1);
  163. else
  164. E = -1e5;
  165. V = normalize(-I);
  166. VN = V . i_Nf;
  167. illuminance( P, i_Nf, PI / 2)
  168. {
  169. float isKeyLight = 1;
  170. if( i_keyLightsOnly != 0 )
  171. {
  172. lightsource( "iskeylight", isKeyLight );
  173. }
  174. if( isKeyLight != 0 )
  175. {
  176. float nonspecular = 0;
  177. lightsource( "__nonspecular", nonspecular );
  178. if( nonspecular < 1 )
  179. {
  180. Ln = normalize(L);
  181. H = normalize(Ln + V);
  182. NH = i_Nf . H;
  183. NHSQR = SQR(NH);
  184. NH2 = NH * 2;
  185. Dd = (E + 1) / (NHSQR + E);
  186. Dd *= Dd;
  187. VH = V . H;
  188. LN = Ln . i_Nf;
  189. if(VN < LN)
  190. {
  191. if(VN * NH2 < VH)
  192. Gg = NH2 / VH;
  193. else
  194. Gg = 1 / VN;
  195. }
  196. else
  197. {
  198. if(LN * NH2 < VH)
  199. Gg = (LN * NH2) / (VH * VN);
  200. else
  201. Gg = 1 / VN;
  202. }
  203. /* poor man's Fresnel */
  204. tmp = pow((1 - VH), 3);
  205. Ff = tmp + (1 - tmp) * i_specularRollOff;
  206. varying color cur_cl;
  207. GET_CL(cur_cl);
  208. C += cur_cl * Dd * Gg * Ff * (1-nonspecular);
  209. }
  210. }
  211. }
  212. if( i_keyLightsOnly == 0 && unshadowed == 0 )
  213. {
  214. float samples = 16;
  215. option( "user:_3dfm_arealight_samples", samples );
  216. float eta = 0;
  217. if( i_specularRollOff < 0.99 )
  218. {
  219. float sr = max( 0.0001, i_specularRollOff );
  220. /* Similar attenuation for highlights seen head-on. */
  221. eta = -((sr+1+2*sqrt(sr))/(sr-1));
  222. }
  223. float e = 1 / pow( i_eccentricity, 2.75 /* guesswork */ );
  224. float denormalize = 2 * PI / (e + 2);
  225. /* Do I look like I know what I'm doing? Yes? Awesome! */
  226. denormalize *= 1.27;
  227. color clight;
  228. trace(
  229. P, i_Nf,
  230. "type", "transmission",
  231. "hitsides", "reversed",
  232. "samplearealights", 1,
  233. "samples", samples,
  234. "arealightcontribution", clight,
  235. "bsdf", "blinn",
  236. "wo", V,
  237. "eta", eta,
  238. "roughness", pow( e + 1, -2/7 ) );
  239. C += denormalize * clight;
  240. }
  241. return C;
  242. }
  243. color getAnisotropic(
  244. vector i_N, i_I, i_xdir;
  245. float i_fresnel, i_roughness, i_spreadx, i_spready;
  246. uniform float i_keyLightsOnly, unshadowed;)
  247. {
  248. /* Stam's anisotropic BRDF */
  249. float stam_anisotropy( float u, v, w, rx, ry )
  250. {
  251. float w2 = w * w;
  252. float bt = 4 * PI * w2 * w2 * rx * ry;
  253. float ex = exp(- u * u / (4 * w2 * rx * rx)) * exp( - v * v / (4 * w2 * ry * ry));
  254. return ex / bt;
  255. }
  256. extern point P;
  257. vector ydir = i_N ^ i_xdir;
  258. float costheta2 = i_I.i_N;
  259. /*float sintheta2 = sin(acos(costheta2));*/
  260. float rx = i_roughness / i_spreadx;
  261. float ry = i_roughness / i_spready;
  262. float exists, emitspec = 0;
  263. color ClnoShadow = 0;
  264. color spec = 0;
  265. illuminance( P, i_N, PI / 2 )
  266. {
  267. float isKeyLight = 1;
  268. if( i_keyLightsOnly != 0 )
  269. {
  270. lightsource( "iskeylight", isKeyLight );
  271. }
  272. if( isKeyLight != 0 )
  273. {
  274. float nonspecular = 0;
  275. lightsource( "__nonspecular", nonspecular );
  276. if( nonspecular<1 && i_N.L>0 )
  277. {
  278. vector Ln = normalize(L);
  279. float costheta1 = Ln.i_N;
  280. vector V = Ln + i_I;
  281. float v = V.i_xdir;
  282. float u = V.ydir;
  283. float w = V.i_N;
  284. float G = (1 + Ln.i_I);
  285. G = clamp( G * G / (costheta1*costheta2), 0, 1);
  286. float D = stam_anisotropy( u, v, w, rx, ry );
  287. float factor = G * D;
  288. float HdotI = V.i_I / length(V);
  289. HdotI = 1.0 - HdotI;
  290. HdotI = HdotI * HdotI * HdotI;
  291. factor *= HdotI + (1.0 - HdotI);
  292. factor = clamp(factor, 0, 1) * i_fresnel;
  293. varying color cur_cl;
  294. GET_CL(cur_cl);
  295. spec += factor * cur_cl * (1-nonspecular);
  296. }
  297. }
  298. }
  299. return spec/4;
  300. }
  301. void
  302. computeSurfaceTransparency(
  303. float i_matteOpacityMode;
  304. float i_matteOpacity;
  305. color i_transparency;
  306. output color o_outTransparency )
  307. {
  308. if(i_matteOpacityMode == 0)
  309. {
  310. // This is the "Black Hole" Maya setting
  311. o_outTransparency = 0;
  312. }
  313. else if(i_matteOpacityMode == 1)
  314. {
  315. // This is the "Solid Matte" Maya setting
  316. o_outTransparency = i_matteOpacity;
  317. }
  318. else
  319. {
  320. // This is the "Opacity Gain" Maya setting (and the default value)
  321. o_outTransparency = (1 - i_transparency) * i_matteOpacity;
  322. }
  323. o_outTransparency = 1.0 - o_outTransparency;
  324. }
  325. void computeSurface(
  326. color i_surfaceColor;
  327. color i_transparency;
  328. float i_matteOpacityMode;
  329. float i_matteOpacity;
  330. output color o_outColor;
  331. output color o_outTransparency;
  332. )
  333. {
  334. computeSurfaceTransparency(
  335. i_matteOpacityMode, i_matteOpacity, i_transparency, o_outTransparency );
  336. o_outColor = i_surfaceColor * (1 - o_outTransparency);
  337. o_outColor = clamp(o_outColor, 0, 1e30);
  338. }
  339. float raySpecularDepth()
  340. {
  341. uniform float depth = 0;
  342. rayinfo( "speculardepth", depth );
  343. return depth;
  344. }
  345. color getReflection(
  346. normal i_N;
  347. vector i_I;
  348. color i_specularColor;
  349. float i_reflectivity;
  350. color i_reflectedColor;
  351. uniform float i_maxDistance;
  352. uniform float i_samples;
  353. uniform float i_blur;
  354. uniform float i_noiseAmp;
  355. uniform float i_noiseFreq;
  356. uniform float i_reflectionLimit )
  357. {
  358. extern point P;
  359. extern uniform float __reflects;
  360. #if defined(USE_AOV_aov_env_reflection) || \
  361. defined(USE_AOV_aov_rt_reflection) || \
  362. defined(USE_AOV_aov_rt_reflection_alpha) || \
  363. defined(USE_AOV_aov_reflection) || \
  364. defined(USE_AOV_aov_env_specular)
  365. extern color __transparency;
  366. #endif
  367. color ray_coloration = i_specularColor * i_reflectivity;
  368. // Color from the "reflectedColor" attr meant for env maps.
  369. color env_color = i_reflectedColor;
  370. color reflected = env_color;
  371. if( ray_coloration != color(0) &&
  372. raySpecularDepth() < i_reflectionLimit &&
  373. __reflects != 0)
  374. {
  375. vector R = reflect( i_I, i_N );
  376. if( i_noiseAmp != 0 && i_noiseFreq != 0)
  377. {
  378. point Pobj = transform("object", P);
  379. R = mix( R, R * noise( Pobj * i_noiseFreq ), i_noiseAmp );
  380. }
  381. color trs;
  382. color rc = trace(
  383. P, R,
  384. "subset", "-_3dfm_not_visible_in_reflections",
  385. "maxdist", i_maxDistance,
  386. "samplecone", i_blur,
  387. "samples", i_samples,
  388. "transmission", trs,
  389. "weight", ray_coloration );
  390. #ifdef USE_AOV_aov_rt_reflection
  391. extern color aov_rt_reflection;
  392. aov_rt_reflection += __transparency * rc * ray_coloration;
  393. #endif
  394. #ifdef USE_AOV_aov_rt_reflection_alpha
  395. extern float aov_rt_reflection_alpha;
  396. aov_rt_reflection_alpha += luminance(__transparency * (1 - trs));
  397. #endif
  398. if( trs != 0 )
  399. {
  400. varying color gi_env_color = getGiEnvironmentSpecular(R, i_samples, i_blur);
  401. #ifdef USE_AOV_aov_env_specular
  402. extern varying color aov_env_specular;
  403. if( isoutput( aov_env_specular ) )
  404. {
  405. aov_env_specular += __transparency * gi_env_color * trs * ray_coloration;
  406. }
  407. #endif
  408. uniform float add_to_final_mix = getGiAddToFinalMix();
  409. if( add_to_final_mix > 0 )
  410. {
  411. reflected += gi_env_color;
  412. }
  413. #if !defined(USE_DEPRECATED_SHADING) && defined(USE_AOV_aov_env_reflection)
  414. env_color += gi_env_color;
  415. #endif
  416. }
  417. #if !defined(USE_DEPRECATED_SHADING) && defined(USE_AOV_aov_env_reflection)
  418. env_color *= trs;
  419. #endif
  420. reflected *= trs;
  421. reflected += rc;
  422. }
  423. #ifdef USE_AOV_aov_env_reflection
  424. extern color aov_env_reflection;
  425. aov_env_reflection += __transparency * env_color * ray_coloration;
  426. #endif
  427. #ifdef USE_AOV_aov_reflection
  428. extern color aov_reflection;
  429. aov_reflection += __transparency * reflected * ray_coloration;
  430. #endif
  431. return reflected * ray_coloration;
  432. }
  433. float doRefraction(
  434. normal i_N;
  435. vector i_I;
  436. uniform float i_refractions;
  437. float i_refractiveIndex;
  438. uniform float i_refractionLimit;
  439. float i_lightAbsorbance;
  440. float i_shadowAttenuation;
  441. output color io_transparency;
  442. output color o_refraction; )
  443. {
  444. // Returns a non-zero value if there is a total internal reflection
  445. // (which should be computed elsewhere)
  446. //
  447. extern point P;
  448. uniform string rayType;
  449. uniform float isShadowMap;
  450. extern uniform float __refracts;
  451. float tir = 0;
  452. if( io_transparency != color(0) &&
  453. __refracts != 0)
  454. {
  455. /*
  456. Check for shadows (either raytraced or shadow maps), in which case
  457. we compute a straight opacity instead of tracing refraction rays.
  458. */
  459. if( (1 == rayinfo( "type", rayType ) && rayType == "transmission") ||
  460. (1 == attribute( "user:ShadowMapRendering", isShadowMap ) &&
  461. isShadowMap != 0) )
  462. {
  463. o_refraction = 0;
  464. io_transparency *=
  465. mix( 1, abs( normalize(i_I) . i_N ), i_shadowAttenuation );
  466. }
  467. else if( i_refractions != 0 )
  468. {
  469. color refractionColor = 0;
  470. if( raySpecularDepth() < i_refractionLimit )
  471. {
  472. float eta;
  473. normal Nf = i_N;
  474. if( i_I . i_N < 0 )
  475. {
  476. eta = 1.0 / i_refractiveIndex;
  477. Nf = i_N;
  478. }
  479. else
  480. {
  481. eta = i_refractiveIndex;
  482. Nf = -i_N;
  483. }
  484. vector refract = refract(normalize(i_I), Nf, eta);
  485. if( length( refract ) <= EPSILON )
  486. {
  487. o_refraction = 0;
  488. tir = 1.0;
  489. }
  490. else
  491. {
  492. color trs = 0;
  493. vector dir = normalize(refract);
  494. refractionColor = trace(
  495. P, dir,
  496. "subset", "-_3dfm_not_visible_in_refractions",
  497. "transmission", trs);
  498. uniform float add_to_final_mix = getGiAddToFinalMix();
  499. if( trs != 0 && add_to_final_mix > 0)
  500. {
  501. refractionColor += getGiEnvironmentSpecular(dir, 0, 0) * trs;
  502. }
  503. }
  504. }
  505. o_refraction = io_transparency * refractionColor;
  506. io_transparency = 0;
  507. }
  508. else
  509. {
  510. o_refraction = 0;
  511. }
  512. }
  513. else
  514. {
  515. o_refraction = 0;
  516. }
  517. return tir;
  518. }
  519. float computeShadowValue(normal i_N)
  520. {
  521. float shadowValue = 0;
  522. varying float totalLightIntensity = 0;
  523. extern varying point P;
  524. illuminance(P)
  525. {
  526. /* Do this manually instead of specifying i_N, PI/2 to illuminance so
  527. ambient lights are included. */
  528. if( L.i_N >= 0 )
  529. {
  530. float __3dfm_shadowing = 0;
  531. color __3dfm_unshadowed_cl = 0;
  532. lightsource("__3dfm_shadowing", __3dfm_shadowing);
  533. lightsource("__3dfm_unshadowed_cl", __3dfm_unshadowed_cl);
  534. float unshadowed_intensity = luminance(__3dfm_unshadowed_cl);
  535. shadowValue += __3dfm_shadowing * unshadowed_intensity;
  536. totalLightIntensity += unshadowed_intensity;
  537. }
  538. }
  539. // Environment contribution
  540. shader gi_shader = getshader( "maya_gi_shader" );
  541. if( gi_shader != null )
  542. {
  543. extern point P;
  544. color envDiffuse;
  545. color unshadowedEnvDiffuse;
  546. gi_shader->ComputeUseBackground(
  547. P, i_N, 1, envDiffuse, unshadowedEnvDiffuse );
  548. float unshadowedEnvDiffuseIntensity =
  549. CIEluminance(unshadowedEnvDiffuse);
  550. shadowValue += unshadowedEnvDiffuseIntensity - CIEluminance(envDiffuse);
  551. totalLightIntensity += unshadowedEnvDiffuseIntensity;
  552. }
  553. // Area lights contribution
  554. float samples = 16;
  555. option( "user:_3dfm_arealight_samples", samples );
  556. color areaLight;
  557. color unshadowedAreaLight;
  558. trace(
  559. P, i_N,
  560. "raytype", "transmission",
  561. "hitsides", "reversed",
  562. "samplearealights", 1,
  563. "samples", samples,
  564. "arealightcontribution", areaLight,
  565. "unshadowedarealight", unshadowedAreaLight,
  566. "bsdf", "uniform" );
  567. float unshadowedAreaLightIntensity = CIEluminance(unshadowedAreaLight);
  568. shadowValue += unshadowedAreaLightIntensity - CIEluminance(areaLight);
  569. totalLightIntensity += unshadowedAreaLightIntensity;
  570. shadowValue /= totalLightIntensity;
  571. return shadowValue;
  572. }
  573. void computeShadowPass(normal i_N)
  574. {
  575. #ifdef USE_AOV_aov_shadow
  576. extern float aov_shadow;
  577. aov_shadow = computeShadowValue(i_N);
  578. #endif
  579. }
  580. color computeLuminanceDepth()
  581. {
  582. uniform float near_far[2] = {0, 1e3};
  583. option( "Clipping", near_far );
  584. uniform float near = near_far[0];
  585. uniform float far = near_far[1];
  586. extern varying vector I;
  587. float depth = length(I) - near;
  588. far -= near;
  589. depth = (far - depth) / far;
  590. return color(depth, depth, depth);
  591. }
  592. color getPhong(
  593. normal i_N; vector i_V; float i_size;
  594. uniform float i_keyLightsOnly, unshadowed)
  595. {
  596. color C = 0;
  597. vector R = reflect( -normalize(i_V), normalize(i_N) );
  598. extern varying point P;
  599. illuminance( P, i_N, PI/2 )
  600. {
  601. float isKeyLight = 1;
  602. if( i_keyLightsOnly != 0 )
  603. {
  604. lightsource( "iskeylight", isKeyLight );
  605. }
  606. if( isKeyLight != 0 )
  607. {
  608. float nonspecular = 0;
  609. lightsource( "__nonspecular", nonspecular );
  610. if( nonspecular < 1 )
  611. {
  612. vector Ln = normalize(L);
  613. varying color cur_cl;
  614. GET_CL(cur_cl);
  615. C += cur_cl * pow(max(0.0,R.Ln), i_size) * (1-nonspecular);
  616. }
  617. }
  618. }
  619. return C;
  620. }
  621. /* Implementation of specularstd function */
  622. color getPhongS(
  623. normal i_N; vector i_V; float i_size;
  624. uniform float i_keyLightsOnly, unshadowed)
  625. {
  626. color C = 0;
  627. extern varying point P;
  628. illuminance( P, i_N, PI/2 )
  629. {
  630. vector H = normalize(normalize(L)+i_V);
  631. float isKeyLight = 1;
  632. if( i_keyLightsOnly != 0 )
  633. {
  634. lightsource( "iskeylight", isKeyLight );
  635. }
  636. if( isKeyLight != 0 )
  637. {
  638. float nonspecular = 0;
  639. lightsource( "__nonspecular", nonspecular );
  640. if( nonspecular < 1 )
  641. {
  642. vector Ln = normalize(L);
  643. varying color cur_cl;
  644. GET_CL(cur_cl);
  645. C += cur_cl * pow(max(0.0,i_N.H), i_size) * (1-nonspecular);
  646. }
  647. }
  648. }
  649. return C;
  650. }
  651. color getPhongE(vector i_R; float i_highlight_size, i_roughness;
  652. uniform float i_keyLightsOnly, unshadowed)
  653. {
  654. extern point P;
  655. varying color C = 0;
  656. illuminance( "specular", P, i_R, i_highlight_size * PI/2 )
  657. {
  658. float isKeyLight = 1;
  659. if( i_keyLightsOnly != 0 )
  660. {
  661. lightsource( "iskeylight", isKeyLight );
  662. }
  663. if( isKeyLight != 0 )
  664. {
  665. float nonspecular = 0;
  666. lightsource( "__nonspecular", nonspecular );
  667. if( nonspecular < 1 )
  668. {
  669. float cos_angle = normalize(L) . i_R;
  670. float angle = acos(cos_angle);
  671. float spec = pow( cos(angle / i_highlight_size), pow(i_roughness, -2) );
  672. varying color cur_cl;
  673. GET_CL(cur_cl);
  674. C += spec * cur_cl * (1-nonspecular);
  675. }
  676. }
  677. }
  678. return C;
  679. }
  680. color getGaussian(vector i_I; vector i_N; float i_roughness;
  681. uniform float i_keyLightsOnly, unshadowed)
  682. {
  683. extern point P;
  684. color C = 0;
  685. illuminance( "specular", P )
  686. {
  687. float isKeyLight = 1;
  688. if( i_keyLightsOnly != 0 )
  689. {
  690. lightsource( "iskeylight", isKeyLight );
  691. }
  692. if( isKeyLight != 0 )
  693. {
  694. float nonspecular = 0;
  695. lightsource( "__nonspecular", nonspecular );
  696. if( nonspecular < 1 )
  697. {
  698. vector Ln = normalize(L);
  699. vector Hn = normalize(-i_I + Ln);
  700. float spec = exp( -sq( acos(i_N.Hn) / i_roughness ) );
  701. varying color cur_cl;
  702. GET_CL(cur_cl);
  703. C += cur_cl * spec * (1-nonspecular);
  704. }
  705. }
  706. }
  707. return C;
  708. }
  709. color getGaussianG(vector i_I; vector i_N; float i_roughness;
  710. uniform float i_keyLightsOnly, unshadowed)
  711. {
  712. extern point P;
  713. color C = 0;
  714. illuminance( "specular", P )
  715. {
  716. float isKeyLight = 1;
  717. if( i_keyLightsOnly != 0 )
  718. {
  719. lightsource( "iskeylight", isKeyLight );
  720. }
  721. if( isKeyLight != 0 )
  722. {
  723. float nonspecular = 0;
  724. lightsource( "__nonspecular", nonspecular );
  725. if( nonspecular < 1 )
  726. {
  727. vector Ln = normalize(L);
  728. vector Hn = normalize(-i_I + Ln);
  729. float spec = exp( -sq( acos(i_N.Hn) / i_roughness ) );
  730. spec = smoothstep(0, 1/3, spec);
  731. varying color cur_cl;
  732. GET_CL(cur_cl);
  733. C += cur_cl * spec * (1-nonspecular);
  734. }
  735. }
  736. }
  737. return C;
  738. }
  739. color getCookTorr(vector i_V; vector i_N; float i_roughness; color i_ior;
  740. uniform float i_keyLightsOnly, unshadowed)
  741. {
  742. extern point P;
  743. float etar = 1/i_ior[0];
  744. float etag = 1/i_ior[1];
  745. float etab = 1/i_ior[2];
  746. float Kt, Krr, Krg, Krb;
  747. fresnel(-i_V, i_N, etar, Krr, Kt);
  748. fresnel(-i_V, i_N, etag, Krg, Kt);
  749. fresnel(-i_V, i_N, etab, Krb, Kt);
  750. color F = color(Krr, Krg, Krb);
  751. color C = 0;
  752. illuminance( P, i_N, PI/2)
  753. {
  754. float isKeyLight = 1;
  755. if( i_keyLightsOnly != 0 )
  756. {
  757. lightsource( "iskeylight", isKeyLight );
  758. }
  759. if( isKeyLight != 0 )
  760. {
  761. float nonspecular = 0;
  762. lightsource( "__nonspecular", nonspecular );
  763. if( nonspecular < 1 )
  764. {
  765. vector Ln = normalize(L);
  766. vector Hn = normalize(i_V + Ln);
  767. float NH = i_N.Hn;
  768. float alpha = acos(NH);
  769. float NV = i_N.i_V;
  770. float NL = i_N.Ln;
  771. float HV = Hn.i_V;
  772. // Geometric attenuation term:
  773. float G1 = (2 * NH * NV) / HV;
  774. float G2 = (2 * NH * NL) / HV;
  775. float G = min(1, min(G1, G2));
  776. // Beckmann distribution factor:
  777. float _D = tan(alpha) / i_roughness;
  778. float D = exp( - (_D*_D) ) /
  779. (4.0 * i_roughness * i_roughness * pow(cos(alpha), 4.0));
  780. color spec = D*G*F/NV;
  781. varying color cur_cl;
  782. GET_CL(cur_cl);
  783. C += cur_cl * spec * (1-nonspecular);
  784. }
  785. }
  786. }
  787. return C;
  788. }
  789. void do_bump_map(
  790. float i_bumpValue;
  791. float i_bumpDepth;
  792. normal i_normalCamera;
  793. output normal o_outNormal )
  794. {
  795. extern vector dPdu, dPdv;
  796. float depth = abs(i_bumpDepth);
  797. float offset = clamp(i_bumpValue * i_bumpDepth, -depth, depth);
  798. #ifndef NEW_BUMP /* old bump implementation */
  799. /*
  800. These scale factors are a bit experimental. The constant is to roughly
  801. match maya's bump mapping. The part about dPdu/dPdv ensures that the
  802. bump's scale does not depend on the underlying parametrization of the
  803. patch (the use of Du and Dv below introduce that) and that it happens
  804. in object space. Note that maya's handling of object space appears to
  805. be slightly broken since an enlarged sphere will have the same bump as
  806. a sphere with its control points moved outwards by a scale, somehow.
  807. */
  808. float uscale = 1.0 / (length(vtransform("object", dPdu)) * 6.0);
  809. float vscale = 1.0 / (length(vtransform("object", dPdv)) * 6.0);
  810. vector gu = vector(1, 0, Du(offset) * uscale);
  811. vector gv = vector(0, 1, Dv(offset) * vscale);
  812. normal n = normal(gu ^ gv);
  813. vector basisz = normalize(i_normalCamera);
  814. vector basisx = normalize((basisz ^ dPdu) ^ basisz);
  815. vector basisy = normalize((basisz ^ dPdv) ^ basisz);
  816. o_outNormal = normal(
  817. xcomp(n) * basisx + ycomp(n) * basisy + zcomp(n) * basisz);
  818. o_outNormal = normalize(o_outNormal);
  819. #else
  820. extern point P;
  821. extern normal Ng;
  822. normal Nn = normalize(i_normalCamera);
  823. normal Ngn = normalize(Ng);
  824. normal Noffset = Nn - Ngn;
  825. float scale = 0.25;
  826. point Pp =
  827. transform("world", P) +
  828. normalize(ntransform("world", Ngn)) * offset * scale;
  829. Nn = -ntransform("world", "current", calculatenormal(Pp));
  830. Nn = normalize(Nn);
  831. o_outNormal = normalize(Nn + Noffset);
  832. #endif
  833. }
  834. /* Macros to implement a special case for photons in the surface shaders. */
  835. #define BEGIN_PHOTON_CASE( diffuseColor, specularColor, transparency ) \
  836. string rayType; \
  837. if( 1 == rayinfo( "type", rayType ) && rayType == "light" ) \
  838. { \
  839. string shadingmodel; \
  840. if( 1 == attribute( "photon:shadingmodel", shadingmodel ) && \
  841. shadingmodel == "matte" ) \
  842. { \
  843. o_outColor = diffuseColor; \
  844. } \
  845. else \
  846. { \
  847. o_outColor = specularColor; \
  848. } \
  849. o_outTransparency = transparency; \
  850. } \
  851. else \
  852. { /* This encloses the shader body. */
  853. /* Macros to implement a special case for photons in the surface shaders
  854. without o_outTransparency parameter */
  855. #define BEGIN_PHOTON_CASE_OI( diffuseColor, specularColor, transparency ) \
  856. extern color Oi; \
  857. string rayType; \
  858. if( 1 == rayinfo( "type", rayType ) && rayType == "light" ) \
  859. { \
  860. string shadingmodel; \
  861. if( 1 == attribute( "photon:shadingmodel", shadingmodel ) && \
  862. shadingmodel == "matte" ) \
  863. { \
  864. o_outColor = diffuseColor * (1.0 - transparency); \
  865. } \
  866. else \
  867. { \
  868. o_outColor = specularColor; \
  869. } \
  870. Oi = 1.0 - transparency; \
  871. } \
  872. else \
  873. { /* This encloses the shader body. */
  874. #define END_PHOTON_CASE } /* This closes the brace above. */
  875. // Compute the roughness corresponding to a given glossiness value.
  876. float roughness(float gloss)
  877. {
  878. return pow(2.0, 8.0 * gloss);
  879. }
  880. /*
  881. * Oren and Nayar's generalization of Lambert's reflection model.
  882. * The roughness parameter gives the standard deviation of angle
  883. * orientations of the presumed surface grooves. When roughness=0,
  884. * the model is identical to Lambertian reflection.
  885. * Taken from Arman so credits go to Larry Gritz.
  886. */
  887. color
  888. LocIllumOrenNayar (
  889. normal N;
  890. vector V;
  891. float roughness;
  892. uniform float keyLightsOnly;
  893. uniform float unshadowed;)
  894. {
  895. /* Surface roughness coefficients for Oren/Nayar's formula */
  896. float sigma2 = roughness * roughness;
  897. float A = 1 - 0.5 * sigma2 / (sigma2 + 0.33);
  898. float B = 0.45 * sigma2 / (sigma2 + 0.09);
  899. /* Useful precomputed quantities */
  900. float theta_r = acos (V . N); /* Angle between V and N */
  901. vector V_perp_N = normalize(V-N*(V.N)); /* Part of V perpendicular to N */
  902. /* Accumulate incoming radiance from lights in C */
  903. color C = 0;
  904. extern point P;
  905. illuminance (P, N, PI/2)
  906. {
  907. float isKeyLight = 1;
  908. if( keyLightsOnly != 0 )
  909. {
  910. lightsource( "iskeylight", isKeyLight );
  911. }
  912. if( isKeyLight != 0 )
  913. {
  914. /* Must declare extern L & Cl because we're in a function */
  915. extern vector L;
  916. uniform float nondiff = 0;
  917. lightsource ("__nondiffuse", nondiff);
  918. if (nondiff == 0)
  919. {
  920. vector LN = normalize(L);
  921. float cos_theta_i = LN . N;
  922. float cos_phi_diff = V_perp_N . normalize(LN - N*cos_theta_i);
  923. float theta_i = acos (cos_theta_i);
  924. float alpha = max (theta_i, theta_r);
  925. float beta = min (theta_i, theta_r);
  926. varying color cur_cl;
  927. GET_CL(cur_cl);
  928. C += cur_cl * cos_theta_i *
  929. (A + B * max(0,cos_phi_diff) * sin(alpha) * tan(beta));
  930. }
  931. }
  932. }
  933. return C;
  934. }
  935. // Compute sampling parameters.
  936. float compute_sampling_angle( float glossiness; )
  937. {
  938. if( glossiness >= 1.0 )
  939. return 0.0;
  940. else
  941. return (1.0 - pow(clamp(glossiness, 0.0, 1.0), 0.2)) * PI / 2.0;
  942. }
  943. color trace_reflection(
  944. vector In;
  945. normal Nf;
  946. vector V;
  947. float i_refl_gloss;
  948. float i_refl_gloss_samples;
  949. float i_use_max_dist;
  950. float i_max_dist;
  951. uniform float i_do_refl_falloff;
  952. varying color i_refl_falloff_color;
  953. varying color i_weight )
  954. {
  955. extern point P;
  956. extern uniform float __reflects;
  957. if( __reflects == 0 )
  958. {
  959. return color(0);
  960. }
  961. // Compute the sampling parameters.
  962. float sample_angle = compute_sampling_angle( i_refl_gloss );
  963. float sample_count = (i_refl_gloss == 0) ?
  964. min(4, i_refl_gloss_samples) : i_refl_gloss_samples;
  965. // Compute reflected direction.
  966. vector refl_dir = reflect(In, Nf);
  967. uniform float max_dist = i_use_max_dist > EPSILON ? i_max_dist : 1e38;
  968. color trs = 0;
  969. float dist = 0;
  970. float fade = 1.0;
  971. if( i_use_max_dist != 0 )
  972. {
  973. fade = pow( ( clamp( 1 - dist / max_dist, 0, 1 ) ), 2 );
  974. }
  975. color reflection = trace(
  976. P, refl_dir, dist,
  977. "samplecone", sample_angle,
  978. "samples", sample_count,
  979. "transmission", trs,
  980. "subset", "-_3dfm_not_visible_in_reflections",
  981. "maxdist", max_dist,
  982. "weight", i_weight*fade );
  983. reflection *= fade;
  984. extern color __transparency;
  985. #ifdef USE_AOV_aov_rt_reflection
  986. extern varying color aov_rt_reflection;
  987. if( isoutput( aov_rt_reflection ) )
  988. {
  989. aov_rt_reflection += __transparency * reflection;
  990. }
  991. #endif
  992. #ifdef USE_AOV_aov_rt_reflection_alpha
  993. extern varying float aov_rt_reflection_alpha;
  994. if( isoutput( aov_rt_reflection_alpha ) )
  995. {
  996. aov_rt_reflection_alpha += CIEluminance( __transparency * (1-trs) );
  997. }
  998. #endif
  999. if( trs != 0 )
  1000. {
  1001. color env_color = 0;
  1002. if( i_do_refl_falloff != 0 )
  1003. {
  1004. env_color = i_refl_falloff_color;
  1005. }
  1006. else
  1007. {
  1008. env_color = getGiEnvironmentSpecular(refl_dir, sample_count, sample_angle);
  1009. }
  1010. if( i_use_max_dist != 0 )
  1011. {
  1012. env_color *= (1 - fade);
  1013. }
  1014. env_color *= trs;
  1015. #ifdef USE_AOV_aov_env_specular
  1016. extern varying color aov_env_specular;
  1017. if( isoutput( aov_env_specular ) )
  1018. {
  1019. aov_env_specular += __transparency * env_color;
  1020. }
  1021. #endif
  1022. #ifdef USE_AOV_aov_env_reflection
  1023. extern color aov_env_reflection;
  1024. aov_env_reflection += __transparency * env_color;
  1025. #endif
  1026. reflection += env_color;
  1027. }
  1028. return reflection;
  1029. }
  1030. color trace_refraction(
  1031. normal Nn;
  1032. vector In;
  1033. normal Nf;
  1034. vector V;
  1035. float i_refr_ior;
  1036. float i_refr_gloss;
  1037. float i_refr_gloss_samples;
  1038. output float o_total_internal_refl;
  1039. varying color i_weight )
  1040. {
  1041. extern point P;
  1042. extern uniform float __refracts;
  1043. if( __refracts == 0 )
  1044. {
  1045. o_total_internal_refl = 0;
  1046. return color(0);
  1047. }
  1048. // Compute the sampling parameters.
  1049. float sample_angle = compute_sampling_angle( i_refr_gloss );
  1050. float sample_count = (i_refr_gloss == 0) ?
  1051. min(4, i_refr_gloss_samples) : i_refr_gloss_samples;
  1052. // Compute refracted direction.
  1053. float eta = (In . Nn < 0.0) ? 1.0 / i_refr_ior : i_refr_ior;
  1054. vector refr_dir = refract(In, Nf, eta);
  1055. color refraction = 0;
  1056. if( length( refr_dir ) <= EPSILON )
  1057. {
  1058. o_total_internal_refl = 1;
  1059. refraction = 0;
  1060. }
  1061. else
  1062. {
  1063. color trs = 0;
  1064. refraction = trace(
  1065. P, refr_dir,
  1066. "samplecone", sample_angle,
  1067. "samples", sample_count,
  1068. "subset", "-_3dfm_not_visible_in_refractions",
  1069. "transmission", trs,
  1070. "weight", i_weight );
  1071. if( trs != 0 )
  1072. {
  1073. color env_color = getGiEnvironmentSpecular(refr_dir, sample_count, sample_angle);
  1074. refraction += env_color * trs;
  1075. }
  1076. o_total_internal_refl = 0;
  1077. }
  1078. return refraction;
  1079. }
  1080. /*
  1081. Compute specular highlights.
  1082. NOTES
  1083. - We use the ward anisotropic model. But we sum 3 highlights with decreasing
  1084. roughness and increasing contribution.
  1085. */
  1086. color specular_highlight(
  1087. vector In;
  1088. normal Nf;
  1089. vector V;
  1090. float refl_roughness_u, refl_roughness_v;
  1091. uniform float keyLightsOnly;
  1092. uniform float unshadowed;)
  1093. {
  1094. extern color Cl;
  1095. extern vector dPdu, dPdv;
  1096. extern point P;
  1097. vector xdir = normalize( dPdu );
  1098. vector ydir = normalize( dPdv );
  1099. xdir = normalize(Nf^xdir^Nf);
  1100. ydir = normalize(Nf^ydir^Nf);
  1101. color highlights = 0;
  1102. /* We have three specular higlihgts of diminushing roughness but increasing
  1103. brightness */
  1104. uniform float component_coefs[3] = {0.5, 1.0, 1.5};
  1105. illuminance( P, Nf, PI * 0.5 )
  1106. {
  1107. float isKeyLight = 1;
  1108. if( keyLightsOnly != 0 )
  1109. {
  1110. lightsource( "iskeylight", isKeyLight );
  1111. }
  1112. if( isKeyLight != 0 )
  1113. {
  1114. uniform float nonspecular = 0;
  1115. lightsource( "__nonspecular", nonspecular );
  1116. if( nonspecular == 0 )
  1117. {
  1118. vector Ln = normalize(L);
  1119. float dot_ln = Ln . Nf;
  1120. float dot_vn = V . Nf;
  1121. if( dot_vn*dot_ln>0.0 )
  1122. {
  1123. vector Hn = normalize(V + Ln);
  1124. float dot_hn2 = min(sq(Hn . Nf), 1.0);
  1125. if( dot_hn2>0.0 )
  1126. {
  1127. /* precompute this to get it out of the loop below */
  1128. float k1_devider = 1 / (sqrt(dot_vn * dot_ln) * 4.0 * PI);
  1129. float smooth_step_ln = smoothstep( 0, 0.25, dot_ln );
  1130. uniform float i=0;
  1131. uniform float roughness_coef = 1;
  1132. for( i=0; i<3; i+=1.0 )
  1133. {
  1134. // Compute the highlight due to this light source.
  1135. float k1 =
  1136. (refl_roughness_u * refl_roughness_v * roughness_coef * roughness_coef )
  1137. * k1_devider;
  1138. float k2 =
  1139. sq(Hn . xdir * refl_roughness_u * roughness_coef)
  1140. + sq(Hn . ydir * refl_roughness_v * roughness_coef);
  1141. color c =
  1142. k1 * exp(-k2 / dot_hn2)
  1143. * dot_ln
  1144. * smooth_step_ln;
  1145. varying color cur_cl;
  1146. GET_CL(cur_cl);
  1147. // Accumulate highlights.
  1148. highlights += cur_cl * c * component_coefs[i];
  1149. roughness_coef *= 0.5;
  1150. }
  1151. }
  1152. }
  1153. }
  1154. }
  1155. }
  1156. return highlights;
  1157. }
  1158. /*
  1159. Compute motion vector.
  1160. */
  1161. vector motionVector()
  1162. {
  1163. extern point P;
  1164. extern vector dPdtime;
  1165. vector motion = dPdtime;
  1166. point P0 = transform( "screen", P );
  1167. point P1 = transform( "screen", P + motion );
  1168. return P0 - P1;
  1169. }
  1170. #endif /* _shading_utils_h */