• 検索結果がありません。

Kageyama (Kobe Univ.) / 41

N/A
N/A
Protected

Academic year: 2021

シェア "Kageyama (Kobe Univ.) / 41"

Copied!
42
0
0

読み込み中.... (全文を見る)

全文

(1)

射影変換とモデルビュー変換

2015

年度 情報可視化論

陰山 聡

(2)
(3)

クリップ座標

これまではクリップ座標の立方体の中だけで描画していた。つまり

ビューボリュームは正規化ビューボリューム

[

−1, +1] × [−1, +1] × [−1, +1]

で固定であった。これは不便。

長さの単位(大きさ)を気にしないで、つまりワールド座標で物体を自

由に定義したい。

(4)

射影変換

正射影

(5)

正射影

カメラは

z =

に位置し、

−z

方向を向いている。

正規化ビューボリュームの座標系は左手系。

z

x

y

right

bottom

top

(6)

正射影

z x y (1,1,-1) (1,0,-1)

(left, top, near) (right, bottom, near)

z' x'

y'

直方体から立方体(正規化ビューボリューム)への単純なスケール

変換行列。

(7)

透視射影

カメラは原点に位置し、

−z

方向を向いている。

物体を回転・移動させればいつでも

−z

方向に見えるようにできる。

near

height

z

x

y

(8)

透視射影

z x y (1,1,-1) (1,0,-1) near far width height z' x' y'

視錐台形から立方体への変換。

(9)

透視射影

z y y = - β-1z z' y' +1 +1 - 1 - 1

x

y

z

 =

−β x/z

−β y/z

c

1

z + c

2

(10)

(復習)

平行移動変換

x

y

z

 =

x + t

y + t

xy

z + t

z

は同次座標を使うと行列演算で書けた。

x

y

z

w

 =

1

0

0

t

x

0

1

0

t

y

0

0

1

t

z

0

0

0

1

x

y

z

1

(11)

では、透視射影

x

y

z

 =

−β x/z

−β y/z

c

1

z + c

2

も工夫すれば行列で書けるか?

x

y

z

w

 =

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

x

y

z

1

・できない。

(12)

では、透視射影

x

y

z

 =

−β x/z

−β y/z

c

1

z + c

2

も工夫すれば行列で書けるか?

x

y

z

w

 =

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

x

y

z

1

・できない。

(13)

z

補間の問題

透視射影の場合、もう一つ注意しなければいけない問題がある。

復習:フラグメントシェーダに渡される時の

varying

値の自動線形

補間

フラグメント プリミティブ

(14)

z

補間の問題

varyingValue_2

varyingValue_3 varyingValue_1

(15)

z

補間の問題

ピクセル(赤)が等間隔に並んでいても

プリミティブ(緑)上の補間点(青)の

z

値は非等間隔。

これは都合が悪い。

z y

(16)

等間隔ピクセル

p

は等間隔の

1/z

に対応

z y 直線 ay+bz=c1 直線 z = c2 座標 (p, c2) 座標 (y, z) (ap/c2 +b)z=c1

1

=

a

p +

b

(17)

そこで

z

の代わりに

z

⇒ z

=

−α − γ/z

という座標変換して

z

をフラグメントシェーダ(プリミティブ合成ス

テージ)に渡せば、

z

方向にも自然に等間隔の線形補間になる。

(負の

z

に対して、

γ > 0

なら

z

z

の単調増加関数である。)

−1 ≤ z

≤ +1

となるように

α

γ

を調整する。

そういえば・

・透視射影の

x, y

成分も

z

の除算が入っていた:

(

x

)

=

(

−β x/z

−β y/z

)

(18)

そこで

ある点

(x, y, z)

t

に対して、

x

y

z

 =

−β x/z

−β y/z

−α − γ/z

をプリミティブ組み立てステージに渡せばよい。(

3

成分全てに

z

の除算

が入っていることに注意。)これを

OpenGL

では、次の

2

段階に分けて実

行する。

(19)

透視射影変換の二つのステップ

(1)

同次座標の行列演算。(この行列は一意には決まらない。ここで挙げ

るのは一つの例である。)

x

y

z

w

 =

β

0

0

0

0

β

0

0

0

0

α

γ

0

0

−1 0

x

y

z

1

(2) w

座標での割り算。これを

透視除算

という。プリミティブ組み立て時

に実行される。

x

y

 =

x

/w

y

/w

(20)

パイプラインでの座標の処理

Web アプリ HTML + CSS + JavaScript + シェーダソースコード + オブジェクトデータ WebGL JavaScript API 頂点シェーダ プリミティブ組み立て ラスタ化 フラグメントシェーダ (x', y', z') (x, y, z, w)

(x

, y

, z

) = (x/w, y/w, z/w)

(21)

透視射影行列の設定

near far width height z x y

β

0

0

0

0

β

0

0

0

0

α

γ

(22)

透視射影行列の設定

near far width height z x y

mat4.perspective(fovy, aspect, near, far, projectionMatrix);

fovy

field of view

)は視野の高さ(

y

)方向の角度。

aspect

は縦横比。

上下と左右に非対象な

frustum

(視錐台)を作る場合は、

(23)
(24)

座標変換の実際

モデルビュー変換

射影変換

について、あるオブジェクトに少しずつ座標変換をかけながらその効果

を見る。

(25)

サンプル

3D

物体

らせん状の物体を考える

(26)

webgl sample spiral 00.html

オブジェクトの構成部分

v a r dz = 0 . 1 ; v a r p i t c h = 1 . 0 ; v a r p o f = 0 ; // p o s i t i o n O f f s e t I n F l o a t s v a r c o f = 1 2 ; // c o l o r O f f s e t I n B y t e s f o r ( v a r k =0; k<Nz ; k++) { v a r z = k∗ dz ; p o s i t i o n V i e w [ p o f ] = 0 . 0 ; // x p o s i t i o n V i e w [1+ p o f ] = 0 . 0 ; // y p o s i t i o n V i e w [2+ p o f ] = z ; // z c o l o r V i e w [ c o f ] = 2 5 5 ; // R c o l o r V i e w [1+ c o f ] = 2 5 5 ; // G c o l o r V i e w [2+ c o f ] = 2 5 5 ; // B c o l o r V i e w [3+ c o f ] = 2 5 5 ; // A p o f +=v e r t e x S i z e I n F l o a t s ;

(27)

c o f +=v e r t e x S i z e I n B y t e s ; p h a s e = p i t c h∗ z ;

p o s i t i o n V i e w [ p o f ] = Math . c o s ( p h a s e ) ; // x p o s i t i o n V i e w [1+ p o f ] = Math . s i n ( p h a s e ) ; // y p o s i t i o n V i e w [2+ p o f ] = z ; // z c o l o r V i e w [ c o f ] = 255∗Math . cos ( phase ) ; // R c o l o r V i e w [1+ c o f ] = 255∗Math . s i n ( phase ) ; // G c o l o r V i e w [2+ c o f ] = 255∗Math . s i n ( phase ∗ 0 . 2 ) ; // B c o l o r V i e w [3+ c o f ] = 2 5 5 ; // A p o f +=v e r t e x S i z e I n F l o a t s ; c o f +=v e r t e x S i z e I n B y t e s ; }

(28)

結果

何も変換していないので、見にくい。正規化ビューボリュームから外れ

ている部分が見えない。

(29)

演習

webgl sample spiral 00.html

dz

156

行目)を変えてその効果をみ

(30)

モデル変換

webgl sample spiral 01.html

モデルを移動・縮小・回転する行列

modelViewMatrix

をつくり、頂点

シェーダに送る。これも頂点属性(

attribute

)。

mat4 . i d e n t i t y ( m o d e l V i e w M a t r i x ) ; mat4 . t r a n s l a t e ( m o d e l V i e w M a t r i x , [ 0 . 8 ,− 0 . 5 , −0.8]) ; mat4 . s c a l e ( m o d e l V i e w M a t r i x , [ 0 . 3 , 0 . 3 , 0 . 3 ] ) ; mat4 . r o t a t e X ( m o d e l V i e w M a t r i x ,−Math . PI /3) ; mat4 . r o t a t e Y ( m o d e l V i e w M a t r i x ,−Math . PI /3) ; g l . u n i f o r m M a t r i x 4 f v ( u n i L o c a t i o n , f a l s e , m o d e l V i e w M a t r i x ) ; //−−</new>−−

(31)

頂点シェーダ

modelViewMatrix

も頂点の

attribute

復習:全ての頂点に共通した

attribute

値は

uniform

<! −− new −−> < s c r i p t i d=” s h a d e r−vs ” type=”x−s h a d e r /x−v e r t e x ”> a t t r i b u t e v e c 3 a V e r t e x P o s i t i o n ; a t t r i b u t e v e c 4 a V e r t e x C o l o r ;

u n i f o r m mat4 uMVMatrix ; //<−−new

v a r y i n g v e c 4 v C o l o r ;

v o i d main ( ) {

v C o l o r = a V e r t e x C o l o r ;

g l P o s i t i o n = uMVMatrix ∗ vec4 ( a V e r t e x P o s i t i o n , 1 . 0 ) ; //< −−new

(32)

スナップショット

webgl sample spiral 01.html

(33)

演習

webgl sample spiral 01.html

の回転軸と回転角を変更してその効果を

(34)

射影変換

webgl sample spiral 02.html

常に正規化ビューボリュームのサイズを意識してモデルを移動・縮小・

回転を設定するよりも、ワールド座標(

CG

世界)の中にカメラを設定す

る、と考えた方が自然。

射影変換。

mat4.perspective

projectionMatrix

を作る

projectionMatrix

uniform

として頂点シェーダに送る

シェーダではこの二つの行列をかける

gl Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

(35)

スナップショット

webgl sample spiral 02.html

(36)

演習

webgl sample spiral 02.html

の射影行列の設定

mat4.perspective(...)

(37)

複数の変換行列の管理

描画する物体が複数の要素から構成されているときなど、カメラ(射影

行列)は固定していて、モデルビュー行列は頻繁に更新してロードする

場合には、モデルビュー行列のスタックを使うのが便利。(以前の

OpenGL

OpenGL 1.x

)には

glPushMatrix(), glPopMatrix()

があったが、

今の

OpenGL

にはない。)

JavaScript

には配列に

push

pop

のメソッドが備わっているのでこれを

使えばいい。

(38)

練習

(39)

変換行列の

push

pop

webgl sample spiral 04.html

} m o d e l V i e w M a t r i x = m o d e l V i e w M a t r i x S t a c k . pop ( ) ; } //−−new f u n c t i o n f u n c t i o n u p l o a d M o d e l V i e w M a t r i x T o S h a d e r ( ) { g l . u n i f o r m M a t r i x 4 f v ( u n i L o c a t i o n [ 1 ] , f a l s e , m o d e l V i e w M a t r i x ) ; }

(40)

変換行列のシェーダへのロード

webgl sample spiral 04.html

f u n c t i o n u p l o a d P r o j e c t i o n M a t r i x T o S h a d e r ( ) { g l . u n i f o r m M a t r i x 4 f v ( u n i L o c a t i o n [ 0 ] , f a l s e , p r o j e c t i o n M a t r i x ) ; } //−−new f u n c t i o n −− f u n c t i o n d r a w a s p i r a l ( ) { // Draw t r i a n g l e s

(41)

描画

webgl sample spiral 04.html

}

f u n c t i o n s t a r t u p ( ) {

c a n v a s = document . g e t E l e m e n t B y I d ( ” myGLCanvas ” ) ; g l = c r e a t e G L C o n t e x t ( c a n v a s ) ;

(42)

演習

参照

関連したドキュメント

SVF Migration Tool の動作を制御するための設定を設定ファイルに記述します。Windows 環境 の場合は「SVF Migration Tool の動作設定 (p. 20)」を、UNIX/Linux

断面が変化する個所には伸縮継目を設けるとともに、斜面部においては、継目部受け台とすべり止め

また適切な音量で音が聞 こえる音響設備を常設設 備として備えている なお、常設設備の効果が適 切に得られない場合、クラ

回転に対応したアプリを表示中に本機の向きを変えると、 が表 示されます。 をタップすると、縦画面/横画面に切り替わりま

えて リア 会を設 したのです そして、 リア で 会を開 して、そこに 者を 込 ような仕 けをしました そして 会を必 開 して、オブザーバーにも必 の けをし ます

パスワード 設定変更時にパスワードを要求するよう設定する 設定なし 電波時計 電波受信ユニットを取り外したときの動作を設定する 通常

張力を適正にする アライメントを再調整する 正規のプーリに取り替える 正規のプーリに取り替える

らぽーる宇城 就労移行支援 生活訓練 就労継続支援B型 40 名 らぽーる八代 就労移行支援 生活訓練 就労継続支援B型 40 名