| 456 | } |
| 457 | |
| 458 | virtual float sample(const OSL::ShaderGlobals& sg, float rx, float ry, float rz, OSL::Dual2<OSL::Vec3>& wi, float& pdf) const { |
| 459 | const Vec3 wo_l = tf.tolocal(-sg.I); |
| 460 | const float cosNO = wo_l.z; |
| 461 | if (!(cosNO > 0)) return pdf = 0; |
| 462 | const Vec3 m = sampleMicronormal(wo_l, rx, ry); |
| 463 | const float cosMO = m.dot(wo_l); |
| 464 | const float F = fresnel_dielectric(cosMO, eta); |
| 465 | if (Refract == 0 || (Refract == 2 && rz < F)) { |
| 466 | // measure fresnel to decide which lobe to sample |
| 467 | const Vec3 wi_l = (2.0f * cosMO) * m - wo_l; |
| 468 | const float D = evalD(m); |
| 469 | const float Lambda_o = evalLambda(wo_l); |
| 470 | const float Lambda_i = evalLambda(wi_l); |
| 471 | |
| 472 | const float G2 = evalG2(Lambda_o, Lambda_i); |
| 473 | const float G1 = evalG1(Lambda_o); |
| 474 | |
| 475 | wi = tf.toworld(wi_l); |
| 476 | |
| 477 | pdf = (G1 * D * 0.25f) / cosNO; |
| 478 | float out = G2 / G1; |
| 479 | if (Refract == 2) { |
| 480 | pdf *= F; |
| 481 | return out; |
| 482 | } else |
| 483 | return F * out; |
| 484 | } else { |
| 485 | const Vec3 M = tf.toworld(m); |
| 486 | float Ft = fresnel_refraction (sg.I, M, eta, wi); |
| 487 | const Vec3 wi_l = tf.tolocal(wi.val()); |
| 488 | const float cosHO = m.dot(wo_l); |
| 489 | const float cosHI = m.dot(wi_l); |
| 490 | const float D = evalD(m); |
| 491 | const float Lambda_o = evalLambda(wo_l); |
| 492 | const float Lambda_i = evalLambda(wi_l); |
| 493 | |
| 494 | const float G2 = evalG2(Lambda_o, Lambda_i); |
| 495 | const float G1 = evalG1(Lambda_o); |
| 496 | |
| 497 | const Vec3 ht = -(eta * wi_l + wo_l); |
| 498 | const float invHt2 = 1.0f / ht.dot(ht); |
| 499 | |
| 500 | pdf = (fabsf(cosHI * cosHO) * (eta * eta) * (G1 * D) * invHt2) / fabsf(wo_l.z); |
| 501 | float out = G2 / G1; |
| 502 | if (Refract == 2) { |
| 503 | pdf *= Ft; |
| 504 | return out; |
| 505 | } else |
| 506 | return Ft * out; |
| 507 | } |
| 508 | return pdf = 0; |
| 509 | } |
| 510 | |
| 511 | private: |
| 512 | static float SQR(float x) { |
nothing calls this directly
no test coverage detected