3

そのため、私が構築しているレイ トレーサーでは、コースティクス エフェクトと共に屈折を球に対して機能させましたが、ガラスの球は特に見栄えがよくありません。屈折した計算は正しいと思います。なぜなら、光は予想どおりに反転して曲がっているように見えますが、ガラスのようには見えず、紙か何かのように見えるからです。

内部全反射がガラスの外観の多くの原因であると読んだことがありますが、屈折した光線のいずれかが臨界角を超えるかどうかをテストしたところ、臨界角を超えるものはありませんでした。全反射。これが正常なのか、それとも何か間違ったことをしたのかはわかりません。以下に屈折コードを投稿しましたので、何か提案があればぜひ聞いてください。

/*
 * Parameter 'dir' lets you know whether the ray is starting
 * from outside the sphere going in (0) or from in the sphere
 * going back out (1).
 */
void Ray::Refract(Intersection *hit, int dir)
{

    float n1, n2;
    if(dir == 0){ n1 = 1.0; n2 = hit->mat->GetRefract(); }
    if(dir == 1){ n1 = hit->mat->GetRefract(); n2 = 1.0; }

    STVector3 N = hit->normal/hit->normal.Length();
    if(dir == 1) N = -N;
    STVector3 V = D/D.Length();
    double c1 = -STVector3::Dot(N, V);
    double n = n1/n2;

    double c2 = sqrt(1.0f - (n*n)*(1.0f - (c1*c1))); 

    STVector3 Rr = (n * V) + (n * c1 - c2) * N;

    /*These are the parameters of the current ray being updated*/
    E = hit->point;  //Starting point
    D = Rr;          //Direction
}

このメソッドは、再帰的に実行されるメインのレイ トレーシング メソッド RayTrace() で呼び出されます。以下は、屈折を担当する小さなセクションです。

    if (hit->mat->IsRefractive())
    {    
        temp.Refract(hit, dir); //Temp is my ray that is being refracted
        dir++;
        result += RayTrace(temp, dir); //Result is the return RGB value.
    } 
4

1 に答える 1

5

そうです、球の内部反射を完全に得ることは決してありません(外部から見た場合)。これは対称性のためです。球の内側の光線は、両端で同じ角度で表面に当たります。つまり、一方の端で臨界角を超えると、もう一方の端でもそれを超える必要があります(したがって、そもそも外側から球に入ることができなかったでしょう)。

ただし、フレネルの法則によれば、それでも多くの部分的な反射が得られます。あなたのコードがそれを説明しているようには見えません。それがおそらくあなたのガラスが偽物に見える理由です。それを含めてみて、それが役立つかどうかを確認してください。

(はい、それは光線が屈折面に当たるたびに2つに分割されることを意味します。これは実際に起こるので、それと一緒に暮らす必要があります。両方のパスをトレースするか、使用している場合はとにかくランダム化されたレイトレーシングアルゴリズム、適切な重みでそれらの1つをランダムにサンプリングするだけです。)

追伸 光の偏光のようなものを扱いたくない場合は、フレネルの式に対するシュリックの近似を使用することをお勧めします。

于 2012-12-25T23:47:55.083 に答える