グラフィックスパイプライン 情報可視化論 第 04 回 陰山 聡 神戸大学 システム情報学研究科 計算科学専攻 [情報基盤センター分館 第 1 演習室] 2015.05.12 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 1 / 55 環境設定 環境設定 • WebGL 環境オン • Safari 立ち上げ • 環境設定 • → メニューバーに開発メニューを表示 にチェック • (開発メニューから “WebGL を有効”) • WebGL 公式ページ • http://www.khronos.org/webgl/ • デモ集 http://www.khronos.org/webgl/wiki/Demo_Repository • Safari でのソースコード表示方法: • 開発メニュー • → ページのソースを表示 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 2 / 55 環境設定 復習: WebGL とは WebBL = シェーダを使い、HTML5 の canvas に、JavaScript で 3D CG を書くための API • クロスプラットフォーム • オープンスタンダード • Web で GPU を使ったレンダリングが可能 • 開発・利用が容易: プラグイン不要 • ソースコードが見える • グラフィックス(OpenGL)と UI(ウィンドウ管理やイベント処理) の分離が明白 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 3 / 55 WebGL グラフィックスパイプライン WebGL グラフィックスパイプライン Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 4 / 55 WebGL グラフィックスパイプライン WebGL のグラフィックスパイプライン HTML + CSS + JavaScript + Web アプリ シェーダソースコード + オブジェクトデータ WebGL JavaScript API 頂点シェーダ プリミティブ組み立て ラスタ化 フラグメントシェーダ シザーテスト マルチサンプリング ステンシルテスト デプステスト アルファブレンディング ディザリング 用描画バッファ WebGL cavas の他の画像 スクリーン Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 5 / 55 WebGL グラフィックスパイプライン シェーダ(拡大図は次のページ) HTML + CSS + JavaScript + Web アプリ シェーダソースコード + オブジェクトデータ WebGL JavaScript API 頂点シェーダ プリミティブ組み立て ラスタ化 フラグメントシェーダ シザーテスト マルチサンプリング ステンシルテスト デプステスト アルファブレンディング ディザリング 用描画バッファ WebGL cavas の他の画像 スクリーン Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 6 / 55 WebGL グラフィックスパイプライン シェーダ 頂点シェーダ(バーテックスシェーダ)とフラグメントシェーダ HTML + CSS + JavaScript + Web アプリ シェーダソースコード + オブジェクトデータ WebGL JavaScript API 頂点シェーダ プリミティブ組み立て ラスタ化 フラグメントシェーダ Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 7 / 55 WebGL グラフィックスパイプライン WebGL アプリケーション Web アプリ = HTML + CSS + JavaScript WebGL アプリ = HTML + CSS + JavaScript + シェーダ言語(OpenGL SL) Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 8 / 55 WebGL グラフィックスパイプライン 頂点シェーダ • 各頂点に対して処理を行う • 並列処理 • n 個の頂点があれば n 個の頂点シェーダプロセッサを同時に実行さ せる Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 9 / 55 WebGL グラフィックスパイプライン 頂点シェーダの入出力データ 頂点シェーダ用ソースコード (GLSL) 頂点attribute変数 (座標、色など) 頂点シェーダ ユーザ定義uniform変数 (変換行列、光源位置) Kageyama (Kobe Univ.) 組み込み変数 gl_Position gl_FrontFacing g_lPointSize ユーザ定義の varying変数 情報可視化論 2015.05.12 10 / 55 WebGL グラフィックスパイプライン 頂点シェーダプログラム • C 言語に似ている。 • OpenGL SL (Shading Language) • 4 行 4 列の行列ベクトル演算が組み込み関数 a t t r i b u t e vec3 aVertexPos ; a t r r i b u t e vec4 aVertexColor ; u n i f o r m mat4 uMVMatrix ; u n i f o r m mat4 u P M a t r i x ; v a r y i n g vec4 vColor ; v o i d main ( ) { g l P o s i t i o n = u P M a t r i x ∗ uMVMatrix ∗ v e c 4 ( a V e r t e x P o s , 1 . 0 ) ; vColor = aVertexColor ; } Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 11 / 55 WebGL グラフィックスパイプライン 頂点シェーダプログラム a t t r i b u t e vec3 aVertexPos ; a t r r i b u t e vec4 aVertexColor ; attribute(属性)変数とは • ユーザが定義する変数 • 各頂点に固有のデータ(位置や色) RGBA で 4 成分のベクトル Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 12 / 55 WebGL グラフィックスパイプライン 頂点シェーダプログラム u n i f o r m mat4 uMVMatrix ; u n i f o r m mat4 u P M a t r i x ; mat4 は、4 × 4 の行列の型 uniform 変数とは • ユーザが定義する変数 • (その時刻(フレーム)に)全ての頂点で同じ値を持つデータ Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 13 / 55 WebGL グラフィックスパイプライン 頂点シェーダプログラム v a r y i n g vec4 vColor ; varing 変数 (varying variable) とは • フラグメントシェーダに情報を渡すための変数 • ユーザが定義できる • 組み込み varying 変数もある • gl Position • gl FrontFacing • gl PointSize Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 14 / 55 WebGL グラフィックスパイプライン 頂点シェーダプログラム v o i d main ( ) { g l P o s i t i o n = u P M a t r i x ∗ uMVMatrix ∗ v e c 4 ( a V e r t e x P o s , 1 . 0 ) ; vColor = aVertexColor ; エントリーポイントは main 返値はなし 1. 今処理している頂点の位置(3 次元規格化デバイス座標)を 4 次元に して 2. モデルビュー変換行列をかけて 3. 射影変換行列をかけて 4. 組み込み varying 変数である gl Position に代入する 最後にこの頂点の色を varying 変数である vColor に書き込む Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 15 / 55 WebGL グラフィックスパイプライン プリミティブ組み立て primitive assembly プリミティブ • 3 角形(OpenGL 1.x では沢山のプリミティブがあったがいまは 3 角 形と線分、点のみ。) • 線分 • ポイントスプライト クリッピング処理はここで行われる Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 16 / 55 WebGL グラフィックスパイプライン ラスタ化 プリミティブからフラグメントを作る処理 フラグメント ≈ ピクセル(様々なテストに合格したフラグメントだけが 描画ピクセルになる) プリミティブ Kageyama (Kobe Univ.) フラグメント 情報可視化論 2015.05.12 17 / 55 WebGL グラフィックスパイプライン varying 変数の補間 • 頂点シェーダ からフラグメントシェーダへは varying 変数を通じて 情報を送る。 • 各フラグメントの varying 変数値は自動的に線形補間される。 varyingValue_1 varyingValue_2 varyingValue_3 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 18 / 55 WebGL グラフィックスパイプライン フラグメントシェーダの入出力 全てのフラグメントで並列処理。シェーディング言語でプログラム。 フラグメントシェーダ用 ソースコード (GLSL) 組み込み変数 gl_Position gl_FrontFacing g_lPointSize フラグメント シェーダ 組み込み変数 gl_FragColor ユーザ定義varying変数 ユニフォーム変数 テクスチャ用サンプラ Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 19 / 55 WebGL グラフィックスパイプライン フラグメントシェーダプログラム p r e c i s i o n mediump f l o a t ; // p r e c i s i o n v a r y i n g vec4 vColor ; q u a l i f i e r (精度修飾子) // 補間された値 v o i d main ( ) { gl FragColor = vColor ; } 精度修飾子: 最低保証する精度。 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 20 / 55 WebGL グラフィックスパイプライン WebGL のグラフィックスパイプライン(再掲) HTML + CSS + JavaScript + Web アプリ シェーダソースコード + オブジェクトデータ WebGL JavaScript API 頂点シェーダ プリミティブ組み立て ラスタ化 フラグメントシェーダ シザーテスト マルチサンプリング ステンシルテスト デプステスト アルファブレンディング ディザリング 用描画バッファ WebGL cavas の他の画像 スクリーン Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 21 / 55 WebGL グラフィックスパイプライン シザーテスト 描画ウィンドウの一部の領域だけを「はさみ(scissors)」で切り取る(は さみといっても任意の形ではない。長方形のみ)。 テストに合格したフラグメントだけ描画。不合格フラグメントはそれ以 降のパイプラインを通らない → 処理の高速化 シザーテストの簡単な例: OpenGL Super Bible (2011, p.112) シザーテスト不合格 シザーテスト 合格 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 22 / 55 WebGL グラフィックスパイプライン マルチサンプリング アンチエイリアジング=斜めの線(特にほぼ水平な線)のギザギザをと る方法 マルチサンプリング=周囲の複数のフラグメントをランダムに選択して 色を混ぜる OpenGL Super Bible (2011, p.382) 参照。 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 23 / 55 WebGL グラフィックスパイプライン ステンシルテスト ステンシルバッファの対応する位置の値と比較テストする。 不合格フラグメントは破棄 OpenGL Super Bible (2011, p.399) 参照。 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 24 / 55 WebGL グラフィックスパイプライン デプステスト 既に述べた。 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 25 / 55 WebGL グラフィックスパイプライン アルファブレンディング 半透明な物体の表現 後述 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 26 / 55 WebGL グラフィックスパイプライン ディザリング カラーバッファのビット数が少ないとき、中間色を表現する処理。 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 27 / 55 WebGL による三角形の描画 WebGL による三角形の描画 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 28 / 55 WebGL による三角形の描画 サンプルコード WebGL での三角形の描画 webgl sample triangle 00.html ソースコードの見方: [Safari] 開発 → ページのソースを表示 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 29 / 55 WebGL による三角形の描画 3 角形の描画 HTMLで書いたテキスト WebGLで描いた三角形 canvas Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 30 / 55 WebGL による三角形の描画 webgl sample triangle 00.html <!DOCTYPE HTML> <html l a n g=” en ”> <head> < t i t l e>WebGL Sample T r i a n g l e 00</ t i t l e> <meta c h a r s e t=” u t f −8”> < s t y l e type=” t e x t / c s s ”> canvas { b o r d e r : 2 px s o l i d g r e y ; } . text { position : absolute ; t o p : 40 px ; l e f t : 20 px ; f o n t −s i z e : 1 . 5 em ; Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 31 / 55 WebGL による三角形の描画 webgl sample triangle 00.html <!DOCTYPE HTML> <html l a n g=” en ”> <head> < t i t l e>WebGL Sample T r i a n g l e 00</ t i t l e> <meta c h a r s e t=” u t f −8”> < s t y l e type=” t e x t / c s s ”> canvas { b o r d e r : 2 px s o l i d g r e y ; } . text { position : absolute ; t o p : 40 px ; l e f t : 20 px ; f o n t −s i z e : 1 . 5 em ; Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 32 / 55 WebGL による三角形の描画 color : black ; } </ s t y l e> < s c r i p t type=” t e x t / j a v a s c r i p t ”> var gl ; var canvas ; var shaderProgram ; var vertexBuffer ; f u n c t i o n createGLContext ( canvas ) { v a r names = [ ” w e b g l ” , ” e x p e r i m e n t a l −w e b g l ” ] ; var context = n u l l ; f o r ( v a r i =0; i<names . l e n g t h ; i ++) { try { Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 33 / 55 WebGL による三角形の描画 c o n t e x t = c a n v a s . g e t C o n t e x t ( names [ i ] ) ; } c a t c h ( e ) {} i f ( context ) { break ; } } i f ( context ) { context . viewportWidth = canvas . width ; context . viewportHeight = canvas . height ; } else { a l e r t ( ” F a i l e d to c r e a t e context . ” ) ; } return context ; } Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 34 / 55 WebGL による三角形の描画 f u n c t i o n loadShader ( type , shaderSource ) { var shader = gl . createShader ( type ) ; g l . shaderSource ( shader , shaderSource ) ; gl . compileShader ( shader ) ; if ( ! g l . g e t S h a d e r P a r a m e t e r ( s h a d e r , g l . COMPILE STATUS) ) { a l e r t (” Error compiling shader ” + gl . getShaderInfoLog ( shader ) ) ; gl . deleteShader ( shader ) ; return null ; } return shader ; } function setupShaders () { var vertexShaderSource = Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 35 / 55 WebGL による三角形の描画 var fragmentShaderSource = ” p r e c i s i o n mediump f l o a t ; \n” + ” v o i d main ( ) { \n” + ” g l F r a g C o l o r = v e c 4 ( 0 . 2 , 0 . 4 , 0 . 6 , 1 . 0 ) ; \n” + ” } \n” ; v a r v e r t e x S h a d e r = l o a d S h a d e r ( g l . VERTEX SHADER , vertexShaderSource ) ; v a r f r a g m e n t S h a d e r = l o a d S h a d e r ( g l . FRAGMENT SHADER, fragmentShaderSource ) ; shaderProgram = g l . createProgram ( ) ; Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 36 / 55 WebGL による三角形の描画 g l . attachShader ( shaderProgram , v e r t e x S h a d e r ) ; g l . attachShader ( shaderProgram , fragmentShader ) ; g l . linkProgram ( shaderProgram ) ; if ( ! g l . g e t P r o g r a m P a r a m e t e r ( s h a d e r P r o g r a m , g l . LINK STATUS ) ) { a l e r t ( ” F a i l e d to setup shader . ” ) ; } g l . useProgram ( s h a d e r P r o g r a m ) ; shaderProgram . v e r t e x P o s i t i o n A t t r i b u t e = g l . g e t A t t r i b L o c a t i o n ( shaderProgram , ” a V e r t e x P o s i t i o n ” ) ; } function setupBuffers () { Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 37 / 55 WebGL による三角形の描画 vertexBuffer = gl . createBuffer () ; g l . b i n d B u f f e r ( g l . ARRAY BUFFER , v e r t e x B u f f e r ) ; var t r i a n g l e V e r t i c e s = [ 0.0 , 0.0 , 0.0 , 0.8 , 0.0 , 0.0 , 0.0 , 0.5 , 0.0 ]; g l . b u f f e r D a t a ( g l . ARRAY BUFFER , new F l o a t 3 2 A r r a y ( triangleVertices ) , g l . STATIC DRAW) ; vertexBuffer . itemSize = 3; v e r t e x B u f f e r . nu m be rO f I t em s = 3 ; } f u n c t i o n draw ( ) { g l . viewport (0 , 0 , g l . viewportWidth , g l . viewportHeight ) ; Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 38 / 55 WebGL による三角形の描画 g l . c l e a r ( g l . COLOR BUFFER BIT ) ; g l . v e r t e x A t t r i b P o i n t e r ( shaderProgram . vertexPositionAttribute , v e r t e x B u f f e r . i t e m S i z e , g l . FLOAT , f a l s e , 0 , 0) ; g l . e n a b l e V e r t e x A t t r i b A r r a y ( shaderProgram . vertexPositionAttribute ) ; g l . d r a w A r r a y s ( g l . TRIANGLES , 0 , v e r t e x B u f f e r . n um be rOf It ems ) ; } function startup () { c a n v a s = document . g e t E l e m e n t B y I d ( ” myGLCanvas ” ) ; gl = createGLContext ( canvas ) ; setupShaders () ; setupBuffers () ; gl . clearColor (0.8 , 0.8 , 0.4 , 1.0) ; draw ( ) ; Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 39 / 55 WebGL による三角形の描画 } </ s c r i p t> </ head> <body onl oad=” s t a r t u p ( ) ; ”> <c a n v a s i d=” myGLCanvas ” width=” 480 ” h e i g h t=” 480 ”></ c a n v a s> <d i v c l a s s=” t e x t ”>H e l l o . T h i s i s my f i r s t WebGL program .</ d i v> </ body> </ html> Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 40 / 55 WebGL による三角形の描画 コンテキスト作成 • HTML5 の canvas 要素の getContext method を呼ぶ • 引数(文字列)は “experimental-webgl” を渡す ∗ 。 • getContext method が返すのは WebGLRenderingContext オブジェ クト。 • WebGL の変数や関数はこの WebGLRenderingContext のメンバー。 • このサンプルプログラムでは gl という変数にこのオブジェクトを 代入。 WebGL による三角形の描画 シェーダプログラム • 頂点シェーダ用の(GLSL 言語の)ソースコードは、GPU に送り、 GPU にコンパイルさせる。 • HTML(あるいは JavaScript)の文脈では GLSL ソースコードは単な る文字列。 • ここでは文字列変数 fragmentShaderSource にソースコード文字列を 代入して送っている。 • 【注意】普通はこうはしない。もっと便利な方法がある。後述。 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 42 / 55 WebGL による三角形の描画 シェーダプログラムの作成 1. 頂点シェーダオブジェクトを作る 1.1 頂点シェーダソースコードを頂点シェーダオブジェクトにロードする 1.2 コンパイルする 2. フラグメントシェーダオブジェクトを作る 2.1 フラグメントシェーダソースコードをフラグメントシェーダオブジェ クトにロードする 2.2 コンパイルする 3. プログラムオブジェクトを作る 4. プログラムオブジェクトに頂点シェーダオブジェクトをアタッチす る(こちらが先) 5. プログラムオブジェクトにフラグメントシェーダオブジェクトをア タッチする 6. リンクする 7. このプログラムオブジェクトを WebGLRenderingContext に登録する Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 43 / 55 WebGL による三角形の描画 (GLSL の)頂点属性について ‡ 頂点シェーダ内で定義できる attribute 変数 float, vec2, vec3, vec4, mat2, mat3x2, mat4x2, mat2x3, mat3, mat4x3, mat4, mat2x4, mat3x4 宣言されていても使われていない attribute 変数 → アクティブでない それ以外 → アクティブ アクティブな attribute 変数全体はまとめて整数インデックスで管理され る † それぞれの attribute 変数にはこのインデックスで参照する。 WebGL による三角形の描画 int BindAttribLocation(unit program, unit index, const char *name); • name という attribute 変数を index にバインドする(上書き) 。 • program はリンクしたプログラムオブジェクトの名前。 • 自分でバインドしない場合は GL が自動的にバインド する。 • そのときの index は以下の関数で取得できる。 int GetAttribLocation(unit program, const char *name); attribute 変数名 (name) を指定して、その変数がどのインデックスにバイ ンドされているかを問い合わせる。 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 45 / 55 WebGL による三角形の描画 シェーダプログラム gl.useProgram(shaderProgram); shaderProgram . vertexPositionAttribute = gl.getAttribLocation(shaderProgram, ”aVertexPosition ”); 上で、シェーダプログラムの vertexPositionAttribute というプロパティ名 は任意。 s h a d e r P r o g r a m . anyNameIsOK = g l . g e t A t t r i b L o c a t i o n ( shaderProgram , ” a V e r t e x P o s i t i o n ” ) ; Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 46 / 55 WebGL による三角形の描画 バッファの作成 function setupBuffers () { vertexBuffer = gl . createBuffer () ; g l . b i n d B u f f e r ( g l . ARRAY BUFFER , v e r t e x B u f f e r ) ; var t r i a n g l e V e r t i c e s = [ 0.0 , 0.0 , 0.0 , 0.8 , 0.0 , 0.0 , 0.0 , 0.5 , 0.0 ]; g l . b u f f e r D a t a ( g l . ARRAY BUFFER , new F l o a t 3 2 A r r a y ( triangleVertices ) , g l . STATIC DRAW) ; vertexBuffer . itemSize = 3; v e r t e x B u f f e r . nu m be rO f I t em s = 3 ; } Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 47 / 55 WebGL による三角形の描画 バッファの作成 • 三角形の頂点データをシェーダに送るためにはバッファオブジェク トを使う。 • バッファオブジェクトは WebGLRenderingContext の createBuffer() メソッドで作成する。 • 作成した WebGLBuffer オブジェクトを JavaScript のグローバル変数 vertexBuffer に代入 • vertexBuffer を「現在の配列バッファオブジェクト」にバインドする。 • 後で使えるようにこの頂点配列の情報(頂点数等)も書いておく (どうやって渡してもよい)。 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 48 / 55 WebGL による三角形の描画 描画 f u n c t i o n draw ( ) { g l . viewport (0 , 0 , g l . viewportWidth , g l . viewportHeight ) ; g l . c l e a r ( g l . COLOR BUFFER BIT ) ; g l . v e r t e x A t t r i b P o i n t e r ( shaderProgram . vertexPositionAttribute , v e r t e x B u f f e r . i t e m S i z e , g l . FLOAT , f a l s e , 0 , 0) ; g l . e n a b l e V e r t e x A t t r i b A r r a y ( shaderProgram . vertexPositionAttribute ) ; g l . d r a w A r r a y s ( g l . TRIANGLES , 0 , v e r t e x B u f f e r . n um be rOf It ems ) ; } Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 49 / 55 演習 演習 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 50 / 55 演習 頂点シェーダでの演算 • 頂点シェーダの中で簡単な数値計算をしてみよう。 • 例題:webgl sample triangle 01.html Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 51 / 55 演習 webgl sample triangle 01.html function setupShaders () { var vertexShaderSource = ” 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 ; \n” + ” v o i d main ( ) { \n” + ” g l P o s i t i o n = v e c 4 ( a V e r t e x P o s i t i o n , 1 . 0 ) ; \n” + ” g l P o s i t i o n ∗= v e c 4 ( − 0 . 2 , − 1 . 0 , 1 . 0 , 1 . 0 ) ; // Here ! ! \n ” + ” } \n” ; Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 52 / 55 演習 頂点シェーダでの演算 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 53 / 55 レポート課題 レポート課題 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 54 / 55 レポート課題 • webgl sample triangle 00.html の頂点シェーダを変更して元の三角形 とは別の図形(図)を描け。 • 提出はメールで。添付ファイルは二つ。 1. レポートの PDF ファイル 2. 作成した HTML ファイル • [email protected] • メールのタイトル: 学籍番号_氏名 • レポート(PDF ファイル形式に限る)には以下を記述すること • 学籍番号と氏名 • どのような図形を描いたか • 描いた図形のキャプチャ図 • (オプション: 講義 Web ページでの実名公開が嫌な場合) 氏名のイ ニシャル • 締め切り: 来週 5/19(火)午前 5 時 Kageyama (Kobe Univ.) 情報可視化論 2015.05.12 55 / 55
© Copyright 2024 ExpyDoc