【问题标题】:How to find refraction vector from incoming vector and surface normal?如何从传入向量和表面法线中找到折射向量?
【发布时间】:2015-06-27 19:23:07
【问题描述】:

我正在用 Java 编写光线追踪器,并且正在尝试实现折射,但我对我在该主题上找到的信息感到困惑。如果我有一个入射光线的 3D 矢量,作为 3D 矢量给出的表面法线和两种介质的折射率,我需要应用哪些操作才能获得透射光线的矢量?

【问题讨论】:

标签: java vector raytracing


【解决方案1】:

V_incedence 为归一化的输入向量。设n1n2 为两个表面的折射率。您要计算 V_refraction。令 n 为归一化的法线向量。

V_refraction = r*V_incedence + (rc - sqrt(1-Math.pow(r,2)(1-Math.pow(c,2))))n
where r = n1/n2 and c = -n dot V_incedence.

【讨论】:

  • 感谢您的回复。在第一行中,这是否意味着将 V_incedence.multiply(r) 的向量与 n.multiply(rc - sqrt(1-r^2(1-c^2))) 的向量相加?
  • 这是一个近似值吗?似乎小数点后有偏差
【解决方案2】:

我在我的 ray java tracer 中实现了这个,看看https://github.com/bradforj287/brads-java-raytracer

private static double clamp(final double val, final double min, final double max) {
    return Math.max(min, Math.min(max, val));
}

private Vector3d getRefractionVector(final Vector3d I, final Vector3d N, final double ior) {
    double cosi = clamp(-1, 1, I.dot(N));
    double etai = 1, etat = ior;
    Vector3d n = N;
    if (cosi < 0) {
        cosi = -cosi;
    } else {
        double temp = etai;
        etai = etat;
        etat = temp;
        n = N.multiply(-1);
    }
    double eta = etai / etat;
    double k = 1 - (eta * eta) * (1 - (cosi * cosi));
    if (k <= 0) {
        return Vector3d.ZERO;
    } else {
        return I.multiply(eta).add(n.multiply(((eta * cosi) - Math.sqrt(k))));
    }
}

【讨论】:

    【解决方案3】:

    Bram de Greve 写了一篇关于光线追踪中的反射和折射的精彩文章。你可以找到它here

    他的实现(C++)如下所示:

    Vector refract(const Vector& normal, const Vector& incident, 
                   double n1, double n2) 
    {
        const double n = n1 / n2;
        const double cosI = -dot(normal, incident);
        const double sinT2 = n * n * (1.0 - cosI * cosI);
        if(sinT2 > 1.0) return Vector::invalid; // TIR
        const double cosT = sqrt(1.0 - sinT2);
        return n * incident + (n * cosI - cosT) * normal;
    }
    

    【讨论】:

    • 这是一个非常有用的遮阳篷,尽管我必须编写 cosI = abs(dot(normal, event)) 才能使其正常工作。
    猜你喜欢
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多