これが、私たちのハックが実際のランバートにどのように近似するかです. ボールのポイントを選択すると、腹の部分に確率が高く、いくつかの対応する底がほとんどありません。
グレージング角度には光線がほとんどなく、検出された角度から逸脱するこれらの対応する寄与は非常に小さくなります。
ここで言及されている本物のランバートに関しては、使用される方法は、ボール上の点を見つけてから cos を計算することです。
したがって、ボール上のポイントを取得する必要があります。これは非常に簡単です。ボールの中心に単位ベクトル オフセットを追加するだけです。上のランダムな単位ベクトルを生成する関数があるので、
取得したら、ボールの中心に追加します。
この計算には本質的な違いはないように見えますが、実際の結果では黒い点が少なくなり、上記は使用されたランバートです。
私に限らず、作者の絵はよく見ると黒点が少ない。
こちらのランバートの方が均一、つまりどちらも法線に近い部分が散乱する確率が高いとも言えますが、ランバートの方が均一です。
ここで彼は、私たちのハックが cos^3 に似ており、このランバートが cos に似ていることを意味しているようです。しかし、なぜ説明しなかった。. .
つまり、Lambert を変更した後、散乱がよりランダムになったため、影が少なくなり、ボールが明るくなり、表面が滑らかになりました。
上記で通常のオフセットを検討してきたことに注意してください。通常のオフセットがない場合はどうなるでしょうか。(つまり、ターゲットを探すとき、最初に法線を追加するために p が使用されます)
最初に法線の役割を見てください。つまり、取得したランダム単位ベクトルがボールの内側を指している場合、このベクトルを外向き方向として直接使用するのは合理的ではありません。
したがって、ここで最初に発見をオフセットすると、考慮するすべてのポイントがサーフェスの外側にあるため、不合理な結果は生じません。
もちろん、単位ベクトル生成時に内部に放出される半分を除外することも可能です。このように、法線を使用しないオフセットは、すべての方向でランダムにすることができます。
マテリアルを検討する場合、クラスの設計には 2 つのアイデアがあります. 1 つは、マテリアルを設計し、さまざまなパラメータを開いてさまざまな効果を調整することです.
また、さまざまなマテリアルがあり、最初のオープン パラメータの一部をゼロに直接調整します (つまり、タイプに応じてハード コードの一部にする必要があります)。
ここでは後者を使用します。それから、それはまだ似たような考えです。すべての材料が 1 つのことを解決しなければなりません。実際、入射光を与えるのは BRDF であり、反射光を与えるのは BRDF です。
色などの情報を含む方向を含みます。
したがって、ここでも純粋仮想インターフェイスのカプセル化が行われます。
カプセル化後、スキャッター関数を呼び出すタイミングを考えると、hit 呼び出しが戻った後に呼び出す必要があります。
これまでのカラーリング作業はすべて、rec. ここで、計算時にオブジェクトのマテリアル メンバーを使用する必要があります。これにはパラメーターが必要です。
パラメータの送信。rec カプセル化の精神でパラメータの送信を減らしていました。
したがって、ポインターもここのレコードに配置されます。したがって、全体的なプロセスは次のようになります。まず、マテリアルをオブジェクトのメンバーにする必要があります。次に、適切なマテリアルをオブジェクトに割り当てる必要があります。
オブジェクトはヒットの計算に参加し、この時点でマテリアルを rec に入れる必要があります。ヒット実行が完了した後、rec にはヒット面の法線と位置、およびスキャッターなどのデータがあります。
この関数は、最終的な色を直接取得できます。
この作品は、上記のプロセス全体についてです。
それがコードで行うことです/
親マテリアルのインターフェイス仕様を使用して、さまざまなサブマテリアルを作成し、これらのサブマテリアルを適切なタイミングでさまざまなオブジェクトに与えることができます。
オブジェクトにさまざまなプロパティを持たせます。したがって、色を計算するときは、さまざまなサブクラス オブジェクトに対してポリモーフィック コールが行われます。
循環参照のためにここにステートメントが追加され、記録に資料が必要であることに注意してください。そして資料には記録が必要です。両方のファイルが互いに含まれている場合、それは間違いなく間違っています。
ここで言及されている 2 つの事柄があります。1 つは減衰と吸収です。彼が言った減衰とは、入ってくる白い光と出ていく赤い光を指し、これが減衰です。吸収では、白色光が直接入り、光は出ません。
ここでは減衰のみを考慮することができます。つまり、白色光を仮定すると、反射されるのはアルベドです。両方を考慮することもできます。2 つの反射の合計量が同じであることを確認するには、
p確率を吸収させてから、反射をpで割ります。つまり、反射率は高くなりますが、直接反射しない場所もあります。
次に、ランダムに生成されたものである scatter_diretion に関する別の質問があります。つまり、法線がランド単位ベクトルと完全に反対の場合です。
反射方向が 0 ベクトルであるため問題が発生し、後で計算エラーが発生します。
ですから、ここで判断を下し、この状況を破棄してください。
上記のファブは、浮動小数点数の絶対値用です。
Ray color 関数は、渡されたパラメーターが光線であることを理解し、その関数は光線の色です。
その後、実際の光路では、反射光として機能します. Lambert によると、彼の光は、入射光の色に Lambert 減衰係数を掛けたものであり、これが反射光です。
望ましい結果。
そして、入射光の色をどう計算するかというと、やはりレイカラーなので再帰的ですね。
このようにして、オブジェクトに色を追加できます。
ここから鏡面反射の考察に入りますが、この導出は実は先のひし形の導出と同じです。
反射方向の設計についてですが、ここのrecに記録されている法線は判断と選択なのでちょっとわかりにくいのですが、この法線は光線に対する法線でなければならないので、ドットは0より大きいようです。
0 に等しい接線の場合は 1 つだけです。
で、今回書き直しているのですが、上側が接線なら、この点に光が当たっていないということなので、昔は黒く見えていたはずです。
もちろん、ここでのスキャッターは結局標準化されたインターフェースなので、さまざまなマテリアルの計算が異なるため、そのような戻り値を必要とする特定のマテリアルがあるかもしれません/
ここで色に問題があります。
中央のものはより明白で、デバッグが容易です。
次に、次のように彼の色を追跡しています。
下のラープは再帰的です。ここではシーンを単純化し、ミラー反射を使用しているためです。ボールは 1 つしかないため、再帰を 1 回行った後は衝突がなくなり、元に戻ります。
戻り値が見えますが、戻った後は raycolor の戻り値で、これに atten を掛けて再度戻ると、今度は main の呼び出しに戻ります。
ここで設定する atten は 1 です。メイン側で同じ値を受信するはずが、変更されているため、このリターンで問題が発生します。
実際、ここでのシングルステップ デバッグは、ここで vec の乗算オーバーロードを使用していることがわかります。
現在のデバッグプロセスは、基本的にはピクセルをロックして、問題が色にある場合は色を追跡することだと思います。基本的に、理由はまだ見つかります。
ここにも関数があり、将来デバッグするために直接呼び出しても問題ありませんが、出力に少し時間がかかるため、カラーで出力を手動で削除する必要があるかもしれません。
これで効果は正しくなりましたが、ここでボールが現在ミラー ボールとして機能していることに注意してください。つまり、完全に反射し、まだ屈折していません。
物体の表面があまり滑らかではないことを考えると、わずかな違いの 2 つの入射角に対して同じ反射光が得られる可能性があります。それが上のように見えるものです。
すると、ここでレイトレーシングすると、反射光にわずかなゆらぎがあると考えられ、反射光にオフセット(ボールの半径がオフセット量に相当)が加算されます。
ボールの半径をパラメータとして使用できます。
さらに、彼はここで問題に言及しました。つまり、ボール全体が非常に大きい場合、局所的な表面が非常に平らになり、グレージング角度を追加すると、外乱の結果がボールに入る可能性があります。(しかし、この状況は彼のコードでは考慮されていません。ここで考慮しない場合、トレースされた光は反射後に実際にボールに入り、別の面から出てきます。
これは間違っています。ボールが不透明であれば、たとえ透明であっても、屈折角がなければなりません。それを考慮したい場合は、モデルの法線を変更して、常に外側を向くようにする必要があります。
このように色を計算すると、出ても真っ黒になるのですが、常に外側を向くように変更すると、透明なボールが本当にボールの内側に入ります。. . . . ここで別の問題があります。)
ここでの導出も比較的単純で、著者は R' の特定の導出プロセスを彼に与えませんでしたが、括弧の部分についてです。
入射光線 R を単位ベクトルと考えると、ncosθ は実際には n 方向の R 射影の長さです。(R と n の両方が単位ベクトルであるため)
次に、これに R を追加します。これは、当然、これら 2 つの辺によって形成される三角形の 3 番目の辺です。
次に、2つのηの比較は、実際にはsinの比較であり、斜辺の場合は1であり、sin値は実際には水平辺の長さであり、水平長さの比率に上記の水平ベクトルを掛けます。
得られるのは、R'vertical である屈折部分の水平ベクトルです。
残りは簡単です。R' で垂直と水平を計算し、R' を取得します。ここで得られるベクトルは 2 つの加算であることに注意してください。
現実には。
上記のアルゴリズムには考慮が欠けています。つまり、オブジェクトがガラスや水などの媒体から空気に移動するときに、全反射現象が発生します。
その時、私たちの反射角 sinθ' は 1 よりも大きくなり、解はありません。
したがって、ここには制限が必要です。1 になると、重大な状態に達したことを意味します。それが全反射です。届かない場合は、屈折と反射を同時に行うことができます。
詳しくはメディアをご覧ください。
これが罪の解決です。
実際のアルベドは、見る角度によって変化します。実はこれがフレネル現象です。
最後に興味深いトリックがあります.負の半径を持つボールを作ります.このボールは別のボールの中心と同じ位置に置かれます.負の数の絶対値は半径の半径よりも小さくなります.もう一方のボール。
これがどのような結果をもたらすか、トレース コードを知っています。まず、ほぼすべての場合で半径が 2 乗されます。つまり、交差すると見なされる場合、マイナス記号を追加した後は影響を受けません。次の場合のみです。の符号は、rec に記録されている法線に正確に影響します。
一般に、法線は実際には逆になっていますが、上記のコードは不完全であり、後のバージョンは次のとおりです。
この修正後、recに記録されます。ここが面白いところで、
まず内側のボールに外側から光が入る時はfront_faceがtrueのはずですが、ここで法線が反転しているのでここはfalseです。
もちろん、ここでの法線はいずれにせよ、光線に対して方向を取得し、次の計算には影響しません。
重要なのは、ここのフロントが不当に割り当てられていることです/
しかし、これは私たちが今使用したものであり、これに基づいて屈折率の比率を決定します。
一般に、front_face 変数の反転により、光は内側から外側に向かっていると見なされます。
つまり、内側のボールの内側は空気、外側はガラスなどです。
そして、実際に彼の外側にガラスを置いたので、プログラムの計算によれば、彼はそれがガラス玉であると考えますが、中は中空のガラス玉です。
縦横比が決まれば、縦と横のFOVを1つだけ決めればよいので、ここでは縦のFOVを考えます。
FOV の変更に関しては、仮想ビューポートが実際に変更され、放射される光線の角度に影響します。ビューポート サーフェスのサイズを変更します。
カメラの決定に関して、ここでは、カメラの位置、カメラの焦点、上方向の 3 つの量を指定します。
この 3 つを使用すると、外積によって直交座標軸を構築できます。
この作品は、カメラの uw 軸と選択された up が常に同じ平面上にあると言っています. これは、up と w によって決定される平面に垂直な十字の最初の軸を通過するので、理解しやすいです. 3 番目の 1 つの軸もこの平面内にある必要があります。これは、他の 2 つの軸の平面に対して垂直でなければならないためです。
この点で、アップ軸の機能に関しては、カメラの軸が位置する面を調整することで制御できることが実際に示されています。数回傾けたというなら、カメラ全体の軸も傾いているに違いない。
比例してスケーリングすると、カメラからの距離の前後の位置がそれに応じて変化するためです。実際、上記の書き込み方法は、この面を焦点距離に置くことです。
このサーフェスに配置することは、他の位置に配置することと同じであり、効果はありません。このサーフェスの唯一の機能は、光線の方向を決定することであり、比例スケーリング + 前後の移動では、光線は変化しません。
この開口部は、ここではプリズムの半径を決定します。つまり、焦点ぼけの程度を決定します。
ここでカメラを単純化する方法については、レンズを通過するすべての光がカメラであるセンサーに焦点を合わせるからです。したがって、センサーからレンズまでのセクションを考慮しないでください