投稿

ラベル(レイトレーシング)が付いた投稿を表示しています

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

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

2021/6/10(木) HTML でレイトレーシング (2 回 目 )   by ULproject for HTML(JavaScript, canvas)   参考記事 N88-BASICでレイトレーシング (2回目)   複数の球から 1番近い交点までの距離を求る関数 function distance(_t, V, E) を作ります 値が返る変数 (要素数1の配列変数)は_0を付けて 分かり易いようにしています   Snが球の数で配列要素0~2の3個の球を定義します   var Sn = 3 // 球の個数 //        光源           大球         小球 var SP = [[-12, 8, -5], [5, 0, -40], [0, 5, -20]];// center var Sr = [ 2          ,  12        ,  4         ];// radius     SP[0][0],SP[0][1],SP[0][2]は0番の球の中心座標です 座標の向きは、 1回目の図1を見て下さい Sr[0]は0番の球の半径です   c番の球までの距離t0を求めるには 視点 Vから球の中心座標(SP[c][0],SP[c][1],SP[c][2])を 引き、球を原点に移動させた視点を V0として 交点までの距離を求めます   V0[0] = V[0] - SP[c][0]; V0[1] = V[1] - SP[c][1]; V0[2] = V[2] - SP[c][2]; t0    = distance_sphere(V0, E, Sr[c]);   で t0に距離が入ります ;(セミコロン)は終止符の様なもので 必ず必要です   球 c=0,1,2のt0で一番近いもの を tにすれば良いので、   t = -1.0; si = -1; for (c = 0; c < Sn; c++) {   V0[0] = V[0] - SP[c][0];   V0[1] = V[1] - SP[c][1];   V0[2] = V[2] - SP[c][2];   t0    = distance_sphere(V0, E, Sr[c]);   if (t0 >= 0)   {     if (t0 <

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

イメージ
2021/6/9(水) HTMLでレイトレーシング (1回目) by ULproject for HTML(JavaScript, canvas) レイトレーシングで球を表示するという 簡単なプログラムをHTML(Java script, canvas)で作ります このシリーズは、式などに関する説明を省略して いますので 詳しくは N88-BASICでレイトレーシング (1回目) を見てください 図1 視線方向の単位ベクトルE(上記矢印)     とその出発点V(視点位置ベクトル) 視線と球の1番近い交点の色をスクリーン上に 描いて行きます ここから、数値(スカラー)を小文字、ベクトル (x,y,z成分を持つ矢印)を大文字で書きます 原点が中心で半径rの球は、 |P| = r (|P - C| = rは視線を移動すれば良いので不必要です) 視点VからE方向に向けた視線は、 P = V + Etです |P| = r にP = V + Etを代入して、 |V + Et| = rの両辺を2乗して||を外し、 整理すると(E・E = |E|2 = 12 = 1より) t2 +  2(V・E)t + (V・V - r2) = 0で tの2次方程式になり、解の公式で 視点から球との交点までの距離 t = -V・E±√{ (V・E)2 - V・V + r2 }です 判別式D = (V・E)2 - V・V + r2 で3パターン判別 D < 0 → 交差しない  (tは虚数) D = 0 → 1点で接する(tは1個) D > 0 → 2点で貫く  (tは遠近2個) これをJava scriptで書いていきます ベクトルの成分は、 P=(x, y, z)、V=(Vx ,Vy ,Vz)、V=(V0, V1, V2) などと表しますが、配列を使うことにします var V = [x, y, z] または var V = new Array(3) で、定義します (x, y, zは座標を表す数値、Array(3)の3は 配列の要素数なのでx,y,zの3要素を指定します) 定義するとV[0],V[1],V[2]という変数が使え それぞれx,y,z成分とします VとEの内積は同じxyz成分同士の積の和なので b = V・Eは、 b = V[0]*E[0] + V[1]*E[1] +

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

イメージ
2021/6/8(火) N88-B ASICでレイトレーシング  (8回目)   (by ULproject for N88-BASIC, NL-BASIC) (NL-BASICはAlt+6で高速化します)     透過を追加します 透過は屈折光と反射光に分けて追跡します   物質 1から2へ光が進む時、 物質 1,2の絶対 屈折率を n 1 、 n 2 、相対屈折率を n = n 12  = n 2 /n 1 とし、入射光 E,屈折面の法線N、反射光S、 屈折光 Rとする |E|=|N|=|R|=1 図 5 屈折光R = (1/n)(E - d N)   光が当たった部分の長さを 1にして 幅のある光が屈折する様子を書いた のが図 5です   物質 1 : 物質2 = sinθ : sinα は、 単位時間当たりの光が進む距離の比 つまり、進みやすさの比です。 屈折率 n 1 , n 2 は光の進みにくさなので 進みやすさの比は、 sinθ : sinα = n 2  : n 1  = n : 1 sinθ = nsinα   よって、図 5の角αを持つ2つの 直角三角形は大が小の n倍になって いる   R’= E - d Nと置くと、 R  = (1/n)R’    = (1/n)(E - d N)   となり、 dを求める、   d = ncosα - cosθ ncosα = n√(1-sin 2 α) = √{n 2 -(nsinα) 2 } = √(n 2 -sin 2 θ) = √{n 2 -(1-cos 2 θ)} d = √{n 2 -(1-cos 2 θ)} - cosθ   屈折光 Rと前回やった反射光Sは R = (1/n)[E-[√{n 2 -(1-cos 2 θ)}-cosθ]N] ただし、 cosθ= -E・N S = E+(2cosθ)N = E - 2(E・N)N   次に、入射光が屈折光 (1-k)と反射光kに 分かれる割合 反射率 k = [ {sin(θ-α)/sin(θ+α)} 2   + {tan(θ-α)/tan(θ+α)} 2  ] / 2 を、加法定理等で変形します   sin(θ-α)/sin(θ+α) = (sinθcosα-cosθsinα) / (sinθcosα+cosθsinα) = (nsinαcos