| 393 | return Refract ? 1 - fr : fr; |
| 394 | } |
| 395 | virtual float eval (const OSL::ShaderGlobals& sg, const OSL::Vec3& wi, float& pdf) const { |
| 396 | Vec3 wo = -sg.I; |
| 397 | const Vec3 wo_l = tf.tolocal(wo); |
| 398 | const Vec3 wi_l = tf.tolocal(wi); |
| 399 | if (Refract == 0 || Refract == 2) { |
| 400 | if (wo_l.z > 0 && wi_l.z > 0) { |
| 401 | const Vec3 m = (wi_l + wo_l).normalize(); |
| 402 | const float D = evalD(m); |
| 403 | const float Lambda_o = evalLambda(wo_l); |
| 404 | const float Lambda_i = evalLambda(wi_l); |
| 405 | const float G2 = evalG2(Lambda_o, Lambda_i); |
| 406 | const float G1 = evalG1(Lambda_o); |
| 407 | |
| 408 | const float Fr = fresnel_dielectric(m.dot(wo_l), eta); |
| 409 | pdf = (G1 * D * 0.25f) / wo_l.z; |
| 410 | float out = G2 / G1; |
| 411 | if (Refract == 2) { |
| 412 | pdf *= Fr; |
| 413 | return out; |
| 414 | } else { |
| 415 | return out * Fr; |
| 416 | } |
| 417 | |
| 418 | } |
| 419 | } |
| 420 | if (Refract == 1 || Refract == 2) { |
| 421 | if (wi_l.z < 0 && wo_l.z > 0.0f) { |
| 422 | // compute half-vector of the refraction (eq. 16) |
| 423 | Vec3 ht = -(eta * wi_l + wo_l); |
| 424 | if (eta < 1.0f) |
| 425 | ht = -ht; |
| 426 | Vec3 Ht = ht.normalize(); |
| 427 | // compute fresnel term |
| 428 | const float cosHO = Ht.dot(wo_l); |
| 429 | const float Ft = 1.0f - fresnel_dielectric(cosHO, eta); |
| 430 | if (Ft > 0) { // skip work in case of TIR |
| 431 | const float cosHI = Ht.dot(wi_l); |
| 432 | // eq. 33: first we calculate D(m) with m=Ht: |
| 433 | const float cosThetaM = Ht.z; |
| 434 | if (cosThetaM <= 0.0f) |
| 435 | return 0; |
| 436 | const float Dt = evalD(Ht); |
| 437 | const float Lambda_o = evalLambda(wo_l); |
| 438 | const float Lambda_i = evalLambda(wi_l); |
| 439 | const float G2 = evalG2(Lambda_o, Lambda_i); |
| 440 | const float G1 = evalG1(Lambda_o); |
| 441 | |
| 442 | // probability |
| 443 | float invHt2 = 1 / ht.dot(ht); |
| 444 | pdf = (fabsf(cosHI * cosHO) * (eta * eta) * (G1 * Dt) * invHt2) / wo_l.z; |
| 445 | float out = G2 / G1; |
| 446 | if (Refract == 2) { |
| 447 | pdf *= Ft; |
| 448 | return out; |
| 449 | } else { |
| 450 | return out * Ft; |
| 451 | } |
| 452 | } |
nothing calls this directly
no test coverage detected