N88-BASICでレイトレーシング (5回目)
2021/6/5(土)
N88-BASICでレイトレーシング (5回目)
(by ULproject for N88-BASIC, NL-BASIC)
(NL-BASICはAlt+6で高速化します)
今回は、次の画面のように陰を描きます。
図3 点Pが陰になる場合
陰は視線と見えている球との交点Pから光源表面
までの間に、光源と自身を除く球があれば点Pに
光が当たっていないので暗くすれば陰になります
自身の球が検索されないように点Pを少し光源に
近づけて点Pを球表面から浮かす必要があります
検索時に自身を除くという方法は、球やポリゴン
のみのに使用できますが、トーラス(ドーナツ型)
などの自身の陰がうつる形に対応できません
今回は球のみですのでどちらでもかまいませんが、
検索部分(*DISTANCE)を変更しなくてよい、点Pを
浮かす方法にしました
また光源自身が含まれないように光源表面までの
距離も少し短めで判定します
今回、陰がうまく出る位置に球を移動しました
DATA文の座標を変えてあります
また、解像度を多くして画面を大きくしました
*SHADEを変更していきます
途中で*DISTANCEを呼ぶので、
そこで使用している変数名を避けます
V(0) = P(0) + SP(SI,0)
V(1) = P(1) + SP(SI,1)
V(2) = P(2) + SP(SI,2) ' V = P (元の座標)
E(0) = SP(0,0) - V(0)
E(1) = SP(0,1) - V(1)
E(2) = SP(0,2) - V(2)
VとEはこの後使用されないので、上書きします。
球表面の点PをV、点Pから光源方向をEにして
*DISTANCEを呼ぶ準備をします。
B = SQR(E(0)*E(0) + E(1)*E(1) + E(2)*E(2))
T1 = B - SR(0) ' 光源表面までの距離
光源中心までの距離から光源の半径を引いて表面
までの距離をt1とします。
IF B <> 0 THEN B = 1/B ELSE B = 0
E(0) = E(0) * B
E(1) = E(1) * B
E(2) = E(2) * B ' E = L(光源方向)
E=E/|E|でEを単位ベクトルにします。
B = 0.1' 1.0E-8 ' 少し手前
T1 = T1 - B*2 ' 光源表面までより短く
V(0) = V(0) + E(0) * B
V(1) = V(1) + E(1) * B ' 点Pと重ならないように
V(2) = V(2) + E(2) * B ' Vを少し光源に寄せる
光源表面までの距離の両端を少し短くし、
点Pを表面から少し浮かせます。
GOSUB *DISTANCE
B = E(0)*N(0) + E(1)*N(1) + E(2)*N(2) ' b = L・N
IF 0 < T AND T < T1 THEN B = 0 ' 陰
IF B < AM THEN B = AM ' ambient
*DISTANCEを呼ぶと一番近いtが得られ、0<t<t1
なら光が遮られているので、明るさをb=0にし、
あとは、前回と同じです。
NL-BASICとblg~.zip(ray005.bas)は
以下のリンクからダウンロードできます
Readme.txtを読んで遊んで下さい
次回