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

3D グラフィックス処理の一般過程 1. 3D グラフィックス処理の一般過程

N/A
N/A
Protected

Academic year: 2021

シェア "3D グラフィックス処理の一般過程 1. 3D グラフィックス処理の一般過程"

Copied!
22
0
0

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

全文

(1)

3. 3D

ビューイング

1.

3Dグラフィックス処理の一般過程

2.

射影と射影変換

3.

ビューボリュームとクリッピング

4.

陰面処理とデプスバッファ

5.

ビューポート変換

6.

3Dグラフィックスを描く

7.

モデルビュー変換

(2)

1.

3Dグラフィックス処理の一般過程

(3)

1.

モデリング変換

座標系の異なる複数のオブジェクトを仮想世界に配

置し,統一的に扱うために,それぞれの座標系を

ワールド座標系に変換する

2.

ビューイング変換

ワールド座標系におけるオブジェクトの各座標系を,

視点座標系における座標値に変換する

3Dグラフィックス処理の一般過程

uvn座標系;

投影面を定義するための座標系

視点座標系のZ軸は,uvn座標系の原点を通り,uv平面と直交する

(4)

1.

正規化変換

x,y 成分は,

-1.0 ~ +1.0

の範囲

あるいは,

0.0 ~ +1.0

の範囲

z成分は,

0.0 ~ +1.0

の範囲

あるいは,

-1.0 ~ +1.0

の範囲

3Dグラフィックス処理の一般過程

(5)

1.

透視投影

(6)

1.

投影面における投影点座標の計算

投影面における投影点(x,y)座標は相似三角形理論で計算できる

投影点のx座標と点Pのx座標P

x

の比,

投影点のy座標と点Pのy座標P

y

の比,

投影面の距離Nと点Pの投影中心との距離-P

z

の比は等しい

従って,

投影点の座標は,視点との距離に反比例する.

⇒遠いものは小さく,近いものは大きく見える

投影面の透視点の座標は投影面との距離に比例する

⇒投影される図形は投影面の距離によってスケーリングされる

しかし,射影変換された座標は最後にビューポートに変換されるので

射影される図形の大きさは結果には影響しない

射影と射影変換

z y x

P

N

P

y

P

x

 





z y z x

P

P

N

P

P

N

y

x

,

,

(7)

1.

ビューボリュームとクリッピング

OpenGL;

glFrustum(Gldouble left, Gldouble right,

Gldouble bottom, Gldouble top,

Fldouble nera, G;double far);

gluPerspective(Gldouble fovy, /* y,z

平面における視角 */

Gldouble aspect,

/* 錐台の幅対高さ比 */

Gldouble near,

Gldouble far);

(8)

正射影変換のビューボリューム

OpenGL;

glOrtho(Gldouble left,

Gldouble right,

Gldouble bottom,

Gldouble top,

Gldouble near,

Gldouble far);

ビューボリュームとクリッピング

(9)

射影中心から放射する直線上にある全ての点は同じ場所

に射影される

右図の場合,P

1

がP

2

に隠されているのでP

1

を描く必要は

ない

隠されていることを見つける方法の1つ

視点から見る頂点の距離を利用すること,即ち遠い頂

点が近い頂点に隠される

距離の表現:デプス(depth)

--- 頂点の遠さを[-1, 1]の範囲で正規化したもの

near plane[N]; z=-1,

far plane[F]; z=1

3次元空間の点が射影変換により新たな3次元の

点にマッピングされる,

x,yは射影面の座標,zは視点からの距離

陰面処理とデプスバッファ

z z

P

b

aP

z

N

F

FN

b

N

F

N

F

a

2





z z z y z x z y x

P

b

aP

P

P

N

P

P

N

z

y

x

P

P

P

,

,

,

,

,

,

(10)

OpenGL depth-buffer/z-buffer

pixel

毎にデプス値を記憶する

Depth test;

frame-buffer

にある輝度あるいは色の値を更新するか否かを判断する

被射影の頂点のデプス値は現在より小さければ,そのバッファ値を更新する

処理終了時,デプスバッファの値は一番近い点の値が保存される

この結果,陰面(陰線)を除去され,見える部分のみが描画される

OpenGL;

glCLearDepthMask(Glclampd depth);

初期値を指定

glClear();

初期化

glEnable(GL_DEPTH_TEST);

デプステストを有効にする

glDepthFunc(Glenum func);

func=GL_LESS;

値が小さい場合更新

(11)

1.

ビューポート変換

一連の変換で計算される図形が最後に,この

viewport

にマッピングされる

2.

OpenGl

glViewport(GLint x, GLint y, Glsizei width, Glsizei height);

デバイス座標またはウィンドウ座標

初期値は,(0, 0, winWidth, winHeight)

注: ビューポート変換には,並行移動に加えスケーリング変換も含む

このために,図形が変形する(「ゆがみ」が生じる)

ビューポートの縦横比を near plane と同じにすると,ゆがみは生じない

ビューポート変換

(12)

1.

3Dグラフィックスを描く

program 3.1

faces;

6個の面を構成する頂点の番号を保存

カメラは,初期には原点にある

投影関係は, reshape() の中で次のように指定する

gluPerspective(60.0, (Glfloat)w/(GLfloat)h, 1.0, 20.0);

視界角fovy=60,

視点と前面,後面との距離は,1.0, 20.0

カメラ位置は原点だから,全面z=-1.0, 後面z=-20.0

reshape() は,ウィンドウを再描画する度にパラメータとして

幅wと高さhが,渡されるので,この縦横比を調整する

立方体の描画は,display()の中でDrawBox()を呼び出して行う

各面毎に,面の頂点を用いて,プリミティブGL_LINE_LOOPを指定する

3Dグラフィックスを描く

(13)

1.

モデルビュー変換 program 3.2

program 3.1

では,物体を視点座標で定義し,カメラ位置を考慮して,

物体の座標を決めている ⇒ これは不自然

モデルを移動したり,カメラ位置と視線方向を変えるモデルビュー変換により

物体は,カメラとは無関係にユーザ座標で設計できる

2.

モデリング変換・・・移動・回転・スケーリング

3.

ビューイング変換・・・カメラ位置と視線方向

モデルビュー変換

(14)

#include <stdlib.h> #include <GL/glut.h> GLint faces[6][4]={ /* 頂点番号と面の情報 */ {0,1,2,3},{3,2,6,7},{7,6,5,4},{4,5,1,0},{5,6,2,1},{7,4,0,3}}; GLfloat v[8][3]; /* 頂点座標 {x0,y0,z0}, {x1,y1,z1},….*/ void drawBox(void){ int i;

for(i=0; i<6; i++){

glBegine(GL_LINE_LOOP); glVertex3fv(&v[faces[i][0]][0]); glVertex3fv(&v[faces[i][1]][0]); glVertex3fv(&v[faces[i][2]][0]); glVertex3fv(&v[faces[i][3]][0]); glEnd(); /* pointer i/f */ } } void init(void){ glClearColor(0.0,0.0,0.0,0.0); v[0][0]=v[1][0]=v[2][0]=v[3][0]=-1; /* x-axis*/ v[4][0]=v[5][0]=v[6][0]=v[7][0]=1; v[0][1]=v[1][1]=v[4][1]=v[5][1]=-1; /* y-axis*/ v[2][1]=v[3][1]=v[6][1]=v[7][1]=1; v[0][2]=v[3][2]=v[4][2]=v[7][2]=-4; /* z-axis*/ v[1][2]=v[2][2]=v[5][2]=v[6][2]=-6; }

void display(void){

glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0);

drawBox(); glFlush(); }

void reshape(int w, int h){

glViewport(0, 0, (GLsizei)w, (GLsizei)h); glLoadIdentity();

glMatrixMode(GL_PROJECTION); /* 射影変換*/ gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0); } /* camera = origine*/

/* ViewVolume w/h = ViewPort w/h*/ void keyboard(unsigned char key, int x, int y){

switch(key){ case 27; exit(0); break; } }

int main(int argc, char **argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(200, 200); glutInitWindowPosition(100, 100); glutCreatWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }

3.1

0

4

3

2

7

6

5

1

(15)

#include <stdlib.h> # include <GL/glut.h> GLint faces[6][4]={ {0,1,2,3},{3,2,6,7},{7,6,5,4},{4,5,1,0},{5,6,2,1},{7,4,0,3}}; GLfloat v[8][3]; void drawBox(void){ int i;

for(i=0; i<6; i++){

glBegine(GL_LINE_LOOP); glVertex3fv(&v[faces[i][0]][0]); glVertex3fv(&v[faces[i][1]][0]); glVertex3fv(&v[faces[i][2]][0]); glVertex3fv(&v[faces[i][3]][0]); glEnd(); } } void init(void){ /* オブジェクトをユーザ座標で定義*/ glClearColor(0.0,0.0,0.0,0.0); v[0][0]=v[1][0]=v[2][0]=v[3][0]=-1; v[4][0]=v[5][0]=v[6][0]=v[7][0]=1; v[0][1]=v[1][1]=v[4][1]=v[5][1]=-1; v[2][1]=v[3][1]=v[6][1]=v[7][1]=1; v[0][2]=v[3][2]=v[4][2]=v[7][2]=1; // -4 1 v[1][2]=v[2][2]=v[5][2]=v[6][2]=-1; // -6  -1 }

void display(void){

glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glLoadIdentity(); glutLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); drawBox(); /* camera位置の設定*/ glFlush(); }

void reshape(int w, int h){

glViewport(0, 0, (GLsizei)w, (GLsizei)h); glLoadIdentity();

glMatrixMode(GL_PROJECTION);

gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0);

glMatrixMode(GL_MODELVIEW);

}

void keyboard(unsigned char key, int x, int y){ switch(key){ case 27; exit(0); break; } }

int main(int argc, char **argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(200, 200); glutInitWindowPosition(100, 100); glutCreatWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }

3.2 モデル・ビュー変換

(16)

gluLookAt(

GLdouble eyex, GLdouble eyey, GLdouble eyez, /* camera 位置 */

GLdouble centerx, GLdouble centery, GLdouble centerz, /* cameraの注視点 */

GLdouble upx, GLdouble upy, GLdouble upz)

/* cameraの上方向 */

OpenGLにおけるカメラの設定

OpenGLにおけるカメラの設定

OpenGLにおけるモデルビュー変換の一般的な手順

1.

モデルビュー変換を指定

glMatrixMode(GL_MODELVIEW);

2.

変換マトリクスの初期化

glLoadIdentity();

3.

モデルビュウー変換

gluLookAt();

(17)

#include <stdlib.h> #include <GL/glut.h> GLint faces[6][4]={ {0,1,1,3},{3,2,6,7},{7,6,5,4},{4,5,1,0},{5,6,2,1},{7,4,0,3}}; GLfloat v[8][3]; void drawBox(void){ int i;

for(i=0; i<6; i++){

glBegine(GL_LINE_LOOP); glVertex3fv(&v[faces[i][0]][0]); glVertex3fv(&v[faces[i][1]][0]); glVertex3fv(&v[faces[i][2]][0]); glVertex3fv(&v[faces[i][3]][0]); glEnd(); } } void init(void){ glClearColor(0.0,0.0,0.0,0.0); v[0][0]=v[1][0]=v[2][0]=v[3][0]=-1; v[4][0]=v[5][0]=v[6][0]=v[7][0]=1; v[0][1]=v[1][1]=v[4][1]=v[5][1]=-1; v[2][1]=v[3][1]=v[6][1]=v[7][1]=1; v[0][2]=v[3][2]=v[4][2]=v[7][2]=1; v[1][2]=v[2][2]=v[5][2]=v[6][2]=-1; } viod LookAt(void){ /* 視点の変化に対するビューアップベクトルの計算*/ int i;

GLdouble look[3], norm;

GLdouble ViewAt[3] = {5.0, 7.5, 5.0}; /* 位置 */ GLdouble ViewTo[3] = {0.0, 0.0, 0.0}; /* 注視方向 */ GLdouble ViewUp[3]; /* 上方向 */ for(i=0; i<3; i++){

look[i] =ViewTo[i] - ViewAt[i]; }

ViewUp[0] = - look[0] * look[2]; ViewUp[1] = - look[1] * look[2];

ViewUp[2] = look[0] * look[0] + look[1] * look[1] + look[2] * look[2];

norm = ViewUp[0]*ViewUp[0] + ViewUp[1]*ViewUp[1] + ViewUp[2]*ViewUp[2]; norm = sqrt(norm);

for(i=0; i<3; i++){

ViewUp[i] /= norm; }

gluLookAt(ViewAt[0], ViewAt[1], ViewAt[2], ViewTo[0], ViewTo[1], ViewTo[2], ViewUp[0], ViewUp[1], ViewUp[2]);

} void display(void){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glLoadIdentity(); LookAt(); drawBox(); glFlush(); }

3.3 視点を変化

(18)

void reshape(int w, int h){

glViewport(0, 0, (GLsizei)w, (GLsizei)h); glLoadIdentity();

glMatrixMode(GL_PROJECTION);

gluPerspective(30.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0);

glMatrixMode(GL_MODELVIEW);

}

void keyboard(unsigned char key, int x, int y){ switch(key){ case 27; exit(0); break; } }

int main(int argc, char **argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(200, 200); glutInitWindowPosition(100, 100); glutCreatWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }

3.3

(19)

#include <stdlib.h> #include <GL/glut.h> GLint faces[6][4]={ {0,1,1,3},{3,2,6,7},{7,6,5,4}, {4,5,1,0},{5,6,2,1},{7,4,0,3}}; GLfloat v[8][3]; GLfloat n[6][3]={ {-1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{1.0, 0.0, 0.0}, {0.0, -1.0, 0.0},{0.0, 0.0, -1.0},{0.0, 0.0, 1.0}}; void drawBox(void){ int i;

for(i=0; i<6; i++)

glBegin(GL_POLYGON); glNormal3fv(&n[i][0]); glVertex3fv(&v[faces[i][0]][0]); glVertex3fv(&v[faces[i][1]][0]); glVertex3fv(&v[faces[i][2]][0]); glVertex3fv(&v[faces[i][3]][0]); glEnd(); } } void init(void){ GLfloat mat_amb_diff[4]={1.0,1.0,1.0,1.0}; GLfloat light_amb[4]={1.0,5.5,1.0,1.0}; glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_SMOOTH);

glMaterialfv(GL_FRONT, GL_SPECULAR, mat_amb_diff);

glLightfv(GL_LIGHT0, GL_POSITION, light_amb);

glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); v[0][0]=v[1][0]=v[2][0]=v[3][0]=-1; v[4][0]=v[5][0]=v[6][0]=v[7][0]=1; v[0][1]=v[1][1]=v[4][1]=v[5][1]=-1; v[2][1]=v[3][1]=v[6][1]=v[7][1]=1; v[0][2]=v[3][2]=v[4][2]=v[7][2]=1; v[1][2]=v[2][2]=v[5][2]=v[6][2]=-1; } viod LookAt(void){ /* 視点の変化に対するビューアップベクトルの計算*/ int i;

GLdouble look[3], norm;

GLdouble ViewAt[3] = {5.0, 7.5, 5.0}; /* 位置 */ GLdouble ViewTo[3] = {0.0, 0.0, 0.0}; /* 注視方向 */ GLdouble ViewUp[3]; /* 上方向 */ for(i=0; i<3; i++){

look[i] =ViewTo[i] - ViewAt[i]; }

ViewUp[0] = - look[0] * look[2]; ViewUp[1] = - look[1] * look[2];

ViewUp[2] = look[0] * look[0] + look[1] * look[1] + look[2] * look[2];

norm = ViewUp[0]*ViewUp[0] + ViewUp[1]*ViewUp[1] + ViewUp[2]*ViewUp[2]; norm = sqrt(norm);

for(i=0; i<3; i++){

ViewUp[i] /= norm; }

gluLookAt(ViewAt[0], ViewAt[1], ViewAt[2], ViewTo[0], ViewTo[1], ViewTo[2], ViewUp[0], ViewUp[1], ViewUp[2]);

}

(20)

void display(void){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glLoadIdentity(); LookAt(); drawBox(); glFlush(); }

void reshape(int w, int h){

glViewport(0, 0, (GLsizei)w, (GLsizei)h); glLoadIdentity(); glMatrixMode(GL_PROJECTION); gluPerspective(30.0, (GLfloat)w/(GLfloat)h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); glClear(GL_DEPTH_BUFFER_BIT); }

void keyboard(unsigned char key, int x, int y){ switch(key){ case 27; exit(0); break; } }

int main(int argc, char **argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(200, 200); glutInitWindowPosition(100, 100); glutCreatWindow(argv[0]); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }

3.4

(21)

glMaterialf*(材質が設定される面,材質の特性,設定値);

1) 材質が設定される面

GL_FRONT:ポリゴンの表面

GL_BACK: ポリゴンの裏面

GL_FRONT_AND_BACK: ポリゴンの表面と裏面

2) 材質の特性

GL_DIFFUSE:拡散反射成分,R,G,B,A強度を0.0~1.0で指定

GL_SPECULAR:鏡面反射成分,同上

GL_AMBIENT:環境光反射成分,同上

GL_EMISSION:発光物体の設定,同上

GL_SHININESS:鏡面反射光の強さを0.0~128.0で指定

3) 設定値と設定方法

1> 配列にR,G,B,A強度を予め定義し,glMaterialfv を用いる

float diffuse[ ]={1.0,1.0,10.,1.0};

float specular[ ]={ 1.0,1.0,10.,1.0};

float ambient[ ]={0.1,0.1,0.1,1.0};

glMateialfv(GL_FRONT, GL_DIFFUSE, diffuse);

glMaterialv(GL_FRONT, GL_SPECULAR, specular);

glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);

2> GL_SHININESSを設定する場合は,glMaterialf を用いる

(22)

1.

P61の演習問題 問1~6を実施

2.

提出は,

12月2日(月)

の授業開始時まで

1.

問1~3は,指定の用紙に記載

2.

プログラムのソースコードはプリントしたものを提出

3.

実行結果を示すウィンドウの図を “

PrtScn

” にてプリントしたも

のを提出(当該ソースコードの裏面に)

3.

作業場所

1.

1207教室のオープン時間

1.

月・火,3&4限

2.

木・金,4限

演習課題

参照

関連したドキュメント

それでは,従来一般的であった見方はどのように正されるべきか。焦点を

の点を 明 らか にす るに は処 理 後の 細菌 内DNA合... に存 在す る

週に 1 回、1 時間程度の使用頻度の場合、2 年に一度を目安に点検をお勧め

食品 品循 循環 環資 資源 源の の再 再生 生利 利用 用等 等の の促 促進 進に に関 関す する る法 法律 律施 施行 行令 令( (抜 抜す

過水タンク並びに Sr 処理水貯槽のうち Sr 処理水貯槽(K2 エリア)及び Sr 処理水貯槽(K1 南エリア)の放射能濃度は,水分析結果を基に線源条件を設定する。RO

過水タンク並びに Sr 処理水貯槽のうち Sr 処理水貯槽(K2 エリア)及び Sr 処理水貯槽(K1 南エリア)の放射能濃度は,水分析結果を基に線源条件を設定する。RO

部分品の所属に関する一般的規定(16 部の総説参照)によりその所属を決定する場合を除くほ か、この項には、84.07 項又は

仕上の構成 仕上の構成は、表面処理、主仕上、仕上下地及び附合物よりなるものとする。 ア「 表面処理 」とは 、仕上表面の保護又は意匠