Пример #1
0
def microfacetNoExp(mu_o, mu_i, eta_, alpha, phi_d):
    sinThetaI = f.safe_sqrt(1.0 - mu_i * mu_i)
    sinThetaO = f.safe_sqrt(1.0 - mu_o * mu_o)
    cosPhi = math.cos(phi_d)
    sinPhi = math.sin(phi_d)

    wi = np.array([-sinThetaI, 0.0, -mu_i])
    wo = np.array([sinThetaO * cosPhi, sinThetaO * sinPhi, mu_o])
    reflect = (-mu_i * mu_o) > 0

    if (mu_o == 0.0) or (mu_i == 0.0):
        return 0.0

    conductor = eta_.imag != 0.0
    if conductor and not reflect:
        return 0.0

    eta = eta_
    if not (-mu_i > 0 or conductor):
        eta = (complex(1.0, 0.0) / eta_)

    scalingFactor = 1.0
    if not reflect:
        scalingFactor = eta.real
    H = wi + wo * scalingFactor
    H /= np.linalg.norm(H)

    H *= np.sign(H[2])  # math::signum(Frame::cosTheta(H));

    cosThetaH2 = H[2] * H[2]
    D = 1.0 / (math.pi * alpha * alpha * cosThetaH2 * cosThetaH2)

    # Calculate the fresnel term
    F = 0.0
    if not conductor:
        F, _ = fresnelDielectric(np.dot(wi, H), 0, eta_.real)
    else:
        F = fresnelConductor(np.abs(np.dot(wi, H)), eta)
    G = smithG1(wi, H, alpha) * smithG1(wo, H, alpha)

    if reflect:
        return F * D * G / (4.0 * np.abs(mu_i * mu_o))
    else:
        sqrtDenom = np.dot(wi, H) + eta.real * np.dot(wo, H)

        return np.abs(((1 - F) * D * G * eta.real * eta.real * np.dot(wi, H) * np.dot(wo, H)) / (
            mu_i * mu_o * sqrtDenom * sqrtDenom))
Пример #2
0
def getAB(mu_i, mu_o, eta, alpha):
    reflect = (-mu_i * mu_o) > 0
    sinMu2 = f.safe_sqrt((1.0 - mu_i * mu_i) * (1.0 - mu_o * mu_o))
    if reflect:
        temp = 1.0 / (alpha * (mu_i - mu_o))
        A = (mu_i * mu_i + mu_o * mu_o - 2) * temp * temp
        B = 2.0 * sinMu2 * temp * temp
    else:
        temp = 1.0 / (alpha * (mu_i - eta.real * mu_o))
        A = (mu_i * mu_i - 1.0 + eta.real * eta.real * (mu_o * mu_o - 1.0)) * temp * temp
        B = 2 * eta.real * sinMu2 * temp * temp

    return A, B
Пример #3
0
def fresnelConductor(cosThetaI, eta_):
    eta = eta_.real
    k = eta_.imag

    cosThetaI2 = cosThetaI * cosThetaI
    sinThetaI2 = 1.0 - cosThetaI2
    sinThetaI4 = sinThetaI2 * sinThetaI2

    temp1 = eta * eta - k * k - sinThetaI2
    a2pb2 = f.safe_sqrt(temp1 * temp1 + 4 * k * k * eta * eta)
    a = f.safe_sqrt(0.5 * (a2pb2 + temp1))

    term1 = a2pb2 + cosThetaI2
    term2 = 2 * a * cosThetaI

    Rs2 = (term1 - term2) / (term1 + term2)

    term3 = a2pb2 * cosThetaI2 + sinThetaI4
    term4 = term2 * sinThetaI2

    Rp2 = Rs2 * (term3 - term4) / (term3 + term4)

    return 0.5 * (Rp2 + Rs2)
Пример #4
0
def microfacetNoExpFourierSeries(mu_o, mu_i, etaC, alpha, n, phiMax):
    # const
    nEvals = 200
    eps = 10e-4

    def foo(a):
        return microfacetNoExp(mu_o, mu_i, etaC, alpha, a)

    reflect = - mu_o * mu_i > 0.0
    sinMu2 = f.safe_sqrt((1.0 - mu_i * mu_i) * (1.0 - mu_o * mu_o))
    phiCritical = 0.0
    conductor = etaC.imag != 0.0

    if -mu_i > 0.0 or conductor:
        eta = etaC
    else:
        eta = complex(1.0, 0.0) / etaC

    if reflect:
        if not conductor:
            if sinMu2 == 0:
                temp = -1.0
            else:
                temp = (2.0 * eta.real * eta.real - mu_i * mu_o - 1.0) / sinMu2
            phiCritical = f.safe_acos(temp)
    elif not reflect:
        if eta.real > 1.0:
            etaDenser = eta.real
        else:
            etaDenser = 1.0 / eta.real
        if sinMu2 == 0:
            temp = -1.0
        else:
            temp = (1.0 - etaDenser * mu_i * mu_o) / (etaDenser * sinMu2)
        phiCritical = f.safe_acos(temp)

    if reflect:
        if phiCritical > eps and phiCritical < phiMax - eps:

            b1 = filonIntegrate(foo, n, nEvals, 0.0, phiCritical)
            b2 = filonIntegrate(foo, n, nEvals, phiCritical, phiMax)
            b = np.concatenate((b1, b2), axis=0)
        else:
            b = filonIntegrate(foo, n, nEvals, 0.0, phiMax)
    else:
        b = filonIntegrate(foo, n, nEvals, 0.0, min(phiCritical, phiMax))

    # ToDo: if (phiMax < math::Pi - math::Epsilon) SVD stuff
    return b