HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
1006
youdaiHGIMG4でベクトル(fv)の反射と屈折の関数や命令を実装したい6解決


youdai

リンク

2021/10/6(Wed) 13:41:55|NO.94058

●HGIMG4でベクトル(fv)の反射と屈折の関数や命令を実装したい
HGIMG4には3Dプログラミング言語によくビルトイン関数として実装されている、3次元(x,y,z)のベクトルの反射と屈折の関数や命令がありません。
数学系の情報を参照したのですが、それをどうやってHSP3のスクリプトで実装すればよいか分かりませんでした。
数学に詳しい方がいましたら、HSP3のスクリプトにして教えて下さい。よろしくお願い致します。



この記事に返信する


usagi

リンク

2021/10/7(Thu) 16:15:16|NO.94067

こんにちは、
fv値の実態は配列になりますので、以下のコメントアウトと同じ意味になります。


fvset fv, 1,2,3 ;fv.0 = 1.0 ; X ;fv.1 = 2.0 ; Y ;fv.2 = 3.0 ; Z

>数学系の情報を参照したのですが、それをどうやってHSP3のスクリプトで実装

たとえば、その参照された情報が C = A + B という情報でしたら
A[1,2,3], B[4,5,6]とすると以下の様に計算できます。


fvset C, 1,2,3 fvadd C, 4,5,6 ;もしくは A = 1.0, 2.0, 3.0 B = 4.0, 5.0, 6.0 C.0 = A.0 + B.0 C.1 = A.1 + B.1 C.2 = A.2 + B.2

です。fv***系の命令はadd, sub, mul, div と四則演算用意されてますので、
参照された数学系のサイトの式と置き換えると良いと思います。


>3Dプログラミング言語によくビルトイン関数として実装されている

もう少し、具体例が分かればサンプル出せるかもしれません。

例)openglのreflection関数みたいに、
入力ベクトルと、反射面の法線ベクトルから
出力ベクトルを求める様な仕様の命令が欲しい。
など。。。



youdai

リンク

2021/10/7(Thu) 16:50:23|NO.94068

返信ありがとうございます。
関数の具体例は以下のものになります。

GLSLのreflect関数(反射)


; openGL ES2.0リファレンスより抜粋 genType reflect( genType I, genType N ) 生成ベクトルIが法線Nを持つサーフェスで反射したもの。 reflect(I, N) == I - 2 * dot(N, I) * N

GLSLのrefract関数(屈折)


; openGL ES2.0リファレンスより抜粋 genType refract( genType I, genType N, float eta ) 生成ベクトルIが屈折率etaで法線Nを持つサーフェスに対して起こす屈折のベクトル。 屈折ベクトルは次のようにして計算する。 k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)) if (k < 0.0) return genType(0.0) else return eta * I - (eta * dot(N, I) + sqrt(k)) * N

これをどのようにしてHGIMG4に移植したものか上手くスクリプト化できなくて悩んでいます。



usagi

リンク

2021/10/7(Thu) 18:43:05|NO.94069

取り急ぎ、反射はこんな感じでいかがでしょうか。

#include "hgimg4.as" #module ;reflect(I, N) ※Rに結果を代入 #deffunc reflect array R, array I, array N ;I - 2 * dot(N, I) * N ; dot(N, I) この部分 dot.0 = N.0 : dot.1 = N.1 : dot.2 = N.2 fvinner dot, I.0, I.1, I.2 ; 2 * dot この部分 dot.0 *= 2 ; ... * N の部分 h.0 = N.0 : h.1 = N.1 : h.2 = N.2 fvmul h, dot.0, dot.0, dot.0 ; I - ... の部分 fvset R, I.0, I.1, I.2 fvsub R, h.0, h.1, h.2 return #global mes "テスト" fvset i, 1,-1,0 ; 入力ベクトル i fvset n, 0, 1,0 ; 反射面の法線ベクトル n reflect r, i, n ; 今回つくった、反射命令 rに反射ベクトルを返す mes strf("x: %f, y:%f ,z:%f", i.0, i.1, i.2) mes strf("x: %f, y:%f ,z:%f", n.0, n.1, n.2) mes strf("x: %f, y:%f ,z:%f", r.0, r.1, r.2) redraw 0



usagi

リンク

2021/10/7(Thu) 19:13:35|NO.94070

HSPには構造体やクラス、演算子のオーバーロードが無いので、
C++に近い様な記述の言語の式を移植する場合は、
この様に式を展開して一つづつ配列操作する必要があります。



usagi

リンク

2021/10/7(Thu) 22:14:38|NO.94072

屈折も用意しました。
※屈折の方は、コメント少ないですが、反射の方を移植参考にしてください。
 スカラーなのかベクトルなのか意識すると、計算の置き換えが理解できるかと思います。


#include "hgimg4.as" #module ; 反射 ; reflect(I, N) ※Rに結果を代入 #deffunc reflect array R, array I, array N ;I - 2 * dot(N, I) * N ; dot(N, I) この部分 dot.0 = N.0 : dot.1 = N.1 : dot.2 = N.2 fvinner dot, I.0, I.1, I.2 ; 2 * dot この部分 dot.0 *= 2 ; ... * N の部分 h.0 = N.0 : h.1 = N.1 : h.2 = N.2 fvmul h, dot.0, dot.0, dot.0 ; I - ... の部分 fvset R, I.0, I.1, I.2 fvsub R, h.0, h.1, h.2 return ; 屈折 ; 命令名の重複ができないので、reflect2とする ※Rに結果を代入 #deffunc reflect2 array R, array I, array N, double eta dot.0 = N.0 : dot.1 = N.1 : dot.2 = N.2 fvinner dot, I.0, I.1, I.2 k = 1.0 - eta * eta * (1.0 - dot.0 * dot.0) if k < 0.0 { ; R = genType(0.0) fvset R, 0, 0, 0 } else { ; R = eta * I - (eta * dot(N, I) + sqrt(k)) * N _s = eta * dot.0 + sqrt(k) fvset _v, _s, _s, _s fvmul _v, N.0, N.1, N.2 fvset R, eta, eta, eta fvmul R, I.0, I.1, I.2 fvsub R, _v.0, _v.1, _v.2 } return #global mes "反射" fvset i, 1,-1,0 ; 入力ベクトル i fvset n, 0, 1,0 ; 反射面の法線ベクトル n reflect r, i, n ; 今回つくった、反射命令 rに反射ベクトルを返す mes strf("x: %f, y:%f ,z:%f", i.0, i.1, i.2) mes strf("x: %f, y:%f ,z:%f", n.0, n.1, n.2) mes strf("x: %f, y:%f ,z:%f", r.0, r.1, r.2) mes "屈折" fvunit i ; 屈折は入力ベクトルのノーマライズが必要 reflect2 r, i, n, 0.5 mes strf("x: %f, y:%f ,z:%f", i.0, i.1, i.2) mes strf("x: %f, y:%f ,z:%f", n.0, n.1, n.2) mes strf("x: %f, y:%f ,z:%f", r.0, r.1, r.2) redraw 0



youdai

リンク

2021/10/8(Fri) 21:24:06|NO.94084

スクリプト内のコメントも含めて、関数のスクリプト化の理解に大変参考になりました。
大変勉強になりました。
ありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.