投稿

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

HTMLで動くレイトレーシング

イメージ
2021/7/6(火) HTMLで動くレイトレーシング (1回目)~(4回目)   (by ULproject for HTML,JavaScript,canvas)   HTMLでレイトレーシング (8回目) HTMLで行列(matrix) (2回目) HTMLでクォータニオン(quaternion) (1回目) を使ってレイトレーシングを動かしてみました   HTML,JavaScript,canvasは、使い慣れていない ため、不具合などが多々あると思いますが、 ご了承ください   (1回目)~(4回目)のプログラムの説明   上記リンク先のプログラムをほぼそのまま結合 (1回目) mray001.html … 行列による移動 (2回目) mray002.html … クォータニオンによる移動   上記プログラムを OpenGL風インターフェースに改造 (3回目) mray003.html … mray001.htmlを改造 (4回目) mray004.html … mray002.htmlを改造   以下、モデル (球)の配置の説明   function model() {   var md;     Sn = 0;    // Model reset   md = Mode; // Push Mode   Mode = 0;  // Model mode     Specular(1.0);   Shininess(10.0);   Reflect(0.0);   Clarity(0.0);   Refract(1.0);     // 光源   Diffuse(1.0, 1.0, 1.0);   Push();   Translate(-500, 500, 500);   Sphere(2);   Pop();     // 大球   Diffuse(0.0, 1.0, 1.0);   Push();   Translate(3, 8, -80);   Sphere(18);   Pop();     // 小球   Diffuse(1.0, 1.0, 0.0);   Push();   Translate(-6, 14, -60);   Sphere(6);   Pop();     // 透明   Diffuse(0.1, 0.1, 0.1);   

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

イメージ
2021/6/16(水) HTML でレイトレーシング  (8 回 目 )   by ULproject for HTML(JavaScript, canvas) ray008.html 式変形など詳しくは N88-BASICでレイトレーシング (8回目) 透過を追加します 透過は屈折光と反射光に分けて追跡します   物質 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 を、加法定理等で変形すると 反射率 k = [ {( ncosα- cosθ)/( ncosα+ cosθ)} 2   + {(n

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