Render3D.zip
3Dレンダリングvbサンプルソース


サンプルイメージ


無限の有限証明(無限対数軸)

lim↓x→∞ x
MAX_N=任意
n=MAX_N
c=MAX_N/x
lim↓x→∞ c=0
c=無限のとき
 a=0.0
それ以外
 a = MAX_N * Math.Pow(1.0 / n, c)
 lim↓c→0 a=MAX_N
d = x = MAX_N / (Math.Log(a / MAX_N) / Math.Log(1.0 / n))
b = Math.Cos((Math.PI * d) * (2.0 / MAX_N))

0<x<∞
0<a<MAX_N

無限を有限で表現できた
証明終了

ゼノンのパラドックスの完全解答


無限遠透視射影
無限対数軸を用いた透視射影の自作3Dエンジンライブラリ
無限対数軸とは0~MAX_Nの範囲に0~∞をぶち込むものです
だから視垂台ではなく無限遠までの視円錐の透視射影

無限対数軸(x)を次のように設定する
x:実数
Range:対数軸の範囲
Base:基数
c = Range / Abs(x)
cが非数または∞ならば
 無限対数軸 = 0.0
それ以外で
 無限対数軸 = Range * (1.0 / Base)^c
 無限対数軸が非数または∞ならば
  無限対数軸 = 0.0
xが負ならば
 無限対数軸 *= -1.0

ここで、Range = 1.0, Base = 8.0とし、
同次座標ベクトルV(w,x,y,z)を次のように変換する
V'.w = 1.0
V'.x = (1.0 - 無限対数軸(V.z)) * V.x
V'.y = (1.0 - 無限対数軸(V.z)) * V.y
V'.z = 0.0

これで、無限遠透視射影の視点上の座標V'x, V'.yが得られた
Baseの値を大きくすると、射影の歪みが少なくなる

注意:Range=1.0で無限遠透視射影をすると(つまり、0.0~1.0の範囲)、浮動小数点丸めで精度が落ちるので、
Rangeを目的空間のスケールに合わせて設定し、以下のように修正しました

V'.w = 1.0
V'.x = (Range - 無限対数軸(V.z)) * V.x / Range / Range
V'.y = (Range - 無限対数軸(V.z)) * V.y / Range / Range
V'.z = 0.0

(Range - 無限対数軸(V.z)) と V.x が0.0~Rangeの範囲のスケールなので、
Range^2で割って、0.0~1.0スケールに合わせています
こうすることにより、浮動小数点丸めの問題を軽減しました
また、この逆変換は、

V.w = 1.0
V.x = Range * V'.x / (Range - 無限対数軸(V'.z)) * Range
V.y = Range * V'.y / (Range - 無限対数軸(V'.z)) * Range
V.z = (V'.z / Range) * Range

となります


描画

透視射影以外は、基本的に一般の3Dエンジンと同じ

カメラはカメラ行列群をかけて逆行列とし、
それにかけるローカルはローカル行列群をかける
これが、視点変換行列で、これで変換されるものが反変ベクトル
法線ベクトルの変換は視点変換行列の逆行列の転置で、これで変換されるものが共変ベクトル

描画するポリゴン三角形の最遠点Vを取得して、Vと共変ベクトルの内積が負ならば、
ポリゴンを無限遠透視射影の視点上の座標V'に描画する

陰面消去は画素ごとにZバッファを記録して、近い物体で上書きする


陰面消去


照明





更新履歴
2014/02/12 : ディープコピーとシャローコピーのClone()のバグ修正。これはまだ、潜在的に残ってるかも。
2014/02/15 : 照明修正。スフィア実装。ポリゴンの法線を逆向きに実装した気もしないでもないけど、対処療法でできたから気が向いたら直す。
2014/02/16 : MouseCamera実装。
2014/02/17 : Vectorの同次座標の扱いを変更。Render3D.LookAt()実装。
2014/02/18 : Label実装。
2014/02/20 : Line実装。
2014/02/23 : 浮動小数点丸めに対する修正。
2014/02/26 : 全般修正。
2014/02/26 : ピクセル描画修正。
2014/03/26 : 照明高速化修正。通常透視射影実装。


テクスチャマッピングはテクスチャUVの回転が上手くいかないで頓挫





おまけ

n次球の方程式:Sn^2=r^2
この式は各座標における最短距離でもあります

円の方程式:x^2+y^2=r^2
球の方程式:x^2+y^2+z^2=r^2
四次元球の方程式:w^2+x^2+y^2+z^2=r^2

球を平面に射影すると
x^2+y^2=r^2-z^2
となり、同心円となります
また球面上の直線は平面では曲線となります
ですから、平面で複雑な曲線も球面では簡単な次数として表されます

同様に、四次元球を立体に射影すると
x^2+y^2+z^2=r^2-w^2
となり、同心球となり、同様の話になります

これで何が出来るかというと、例えば、平面上でのsinカーブは、球面上の直線だということです

球の方程式:x^2+y^2+z^2=r^2
球面上の直線:z=0
xy平面に射影すると
x^2+y^2=r^2
極座標は
x=rcost
y=rsint

cost=x/r
sint=y/r

だから、sinもcosもπも球面を解いただけです

四次元球の方程式:w^2+x^2+y^2+z^2=r^2
四次元球面上の直線:w=1
xyz立体に射影すると
x^2+y^2+z^2=r^2-1
極座標は
x=√(r^2-1)sintcosu
y=√(r^2-1)sintsinu
z=√(r^2-1)cost

Render3DSphere.zip
球面線形補間vbサンプルソース


サンプルイメージ
Quarternion::Slerp2()は失敗して、削除


Sphere4D.zip
カメラスプライン補間vbサンプルソース





Test.zip
XNAvbサンプルソース


サンプルイメージ

XNAで高速化にトライするも、点描画が重いわけではなく、レンダリングアルゴリズムが重いことが判明
レンダリングアルゴリズムをもうちょっと考えるか
むぅ、多分、PowとLogが重すぎるなり
結局、照明を高速化した

そういえば、XNA使ってるのはVisualStudioForWindowsPhone用のプロジェクトです





VBスケルトンコード
以上、乱数やら3Dエンジンやらのスケルトンコードをまとめておいた





戻る