HTMLでレイトレーシング (3回目)

2021/6/11(金)

HTMLでレイトレーシング (3)


by ULproject for HTML(JavaScript, canvas)


参考記事

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

 

表示用の色指定を追加しました

'#rgb'で,r,g,b=0~f(16階調)または

'#rrggbb'でrr,gg,bb=0~ff(256階調)です

var Sc = [ '#fff'     ,  '#0ff'    ,  '#ff0'    ];// color

 

まずスクリーン上の任意の視点Vからの

視線ベクトルを生成します

 

スクリーンを1回目の図1のx,y,zの

長さで定義します。変数名をVXYZとすると

function trace()内で

var VXYZ = [16, 10, 40]; // Screen幅/2, 高/2, Screen-視点距離

 

32×20で視線が集まる焦点距離が40の

z=0の平面になります。手前がz軸です

 

任意のx,y(-1.0≦x,y≦1.0)でスクリーンの

任意の点Vを表すことにします

 

V = (VXYZ[0] × x , VXYZ[1] × y , 0)

x=1,y=1のとき一番右上です

視線Eは焦点からスクリーン上の視点へ

と向かう方向なので、焦点をV’とすると、

V’= (0 , 0 , VXYZ[2])

E = V - V’= (VXYZ[0] × x, VXYZ[1] × y, -VXYZ[2])

E  = E / |E| (|E|はx,y,z成分の2乗の和の平方根)

(三平方の定理の3次元版です)

 

_V[0]  = VXYZ[0] * x; _V[1]  = VXYZ[1] * y; _V[2]  =  0.0    ;

_E[0]  = _V[0]      ; _E[1]  = _V[1]      ; _E[2]  = -VXYZ[2];

a = Math.sqrt(_E[0]*_E[0] + _E[1]*_E[1] + _E[2]*_E[2]);

_E[0] /= a          ; _E[1] /= a          ; _E[2] /= a       ;

 

上記Math.sqrtの中は2乗の和なので常に正で

a>0 (VXYZ[2]>0より)なので、Math.sqrt(負)

/0のエラーチェックは不必要です

関数名はfunction ray_view(_V, _E, VXYZ, x, y)

にしました

 

更にスクリーンを走査して球の存在を色で描画します

以下のような画面になります

 










まず、解像度の指定です

 

var RES = [80, 50, 4]; //  x dots , y dots, dot size

RES[0]×RES[1]の点の数(解像度)で構成される

スクリーンということにします

RES[2]で1dotの大きさを指定しておきます

解像度を小さくすると画面が小さくなるので

1dot(点)の大きさを指定できるようにしました

 

今回作る関数は

function ray_trace(VXYZ)

{

  var V  = new Array(3);

  var E  = new Array(3);

  var _t = new Array(1);

  var iw, ih, ix, iy, iz, si;

  var x0, y0;

 

  iw = RES[0]; ih = RES[1]; iz = RES[2];

  x0 = (640 - iw*iz) / 2; y0 = (400 - ih*iz) / 2;

  lineb(x0 - 1, y0 - 1, iw*iz + 2, ih*iz + 2, '#fff');

  iw--; ih--;

  for (iy = 0; iy <= ih; iy++)

  {

    y = 1 - 2 * iy / ih;

    for (ix = 0; ix <= iw; ix++)

    {

      x = 2 * ix / iw - 1;

      ray_view(V, E, VXYZ, x, y);

      si = distance(_t, V, E);

      if (_t[0] >= 0) linebf(x0+ix*iz, y0+iy*iz, iz, iz, Sc[si]);

    }

  }

}

 

RESの値を一時的にiw,ih,izに代入して

使用しています。

大きさiz×izの正方形の点がiw×ih個

で構成されたスクリーンになります

(wはwidth幅、hはheight高さです)

 

x0、y0はPCの画面を640×400として

スクリーンが中央に表示するための

左上のPC画面座標です。

lineb白色の長方形を描くことでスクリーンが

分かるようにしてあります

 

以下、RES[0],RES[1]=3,2として

説明すると

iw=2  (RES[0]-1)

ih=1  (RES[1]-1)

ix=0~iw

iy=0~ih

つまり

(ix,iy)=(0,0),(1,0),(2,0),

        (0,1),(1,1),(2,1)

と変化させてスクリーン上のすべて

の点を描いていきます

x = 2 * ix / iw

y = 1 - 2 * iy / ih

で、-1.0≦x,y≦1.0の値を得ます

(x,y)=(-1, 1),( 0, 1),( 1, 1),

      (-1,-1),(-1, 0),(-1, 1)

となります

 

上記で作った*RAY.VIEWでV, Eを作り

以前作った*DISTANCEでtを得ます

tが0以上なら見えている球の色

で点を描きます

 

PC画面座標(10, 5)に大きさ(8, 4)

緑色の塗潰した箱を

linebf(10,5,8,4,'#0f0')

で描いています

 

ray003.htmlはMicrosoft Edgeに重ねると

動き、メモ帳でコードを見ることが出来ます

 

blg~.zip(ray003.html)は

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

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

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


VL-BASICホームページのHTML項目内で

htmlの動作を見ることが出来ます

https://vlbasic.amebaownd.com/pages/3605089/page_202002222051


次回

HTMLでレイトレーシング (4回目)


このブログの人気の投稿

NEWS

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