Пример #1
0
def sample_ray_dir(indir, normal, hit_pos, mat):
    u = ti.Vector([0.0, 0.0, 0.0])
    pdf = 1.0
    if mat == mat_lambertian:
        u = sample_brdf(normal)
        pdf = max(eps, compute_brdf_pdf(normal, u))
    elif mat == mat_specular:
        u = reflect(indir, normal)
    elif mat == mat_glass:
        cos = indir.dot(normal)
        ni_over_nt = refr_idx
        outn = normal
        if cos > 0.0:
            outn = -normal
            cos = refr_idx * cos
        else:
            ni_over_nt = 1.0 / refr_idx
            cos = -cos
        has_refr, refr_dir = refract(indir, outn, ni_over_nt)
        refl_prob = 1.0
        if has_refr:
            refl_prob = schlick(cos, refr_idx)
        if ti.random() < refl_prob:
            u = reflect(indir, normal)
        else:
            u = refr_dir
    return u.normalized(), pdf
Пример #2
0
def out_dir(indir, n, mat):
    u = ti.Vector([1.0, 0.0, 0.0])
    if mat == mat_lambertian:
        if abs(n[1]) < 1 - eps:
            u = ti.normalized(ti.cross(n, ti.Vector([0.0, 1.0, 0.0])))
        v = ti.cross(n, u)
        phi = 2 * math.pi * ti.random()
        ay = ti.sqrt(ti.random())
        ax = ti.sqrt(1 - ay**2)
        u = ax * (ti.cos(phi) * u + ti.sin(phi) * v) + ay * n
    elif mat == mat_metal:
        u = reflect(indir, n)
    else:
        # glass
        cos = ti.dot(indir, n)
        ni_over_nt = refr_idx
        outn = n
        if cos > 0.0:
            outn = -n
            cos = refr_idx * cos
        else:
            ni_over_nt = 1.0 / refr_idx
            cos = -cos
        has_refr, refr_dir = refract(indir, outn, ni_over_nt)
        refl_prob = 1.0
        if has_refr:
            refl_prob = schlick(cos, refr_idx)
        if ti.random() < refl_prob:
            u = reflect(indir, n)
        else:
            u = refr_dir
    return ti.normalized(u)
Пример #3
0
def sample(p):
    a = ti.random(ti.f32) * tau
    d = vec2(ti.cos(a), ti.sin(a))
    ret = 0.0
    depth = 0
    steps = 0
    sign = 1.0
    f = sdf(p)
    while depth < 5 and steps < 1e3:
        if f[0] < 0.0:
            sign = -1.0
        steps += 1
        f = sdf(p)
        p += d * sign * f[0]
        if sign * f[0] < 1e-6:
            ret += f[1]  # EMI
            if random_in(f[2]):  # RFL
                depth += 1
                n = sign * gradient(p)
                d = reflect(d, n)
                p += n * 1e-3
            elif random_in(f[3]):  # RFR
                depth += 1
                n = sign * gradient(p)
                eta = 1.50
                if sign > 0.0:
                    eta = 1 / eta
                has, d = refract(d, n, eta)
                if not has:
                    d = reflect(d, n)
                else:
                    p += -n * 1e-3
            else:
                break
        elif abs(f[0]) > 1e1:
            break
        if f[0] < 0:
            sign = -1.0
        else:
            sign = 1.0
    return ret