光线跟踪器透明度中的条纹

时间:2016-09-16 23:31:53

标签: go graphics raytracing

我现在正在golang写一个路径追踪器,我有漫反射和镜面反射的材料。然而,我的透明材料看起来很怪异和环绕。

可能导致此问题的原因是什么?refracting sphere

这是相关代码:

积分仪:

func render(scene *Scene, cam *Camera, img *image.RGBA) {
    random := rand.New(rand.NewSource(1))
    for y := Height - 1; y >= 0; y-- {
        for x := 0; x < Width; x++ {
            col := RGB{0.0, 0.0, 0.0}

            for i := 0; i < SPP; i++ {
                u := (float64(x) + random.Float64()) / float64(Width)
                v := (float64(y) + random.Float64()) / float64(Height)

                r := cam.RayAt(u, v, random)

                c := getColor(r, scene, 0, random)
                col.R += c.R
                col.G += c.G
                col.B += c.B
            }
            col.R *= 255.0 / SPP
            col.G *= 255.0 / SPP
            col.B *= 255.0 / SPP
            img.Set(x, y, color.RGBA{uint8(col.R), uint8(col.G), uint8(col.B), uint8(255)})
        }
    }

}
func getColor(r Ray, scene *Scene, depth int, rnd *rand.Rand) RGB {
    if depth > MaxDepth {
        return background(r)
    }
    b, hit := scene.Hit(r, tMin, tMax)

    if b {
        bounced, bouncedRay := hit.Bounce(r, rnd.Float64(), rnd.Float64(), hit, rnd)
        if bounced {
            bounceColor := getColor(bouncedRay, scene, depth+1, rnd)
            return hit.Material.Color().Multiply(bounceColor)
        }
        return hit.Material.Color()
    }
    return background(r)
}

材料:

type Material struct {
    Col          RGB
    Index        float64 // refractive index
    Reflectivity float64
    Transparency float64 // the amount of light to let through
    Gloss        float64 // reflection cone angle in radians
}

func (m *Material) Color() RGB {
    return m.Col
}

func (m *Material) Bounce(r Ray, fu, fv float64, hit Hit, rnd *rand.Rand) (bool, Ray) {

    var direction Vector

    if m.Reflectivity > 0 && rnd.Float64() < m.Reflectivity {
        // we should reflect
        reflectDirection := r.Direction.Reflect(hit.Normal)
        direction = Cone(reflectDirection, m.Gloss, fu, fv, rnd)

    } else if m.Transparency > 0 && rnd.Float64() < m.Transparency {
        // we should refract
        _, direction = r.Direction.Refract(hit.Normal, m.Index)
    } else {
        direction = hit.Normal.Add(VectorInUnitSphere(rnd))
    }

    return true, Ray{hit.Point, direction}
}

载体:

func (v Vector) Refract(ov Vector, n float64) (bool, Vector) {
    uv := v.Normalize()
    uo := ov.Normalize()
    dt := uv.Dot(uo)
    discriminant := 1.0 - (n * n * (1 - dt*dt))
    if discriminant > 0 {
        a := uv.Subtract(ov.MultiplyScalar(dt)).MultiplyScalar(n)
        b := ov.MultiplyScalar(math.Sqrt(discriminant))
        return true, a.Subtract(b)
    }
    return false, Vector{}
}

0 个答案:

没有答案