投稿

ラベル(JavaScript)が付いた投稿を表示しています

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

イメージ
2021/6/15(火) HTML でレイトレーシング  (7 回 目 )   by ULproject for HTML(JavaScript, canvas)   参考記事 N88-BASICでレイトレーシング (7回目) 反射は、 前回の specularの式 S = E - 2(E・N)N = E + (2cosθ)N が、そのまま使えます 視点 V、視線Eの交点Pでの反射Sを前回で求め ていますので、それらが保存されるように変更を 加えました   P、Sを新たなV、Eとしてその先の交点の色を追加 するということを繰り返せば反射で映ったものを 描けます   Level変数を追加し、反射回数を制限しています また、 slcに反射による減衰量を保存し、一定数以下なら 反射を制限するようにしています   表示する球を 4個(後ろにある光源を入れると5個) に増やすなど、ところどころ変更が加えてあります   今までの shade関数をshade_siに変更し shade関数からshade_siを呼び出しています shade関数では、新たに   sl1 = Sl[si]; if (sl1 > 0.0) {   vector_specular(S, E, N);   b = 0.1;//1.0e-8; // 少し手前   V0[0] = P[0] + S[0] * b;   V0[1] = P[1] + S[1] * b;   V0[2] = P[2] + S[2] * b;   slc *= sl1;   shade(CL0, V0, S, slc, li);   if (CL0[3] >= 0.0)   {     _CL[0] += CL0[0]; _CL[1] += CL0[1]; _CL[2] += CL0[2];   } }   を追加し、鏡面反射する表面 (Sl[si] > 0)は 表面を視点、反射ベクトル Sを視線として 再帰的に追跡をし、色を足していっています   ray007.htmlはMicrosoft Edgeに重ねると 動き、メモ帳でコードを見ることが出来ます   blg~.zip(ray007.html)は 以下のリンクからダウンロードできます VL-BASIC(N88-BASIC互換?)ホームページ Readme.

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

イメージ
2021/6/14(月) HTML でレイトレーシング  (6 回 目 )   by ULproject for HTML(JavaScript, canvas)   参考記事 N88-BASICでレイトレーシング (6回目) 次に specular(鏡面)反射ですが、鏡のように はっきりとモノが映るのではなく、光源の色 が反射して見える程度でハイライトとも言われ ていたと思います shininess(輝かしさ)はハイライト部分を、 鋭く (小さく明るく)するか鈍く(広く暗く) するかの程度を表します   ハイライトの色は光源の色が大きく関係して 来るのですが、このシリーズではプログラムが 複雑になりすぎないよう光源から出る光の色 を白に限定していますので、ハイライト も白になります   まず、反射ベクトルを求めます。 図 4 反射ベクトルS 図の Eの反射がSです。 -Eと球の法線ベクトルNの内積 -E・N つまり -(E・N)は、Eの 始点から Nに下した垂線の交点 と Nの始点までの距離になり、 -2(E・N)は、Nの始点から、 Eと始点を同じにしたSの終点 までの長さになり、 Nをその長さ にしたのが、 -2(E・N)Nです。 Eに-2(E・N)Nを足せばSに なります。   S = E - 2(E・N)N   で反射ベクトル Sを求められます。   specularはSが光源方向Lと同じ 方向の時最も明るく、方向がずれる ほど暗くなりますので、内積で表す 事ができます。 値を 0~1にするためS,Lを 単位ベクトルとして、   sp = S・L   shininessをshで表すと、 ハイライトは h   h = sp ** sh   です JavaScriptではaのb乗をa ** bと書きます   vector_specular(S, E, N); で視線の反射ベクトル Sを求めます 中身はほぼ数式通りです   a = E0[0]*S[0] + E0[1]*S[1] + E0[2]*S[2]; // a = L・S specular if (a < 0) a = 0; a = a ** Sh[si]; // shininess a = a *  Ss[si]; で aにspecularが入ります aはRGBに分けていませんので

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

イメージ
2021/6/13(日) HTML でレイトレーシング  (5 回 目 )   by ULproject for HTML(JavaScript, canvas) 参考記事 N88-BASICでレイトレーシング (5回目) 今回は、次の画面のように陰を描きます。 図 3 点Pが陰になる場合   陰は視線と見えている球との交点 Pから光源表面 までの間に、光源と自身を除く球があれば点 Pに 光が当たっていないので暗くすれば陰になります   自身の球が検索されないように点 Pを少し光源に 近づけて点 Pを球表面から浮かす必要があります   検索時に自身を除くという方法は、球やポリゴン のみのに使用できますが、トーラス (ドーナツ型) などの自身の陰がうつる形に対応できません   今回は球のみですのでどちらでもかまいませんが、 検索部分 (distance)を変更しなくてよい、点Pを 浮かす方法にしました   また光源自身が含まれないように光源表面までの 距離も少し短めで判定します   今回、陰がうまく出る位置に球を移動しました   また、解像度を多くして画面を大きくしました   shade関数を変更していきます   V0[0] = P[0]  + SP[si][0]; V0[1] = P[1]  + SP[si][1]; V0[2] = P[2]  + SP[si][2]; // V0 = P (元の座標) E0[0] = SP[0][0] - V0[0]; E0[1] = SP[0][1] - V0[1]; E0[2] = SP[0][2] - V0[2];   球表面の点 PをV0、点Pから光源方向をE0にして distanceを呼ぶ準備をします。   b = Math.sqrt(E0[0]*E0[0] + E0[1]*E0[1] + E0[2]*E0[2]); t1 = b - Sr[0]; // 光源表面までの距離   光源中心までの距離から光源の半径を引いて表面 までの距離を t1とします。   if (b != 0) b = 1/b; else b = 0; E0[0] *= b; E0[1] *= b; E0[2] *= b; // E0 = L(光源方向)   E0=E0/|E0|でE0を単位ベクトルにします。   b

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

イメージ
2021/6/12(土) HTML でレイトレーシング  (4 回 目 )   by ULproject for HTML(JavaScript, canvas)   参考記事 N88-BASICでレイトレーシング (4回目)   今回は陰影 (濃淡)を付けます   濃淡は表面の色を表す diffuse(拡散反射係数) を使用します RGB各0~1で指定し、0~1の実数で濃淡を表現 します RGB各256階調で表現するための変換をしています   前回の x0,y0,ix,iy,izの値を使用して 色 c、濃淡b、大きさiz×izの点を (ix × iz + x0 , iy × iz + y0) の PC画面座標に描く関数     function draws(CL, x0, y0, ix, iy, iz) {   var c, i;     if (CL[3] < 0.0) return;   c  = '#';   i = Math.floor(CL[0]*255);   if (i > 255) i = 255; else if (i < 0) i = 0;   c += ('00' + i.toString(16)).substr(-2); // R   i = Math.floor(CL[1]*255);   if (i > 255) i = 255; else if (i < 0) i = 0;   c += ('00' + i.toString(16)).substr(-2); // G   i = Math.floor(CL[2]*255);   if (i > 255) i = 255; else if (i < 0) i = 0;   c += ('00' + i.toString(16)).substr(-2); // B   linebf(ix*iz + x0, iy*iz + y0, iz, iz, c); }   Math.floorは小数点以下切捨て i.toString(16)は16進数の文字列に変換し ('00' + i.toString(16)).substr(-2) で、右から 2文字を取り出してい

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