N88-BASICでレイトレーシング (4回目)

2021/6/4(金) 

N88-BASICでレイトレーシング (4)

 

(by ULproject for N88-BASIC, NL-BASIC)

(NL-BASICはAlt+6で高速化します)

 

今回は陰影(濃淡)を付けます

 


 







 

濃淡は表面の色を表すdiffuse(拡散反射係数)

を使用します

RGB各0~1で指定し、0~1の実数で濃淡を表現

します

N88-BASICの8色モードで濃淡を表すために

RGBの各明るさに対応して乱数で点を描く量の

増減で表現しています

 

前回のx0,y0,ix,iy,izの値を使用して

c、濃淡b、大きさiz×izの点を

(ix × iz + x0 , iy × iz + y0)

PC画面座標に描くサブルーチン

*DRAWSを作ります。

 

IF CL(3) < 0 THEN RETURN

Y1 = Y0 + IY * IZ: Y2 = Y1 + IZ - 1

X1 = X0 + IX * IZ: X2 = X1 + IZ - 1

FOR PY=Y1 TO Y2

  FOR PX=X1 TO X2

    C = 0

    IF RND(1) < CL(0) THEN C = C + 2

    IF RND(1) < CL(1) THEN C = C + 4

    IF RND(1) < CL(2) THEN C = C + 1

    PSET(PX, PY), C

  NEXT

NEXT

RETURN

 

CL(0)=1の時100%、CL(0)=0の時0%にしたいので

0~1未満の乱数 RND(1) < CL(0) のとき

(R:2)を有効にします

RND(1) <= CL(0)とするとCL(0)=0の時も点が

描かれてしまいます

CL(0~2)でRGB(色番号2,4,1)を表します

 

光が球面に垂直に当たった場所は明る

く、水平方向から当たった場所は暗く

見え、その光は乱反射(四方八方に拡散)

しますので、球をどの方向から見ても

光の量は変わりません

つまり、視線Eの方向は無関係ということです

この光を拡散光(diffuse)と言い次式で表わします

 

b = L・N

 

見ている球の中心が原点になるように

変換した座標系で考えると、

 

P:視線が見ている球表面上の点

N:点Pでの球の法線ベクトル(N = P/|P|)

  球の表面の接面に垂直な単位ベクトル

L:点Pから光源を見る方向

 









2

 

bは図2のLの矢印の先からNに

下した垂線との交点と点Pの距離で、

θが0°で最大の1、90°で0となり、

この値は、球表面に当たる単位面積

当たりの光の量に比例します

 

光が当たっていない場所の明るさを

環境光で指定します

DATA文に追加してAMに読込ませます

 

0番の球を減衰しない点光源にし、視線と球の

交点の色cと明るさbを求めるサブルーチン

*SHADE

を作ります

siが交点のある球の番号ですので、

 

GOSUB *DISTANCE

IF T < 0 THEN CL(3) = -1: RETURN

CL(0) = SD(SI,0): CL(1) = SD(SI,1): CL(2) = SD(SI,2): CL(3) = 1

IF SI = 0 THEN RETURN ' light

 

si=0の球は光源にしたので濃淡なしにします

 

V0(0) = V(0)  - SP(SI,0)

V0(1) = V(1)  - SP(SI,1)

V0(2) = V(2)  - SP(SI,2)

P(0)  = V0(0) + E(0) * T

P(1)  = V0(1) + E(1) * T

P(2)  = V0(2) + E(2) * T

 

V0を球を原点にした時のVとして、

P = V0 + Etで、原点にある球上の

点の座標Pを求めます

 

B = SQR(P(0)*P(0) + P(1)*P(1) + P(2)*P(2)) ' P = V0+Et

IF B <> 0 THEN B = 1/B ELSE B = 0

N(0)  = P(0) * B

N(1)  = P(1) * B

N(2)  = P(2) * B                           ' N = P/|P|

 

N = P/|P| を|P|=0のときエラーに

ならないように工夫して求めます

 

P(0)  = SP(0,0) - (P(0) + SP(SI,0))

P(1)  = SP(0,1) - (P(1) + SP(SI,1))

P(2)  = SP(0,2) - (P(2) + SP(SI,2))

B = SQR(P(0)*P(0) + P(1)*P(1) + P(2)*P(2))

IF B <> 0 THEN B = 1/B ELSE B = 0

P(0)  = P(0) * B

P(1)  = P(1) * B

P(2)  = P(2) * B                           ' P = L(光源方向)

 

Pから光源方向の単位ベクトルL

を求めます。Pはもう使わないので

Lの値はPに入れています

 

B = P(0)*N(0) + P(1)*N(1) + P(2)*N(2)      ' b = L・N

IF B < AM THEN B = AM                      ' ambient

 

b = L・Nを求めます

bが環境光am未満ならbを環境光

にします

 

CL(0) = CL(0) * B: CL(1) = CL(1) * B: CL(2) = CL(2) * B

 

で明るさを反映させます

CL(0~2)に表示色(RGB)が入ります

CL(3) < 0の時は交点なしです

 

NL-BASICとblg~.zip(ray004.bas)は

以下のリンクからダウンロードできます

NL-BASIC(N88-BASIC互換?)ホームページ

Readme.txtを読んで遊んで下さい


次回

N88-BASICでレイトレーシング (5回目)


このブログの人気の投稿

NEWS

N88-BASICでゲーム (1回目)