N88-BASICでかんたんにレイトレーシング 第8回

このホームページのBLOG内リンク先のブログで公開しました。

第1回~第8回の記事(~.doc)とBASIC(~.bas)は

このホームページからダウンロードできます。

以下に、r008.bas の LISt と画面を載せておきます。

1000 '----------------------------------------------------------------------

1010 ' N88-BASICでかんたんにレイトレーシング 第8回

1020 '

1030 ' by ULproject

1040 '

1050 ' for BASIC ( N88-BASIC、VL-BASICなど )

1060 '

1070 ' 2019.12

1080 '

1090 ' スクリーン上の各点からの視線で球をトレース

1100 ' 球0~2の存在を色で確認する(3つの円が見える)

1110 ' 球0は減衰しない点光源(陰対応)

1120 '

1130 ' コメントの大文字はベクトル、小文字はスカラー

1140 '----------------------------------------------------------------------

2000 SN = 3 ' 球の個数

2010 DIM SX(SN), SY(SN), SZ(SN), SR(SN), SC(SN)

2020 ' center radius color

2030 SX(0) = -500: SY(0) = 500:SZ(0) = 500: SR(0) = 2:SC(0) = 7 ' light

2040 SX(1) = 3: SY(1) = 0:SZ(1) = -40: SR(1) = 12:SC(1) = 5 ' big

2050 SX(2) = -3: SY(2) = 9:SZ(2) = -20: SR(2) = 4:SC(2) = 6 ' small

2100 '

2110 CLS 3

2120 '

2130 DIM RES(2), VXYZ(2), V(2), E(2), V0(2), P(2), N(2)

2140 '

2150 RES(0) = 128 ' x dots

2160 RES(1) = 80 ' y dots

2170 RES(2) = 4 ' dot size

2200 '

2210 VXYZ(0) = 16 ' Screen 幅 / 2

2220 VXYZ(1) = 10 ' Screen 高 / 2

2230 VXYZ(2) = 40 ' Screenから視点までの距離

2240 '

2250 GOSUB *RAY.TRACE

2260 END

4000 '----------------------------------------------------------------------

4010 ' 解像度RESのx,y(-1≦x,y≦1)方向視線で球をトレース

4020 ' RES(0),(1),(2)=x,yのドット数,ドットサイズ

4030 ' 球x,y,z,r,c=中心x,y,z,半径,色 x,y,z座標の正方向=右,上,後ろ

4040 '

4050 ' inp VXYZ,sx,sy,sz,sr,sc

4060 ' tmp x,y,ix,iy,iw,ih,iz,x0,y0,a,c,V0,r,b,d,t0,w,h,w1,h1,N,V0,P,N

4070 '----------------------------------------------------------------------

4080 *RAY.TRACE

4090 IW = RES(0): IH = RES(1): IZ = RES(2)

4100 X0 = (640 - IW*IZ) / 2: Y0 = (400 - IH*IZ) / 2

4110 LINE(X0 - 1, Y0 - 1)-STEP(IW*IZ + 1, IH*IZ + 1),7,B

4120 IW = IW - 1: IH = IH - 1

4130 FOR IY = 0 TO IH

4140 Y = 1 - 2 * IY / IH

4150 FOR IX = 0 TO IW

4160 X = 2 * IX / IW - 1

4170 GOSUB *RAY.VIEW

4180 GOSUB *DISTANCE

4190 IF T >= 0 THEN GOSUB *SHADE: GOSUB *DRAW

4200 NEXT

4210 NEXT

4220 RETURN

5000 '----------------------------------------------------------------------

5010 ' 視線と球の交点の色cl、陰影と陰(0≦b≦1)を求める

5020 '

5030 ' inp V,E,si,t

5040 ' out cl,b

5050 ' tmp a,c,b,w,h,w1,h1,N,V0,P,N,am,si,V,E,t1

5060 '----------------------------------------------------------------------

5070 *SHADE

5080 CL = SC(SI)

5090 IF SI = 0 THEN B = 1: RETURN ' light

5100 AM = 0.1 ' ambient

5110 V0(0) = V(0) - SX(SI)

5120 V0(1) = V(1) - SY(SI)

5130 V0(2) = V(2) - SZ(SI)

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

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

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

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

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

5190 N(0) = P(0) * B

5200 N(1) = P(1) * B

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

5220 V(0) = P(0) + SX(SI)

5230 V(1) = P(1) + SY(SI)

5240 V(2) = P(2) + SZ(SI) ' V = P (元の座標)

5250 E(0) = SX(0) - V(0)

5260 E(1) = SY(0) - V(1)

5270 E(2) = SZ(0) - V(2)

5280 B = SQR(E(0)*E(0) + E(1)*E(1) + E(2)*E(2))

5290 T1 = B - SR(0) ' 光源表面までの距離

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

5310 E(0) = E(0) * B

5320 E(1) = E(1) * B

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

5340 B = 1.0E-8 ' 少し

5350 T1 = T1 - B*2 ' 光源表面までより短く

5360 V(0) = V(0) + E(0) * B

5370 V(1) = V(1) + E(1) * B ' 点Pと重ならないように

5380 V(2) = V(2) + E(2) * B ' Vを少し光源に寄せる

5390 GOSUB *DISTANCE

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

5410 IF 0 < T AND T < T1 THEN B = 0 ' 陰

5420 IF B < AM THEN B = AM ' ambient

5430 RETURN

6000 '----------------------------------------------------------------------

6010 ' 点を描く

6020 '

6030 ' inp cl,b,x0,y0,ix,iy,iz

6040 ' tmp w,h,w1,h1

6050 '----------------------------------------------------------------------

6060 *DRAW

6070 FOR H=0 TO IZ-1

6080 H1 = IY*IZ + Y0 + H

6090 W1 = IX*IZ + X0

6100 FOR W=0 TO IZ-1

6110 IF RND(1)*0.99 < B THEN PSET(W1 + W, H1),CL

6120 NEXT

6130 NEXT

6140 RETURN

7000 '----------------------------------------------------------------------

7010 ' スクリーンVXYZからの視点位置ベクトルVと視線単位ベクトルEの生成

7020 ' VXYZ(0),(1),(2)=スクリーン幅/2,高/2,視点スクリーン間距離

7030 '

7040 ' V(0) = VXYZ(0)*x , V(1) = VXYZ(1)*y , V(2) = 0 (-1≦x,y≦1)

7050 ' E(0) = V(0)/|E| , E(1) = V(1)/|E| , E(2) = -VXYZ(2)/|E|

7060 '

7070 ' inp VXYZ,x,y

7080 ' out V,E

7090 ' tmp a

7100 '----------------------------------------------------------------------

7110 *RAY.VIEW

7120 V(0) = VXYZ(0) * X: V(1) = VXYZ(1) * Y: V(2) = 0

7130 E(0) = V(0) : E(1) = V(1) : E(2) = -VXYZ(2)

7140 A = SQR(E(0)*E(0) + E(1)*E(1) + E(2)*E(2))

7150 E(0) = E(0) / A : E(1) = E(1) / A : E(2) = E(2) / A

7160 RETURN

8000 '----------------------------------------------------------------------

8010 ' 視点位置ベクトルVから、視線単位ベクトルE方向の視線と

8020 ' 球との交点との距離tの内で一番近い前方のtと球番号siを求める

8030 '

8040 ' inp V,E,sx,sy,sz,sr,sc,sn

8050 ' out t,si

8060 ' tmp c,V0,r,b,d,t0

8070 '----------------------------------------------------------------------

8080 *DISTANCE

8090 T = -1: SI = -1

8100 FOR C=0 TO SN-1

8110 V0(0) = V(0) - SX(C):V0(1) = V(1) - SY(C):V0(2) = V(2) - SZ(C)

8120 R = SR(C) ' V0 = V - (sx(c),sy(c),sz(c)) , r = sr(c)

8130 GOSUB *DISTANCE.SPHERE ' t0 ← distance.sphere(V0, r)

8140 IF T0 >= 0 THEN IF T0 < T OR T < 0 THEN T = T0: SI = C

8150 NEXT

8160 RETURN

9000 '----------------------------------------------------------------------

9010 ' 視点位置ベクトルVから、視線単位ベクトルE方向の視線と

9020 ' 原点中心で半径rの球との交点までの距離tを求める

9030 '

9040 ' |P|=r … 球 (V+Et)^2=rr tt + 2(V・E)t + V・V - rr = 0

9050 ' P=V+Et … 視線 t = -(V・E)±sqr{(V・E)^2 - V・V + rr}

9060 '

9070 ' inp V0,E,r V0は球が原点の時のVの値

9080 ' out t0

9090 ' tmp b,d

9100 '----------------------------------------------------------------------

9110 *DISTANCE.SPHERE

9120 B = V0(0)* E(0)+V0(1)* E(1)+V0(2)* E(2) ' b = V・E

9130 D = V0(0)*V0(0)+V0(1)*V0(1)+V0(2)*V0(2)-R*R ' d = V・V - rr

9140 D = B*B - D ' d判別式

9150 IF D < 0 THEN T0 = -1:RETURN ' 交点なし

9160 D = SQR(D)

9170 T0 = -B-D ' 視線と球の近い方の交点距離

9180 IF T0 < 0 THEN T0 = -B+D ' 視線と球の遠い方の交点距離

9190 RETURN


N88-BASIC(86)互換?VL-BASIC for windows10,11など by ULproject

VL-BASIC for windows10,11など by ULproject N88互換BASIC? CPUリアルタイムレイトレーシング(一部フォトンマッピング)? BASICでお絵かき を紹介するサイト。

0コメント

  • 1000 / 1000