0

私は C++ と OpenGL (glDrawPixels) を使用してレイ トレーサーに取り組んでおり、これまでのところうまくいっています。ただし、私のシェーディングは少しずれているようです。強度間に露骨な線を入れずに、球を少し滑らかに見せたいです。現時点では、強度 = Id * pd * (N dot L) であるランバート シェーディングを実装しようとしています。法線ベクトルと光​​ベクトルを正規化して (N dot L) を計算する必要があることはわかっていますが、Id と pd (強度拡散と比例係数) はどうですか? 次のことを達成するために、定数値 2.5 を使用しています。

これは私のシェーディングがどのように見えるかの写真です

明らかに、2.5 は完全に恣意的なものであり、他の試みが適切なシェーディングにさえ似ていなかったので、私はそれを使用しているだけです。上記の式は、色に強度を掛けるべきであることを示唆しているようです。これは私の方法です:

Color simpleIlluminate(Vector3D normal, Vector3D light, Color color) {
    float intensity = dotProduct(normal, light)*2.5f;
    color = Color((unsigned int)intensity*color.r, (unsigned int)intensity*color.g, (unsigned int)intensity*color.b);
    return color;
}

法線ベクトルと光​​ベクトルが正しいと仮定します。Color は、RGB 値ごとに unsigned int を持つ、私が作成した単なる色の構造体です。パラメータ Color color は、シェーディングしたい球の色です。たとえば、red = Color(255,0,0) です。色の強度を変更するには、各値に計算した強度を掛けるだけですが、実行すると正しく表示されません。

誰かが私が欠けているものを説明し、ベクトルと球の色が与えられたときに正しい関数がどのように見えるべきかを教えてもらえますか? 私はいたるところを見てきましたが、良い解決策が見つかりません。float から unsigned int への変換が間違っている可能性もありますが、よくわかりません。どんな助けでも大歓迎です。

4

2 に答える 2

3

その 2.5 係数はおそらく結果に悪影響を及ぼしているため、削除します。係数を 0 と 1 の範囲外にスケールアップしているため、バンディングが非常によく発生する可能性があります。

ランバート反射率はコサイン反射率とも呼ばれ、理解するのは簡単です。平面を考えてみましょう。ライトが平面に対して垂直である場合、すべてのライトがサーフェスに落ちます (100%、または係数 1.0)。ライトがその平面に平行に向いている場合、0 のライトがサーフェスに落ちます (すべての光線は平行であるため、平面と交差することはないため、係数または 0)。

ランバート反射率は、光の方向と表面の法線の間の角度のコサインにすぎず、範囲は 0 (平面に光が当たらない) から 1.0 (平面に当たるすべての光) です。Cosine(90) = 1. Cosine(0) = 0 であることに注意してください。したがって、Cosine の法則 (Lambertian 反射率) と呼ばれます。

于 2016-10-10T13:27:30.413 に答える
0

float から unsigned int への変換が間違っている可能性もあります

スポット。(unsigned int)intensity*color.rと同等((unsigned int)intensity)*color.rです。したがって、強度は色で乗算される前に個別のレベルになり、それらの線が得られます. (unsigned int)(intensity*color.r)代わりに試してください。

于 2016-10-10T13:27:19.100 に答える