HTMLでレイトレーシング (3回目)
2021/6/11(金)
HTMLでレイトレーシング (3回目)
by ULproject for HTML(JavaScript, canvas)
参考記事
表示用の色指定を追加しました
'#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)は
以下のリンクからダウンロードできます
Readme.txtを読んで遊んで下さい
VL-BASICホームページのHTML項目内で
htmlの動作を見ることが出来ます
https://vlbasic.amebaownd.com/pages/3605089/page_202002222051
次回