• 沒有找到結果。

OpenGL ES著色語言於Android之應用與分析

N/A
N/A
Protected

Academic year: 2021

Share "OpenGL ES著色語言於Android之應用與分析"

Copied!
52
0
0

加載中.... (立即查看全文)

全文

(1)國立臺灣師範大學 資訊工程研究所碩士論文. OpenGL ES 著色語言於 Android 之應用與分析. Application and Analysis of OpenGL ES Shading Language on Android. 研究生: 指導教授:. 中華民國. 許志遠 張鈞法. 102 年. 撰 博士. 7. 月.

(2) 摘要. Android 發展自 2003 年,廣用於手機、平板等 mobile 裝置,其市占率於 2013 年已達 75%,可見其重要性。在使用者對於解析度、畫質等需求越高的情況 下,純粹使用 2D 繪圖已稍嫌不足夠,如何將 3D 繪圖加以應用已為趨勢。 嵌入式系統在硬體上較受限制,所以我們考量如何在效能與畫質兼具的情 況下達到 3D 視覺效果,經過介紹 OpenGL ES 的繪圖環境,本論文透過使用 OpenGL ES Shading Language(GLSL ES),讓 3D 繪圖的應用在 Android 有更大的展現, 實現 Phong Shading、Bump Mapping、Relief Mapping、Cube Mapping 等不同的 繪圖(render)方式,分別介紹不同繪圖理論及作法。 除了上述提供各種適用於嵌入式的繪圖作法外,透過實作的 FPS 測量數據以 提供硬體規格上效能考量的切換,並可作為程式開發人員選用何種繪圖方式開發 的參考依據,另外,介紹 Android NDK(Android Native Development Kit),由 C++所寫的程式專案能夠過 NDK 移植到 Android,帶來另一種在 Android 上開發 3D 繪圖的想法。. 關鍵字:Phong Shading、Bump Mapping、Relief Mapping、Cube Mapping、Android、 OpenGL ES. II.

(3) 目 錄 附圖目錄 ............................................................ V 附表目錄 ........................................................... VI 第一章 緒論 ........................................................ 1 1.1 背景......................................................... 1 1.2 研究動機..................................................... 1 1.3 論文架構..................................................... 2 第二章 文獻探討 .................................................... 3 2.1 OpenGL ES ................................................... 3. 2.2. 2.3 2.4 第三章 3.1. 2.1.1 OpenGL ES 1.X ......................................... 3 2.1.2 OpenGL ES 2.X ......................................... 4 2.1.3 OpenGL ES 3.X ......................................... 6 Shader ...................................................... 6 2.2.1 Vertex Shader ......................................... 7 2.2.2 Fragment Shader ....................................... 7 Android NDK ................................................. 8 Precomputed Light Transport For All-Frequency Relighting ... 10 技術討論 ................................................... 11 Phong Shading .............................................. 11. 3.1.1 Phong interpolation .................................. 11 3.1.2 Phong reflection model ............................... 13 3.1.3 實作細節.............................................. 13 3.2 Bump Mapping ............................................... 14 3.2.1 Bump mapping basics .................................. 15 3.2.2 實作細節.............................................. 17 3.3 Relief Mapping ............................................. 18 3.3.1 Relief mapping basics ................................ 18 3.3.2 binary search ........................................ 19 3.3.3 linear search ........................................ 20 3.3.4 Self shadow .......................................... 21 3.3.5 實作細節.............................................. 22 3.4 Cube Mapping ............................................... 23 3.4.1 Cube mapping basics .................................. 23 3.4.2 貼圖方式.............................................. 23 3.4.3 反射環境貼圖.......................................... 24 3.4.4 實作細節.............................................. 25 3.5 Android 繪圖環境設置........................................ 26 III.

(4) 第四章 4.1 4.2 4.3 4.4 4.5 第五章. 3.5.1 基礎設置.............................................. 26 3.5.2 進階設置.............................................. 28 3.5.3 其他設置.............................................. 29 實驗結果與分析 ............................................. 30 Phong Shading .............................................. 30 Bump Mapping ............................................... 31 Relief Mapping ............................................. 32 Cube Mapping ............................................... 33 分析比較 ................................................... 34 結論與未來方向 ............................................. 38. 附錄 ............................................................... 39 參考文獻 ........................................................... 44 其他參考資料 ....................................................... 45. IV.

(5) 附圖目錄 圖 2.1:OpenGL ES 1.X pipeline............................................................................. 4 圖 2.2:OpenGL ES 2.X pipeline............................................................................. 5 圖 2.3:fragment 與 vertex 於三角片上的關係圖.................................................. 8 圖 2.4:Android NDK 範例 hello-g12 圖.................................................................. 9 圖 2.5:Android NDK 範例 san-angeles 圖......................... 錯誤! 尚未定義書籤。 圖 2.6:Triple Product Wavelet Integrals for All-Frequency Relighting 不同環境比較圖........................................................................ 錯誤! 尚未定義書籤。 圖 圖 圖 圖 圖 圖 圖 圖 圖 圖. 3.1:flat、Gouraud、Phong shading 三角片上法向量比較圖...................... 10 3.2:flat、Gouraud 、Phong shading 比較圖................................................ 12 3.3:Phong reflection model 示意圖.............................................................. 12 3.4:使用 normal mapping 差異圖..................................................................... 13 3.5:Bump mapping 與 displayment mapping 比較圖...................................... 14 3.6:由 Height map 求 normal map 計算示意圖............................................... 16 3.7:利用 height map 擾亂 normal 示意圖....................................................... 16 3.8:擾亂法向量後示意圖................................................................................... 16 3.9:原圖與 normal map 比較圖......................................................................... 17 3.10:Color map、height map、normal map 比較圖...................................... 18. 圖 圖 圖 圖 圖 圖 圖 圖 圖 圖. 3.11:Binary search 於高度場示意圖.............................................................. 19 3.12:Binary search 交集點錯誤圖.................................................................. 20 3.13:linear search 示意圖.............................................................................. 21 3.14:自我遮蔽示意圖......................................................................................... 21 3.15:Cube map 示意圖一.................................................................................... 24 3.16:Cube map 示意圖二.................................................................................... 24 3.17:Cube map 反射示意圖................................................................................ 24 3.18:入射、反射及折射圖................................................................................. 25 4.1:Phong shading 成果圖................................................................................ 31 4.2:Bump Mapping 成果圖.................................................................................. 32. 圖 圖 圖 圖 圖 圖. 4.3:Relief Mapping 成果圖.............................................................................. 33 4.4:Cube Mapping 成果圖.................................................................................. 34 4.5:六面展開環境貼圖....................................................................................... 34 4.6:效能比較圖................................................................................................... 35 4.7:不同模型成果比較圖................................................................................... 36 4.8:畫質優先考量圖........................................................................................... 37. V.

(6) 附表目錄 表 4.1:ASUS Transformer Pad TF700T 實驗環境表............................................ 30 表 4.2:效能、畫質、開發難度比較表。............................................................... 37. VI.

(7) 第一章 緒論 1.1 背景 電腦圖學領域發展 OpenGL(Open Graphics Library)已相當一段時間,用 在 2D 及 3D 繪圖,擁有跨語言、跨平台與 Open Source 的優勢,成為 DirectX 外 最常被開發研究的對象。隨著 DirectX 9 於 2002 年推出 Shader 繪圖功能,促使 OpenGL 開發全新 OpenGL 2.0 支援 GLSL 的功能[21]。 OpenGL ES 為 Khronos 接手後推廣的 OpenGL API 為了嵌入式系統(Embedded System)的簡化版本,隨著 OpenGL ES 1.0 的出現,為嵌入式系統如 Android、 iOS(iPhone OS)帶來 3D 繪圖的曙光,OpenGL ES 2.0 更加入了 Shader 的支援, 使 3D 繪圖的應用於 mobile 裝置上更為強大。 近年來手機、Pad 等 mobile 裝置發展火熱,幾乎人手一台,同時擁有電腦、 手機、Pad 等裝置已不稀奇,mobile 裝置相較於桌上型電腦或筆記型電腦而言, 更為追求省電、輕薄,在此需求下,mobile 裝置的設計在 CPU、GPU 上傾向於低 耗能,速度較慢,然而時代的進步,隨著市場需求,3D 遊戲在 App 平台層出不窮, 效能不足的問題浮現,如何在這樣的硬體要求之下,使用繪圖技術解決是現在重 要的課題。. 1.2 研究動機 桌上型電腦及筆記型電腦的應用,有不少繪圖相關方面的研究,利用數學模 型、演算法等方式來加速,以求在很短的時間內,有限的硬體之下,達到良好的 1.

(8) 繪圖效果,相較於近年來新興的 mobile 裝置,隨著 Android 版本推陳出新,OpenGL ES 2.0 更能支援 Shader 的使用,但相關研究都還很缺乏。 為了 mobile 裝置上效能的考量,除了等待硬體上的突破外,最直接的方式 便是透過軟體的方式,於是本論文希望實驗借由繪圖(Rendering)方法的切換 以應付不同的需求,亦可滿足硬體規格上不足的效能。 另外,在 Android 這新興領域上圖學的研究還不多,除了上述等直接透過 Java 撰寫繪圖的 OpenGL ES 程式碼外,本研究中也會介紹另一種透過 Android NDK 把 原有的 OpenGL 程式移植到 Android 上的方法,若搭配上數學模型所建立先運算 資訊來繪圖 [NRH04],先行運算好光照、環境、遮蔽等資訊的方式處理以加速, 即使在 mobile 裝置上也能擁有良好的繪圖表現。 嵌入式的系統在 Android 與 iOS 的選擇上,由於 Android 為開放的資源,選 擇其做為本論文研究的平台,實作於 ASUS Pad,希望透過本論文讓 programmer 知道更多 OpenGL ES 在 Anadroid 的應用。. 1.3 論文架構 本論文中共有六章,第一章為緒論,敘述本研究的背景與動機;第二章為文 獻探討,簡單介紹 OpenGL ES、Shader 及 Android NDK;第三章則是對本論文中 所使用的技術做一個概略的介紹;第四章描述本論文實作內容的細節;第五章對 實作結果做一個分析與討論;第六章為結論與未來方向。. 2.

(9) 第二章 文獻探討 2.1 OpenGL ES OpenGL ES 的發展源自 2003 年,為了 mobile 裝置在硬體上效能的受限,其 為 OpenGL 的簡化版本,做為一個免費且跨平台的嵌入式系統,應用包含了手機、 Pad 等。OpenGL ES 是繪圖硬體的軟體介面,為軟體及繪圖硬體中一個靈活強大 的 low-level interface [12]。提供 programmer 指定物件與操作來完成高品質的 繪圖,尤其是 3D 的物件。大多的 OpenGL ES 需要繪圖硬體擁有 framebuffer,因 為 OpenGL ES 畫的物件包含點、線和多邊形,而這些都需要有 framebuffer 存在, programmer 控制這些物件 render 到 framebuffer [ML08]。 目前最新的 OpenGL ES 發展到 3.X 的系列,然而對於開發人員該選擇哪個本 版作為開發程式使用呢?因此以下將介紹不同版本間的差異及其來由,以供開發 人員做選擇。. 2.1.1 OpenGL ES 1.X OpenGL ES 1.1 源自 OpenGL 1.5,除了包含功能強的 function 可以使用之 外也增加了一小部分,然而比起 OpenGL 為了輕量化的緣故,還是刪除了許多 function。 其中與 OpenGL 主要的差異包括 glBegin、glEnd 不支援,需改用 vertex array 的形式,polygon mode 和 antialised polygon rendering 也沒有支援,由於 Quad、 Polygon 可採用三角形繪圖達成,為了輕量化所以不支援,ARB_Image、bitmap 和 3D texture 不支援,還有許多如 frontbuffer、accumulation buffer、display 3.

(10) list、feedback 和 push/pop 等操作也都不支援 [22],另外,double-precision 的 API 沒支援,如 Rotated、Translated 等,須改用 single-precision 的 API 如 Rotatef、Translatef,其餘詳細的差異於可查參考文獻的 OpenGL ES 的規格 書 [BM08]。. 圖 2.1:OpenGL ES 1.X pipeline。OpenGL ES 1.1 的固定管線提供了良好的 3D 應用,從 Transform and Lighting 頂點到 fragment 的 framebuffer [10]。摘錄 自 [13]。. 所以什麼時候選擇此版本做為開發呢?由於固定管線(pipeline),彈性較 低,所以當需要開發的程式不需要太多程式碼便能實現,需求簡單的情況下,可 選擇 OpenGL ES 1.1 的版本來使用,其支援版本自 Android 1.0 開始。. 2.1.2 OpenGL ES 2.X OpenGL ES 2.0 發表自 2007 年,其源自 OpenGL 2.0,與先前版本相比,不 支援 OpenGL ES 1.1 的固定管線,它結合了 OpenGL Shading Language 擁有 4.

(11) programmable 靈活強大的 3D 繪圖管線來創造 shader 及 program 物件,能在 OpenGL ES Shading Language 中撰寫 vertex shader 和 fragment shader [13], 如此可以經由替換不同的 shader 輕易達到不同的 render 方式,例如盒子材質的 切換,不同的反光效果如金屬面則炫光很強,木頭則幾乎無炫光效果,另外搭配 貼圖的使用,便能營造出不同的感覺,此應用不論是展示模型產品或者在遊戲等 領域上都相當實用。 因為 OpenGL 2.0 programmable pipeline 的替換掉 OpenGL 1.x 的 fixed function transformation 和 fragment pipeline,使用 shader 最小化了花費及 能源。. 圖 2.2:OpenGL ES 2.X pipeline。Fragment shader 取代了 OpenGL ES 1.x 的 texture environment、colour sum 等元件。摘錄自 [13]。. OpenGL ES 2.0 雖然並不是完全的兼容 OpenGL ES 1.x,但那些改變與移除 掉的功能可以用 shader 來做到。因為對 shader 支援的關係,OpenGL ES 2.0 5.

(12) 功能很強大,對於開發 OpenGL ES 來講最為推薦,而本論文也是用採用此版本實 作之後探討的應用,其支援版本自 Android 2.2 開始。. 2.1.3 OpenGL ES 3.X OpenGL ES 3.0 的規格於 2012 年公開發表,來自 OpenGL 3.3 和 4.2 的功能, 除了兼容 OpenGL ES 2.0 之外,讓 applicatoin 增加了新的 visual features, 加強了管線包含遮蔽查詢(occlusion queries)、轉換回饋(transform feedback)、實 例渲染(instanced rendering)並支援多個 rendering 目標,全面支援整數及 32 位 元浮點數運算,更大大的加強了 texture 的功能,包含浮點數貼圖、3D 貼圖、 深度貼圖、頂點貼圖、無縫方盒貼圖等[14]。 GPU 方面,目前 ARM 及 Imagination 已經支援,NVIDIA 的 Tegra4 不支援 FP32, 要等到 Tegra 5 才能完全支援 [10],由於 OpenGL ES 3.0 才剛發表不久,Android 目前還未支援,預計到 Android 4.3 會開始支援 [2] 。 目前 Android 支援及使用上最推薦的版本為之援 shader 的 OpenGL ES 2.0, 不過 OpenGL ES 3.0 擁有貼圖及各項強大的功能,期望未來 Android 4.3 以後的 版本能支援!. 2.2 Shader Shader 一詞於 1988 年被 Pixar 在 RenderMan Interface Specification,Version 3.0 中被介紹,在圖學領域中 shader 是一個用來著色的 的 program,產生光及顏色各種特別的效果,其在繪圖硬體上計算著色的效果有 著高度的彈性,大多的 shader 透過 graphics processing unit(GPU)計算繪圖 的效果,但這非必定的,而透過可取代固定管線的 programmable GPU 著色管線, 6.

(13) 可使得客製化的效果能被使用,其中位置、色相、飽和程度、明暗、貼圖等各項 資訊都可以經過演算法定義在 shader,還可藉由外部呼叫該 shader 的 program 來變動參數[26],其在使用上需在程式碼中做綁定,並告訴 program 使用的 vertex shader、fragment shader 及其對應參數為何。 Shader 在 OpenGL 與 Direct3D 都被支援,其應用非常廣泛,不論是電腦 繪圖還是遊戲方面都能做到許多的效果,包含本論文中介紹的 bump mapping、cube mapping 等各種 shading 方式。. 2.2.1 Vertex shader Vertex shader 在 programmable shader 中負責處理各個頂點資訊,能接收 來自外部的頂點參數,包含位置、顏色、貼圖及自定義參數等作為 vertex array object,從 vertex stream 收到一個 vertex 經由上述資訊處理後,output 一個 vertex 到 vertex stream [16] ,再供後續 fragment shader 做處理。 對於 render 每個三角片,OpenGL 都會呼叫 vertex shader 三次處理每個頂 點,呼叫 fragment shader 一次處理三角片中覆蓋的像素,雖然其中牽涉到 rasterization,可先當作 fragment shader 處理的就是像素,而 vertex shader 處理的就是頂點[9]。 vertex. fragment. 7.

(14) 圖 2.3:fragment 與 vertex 於三角片上的關係圖。. 2.2.2 Fragment shader fragment shader 是一個使用者提供的 program,負責處理的 fragment 來自 rasterizing 一個點、線的分割或是 polygon [ML10],如圖 2.3 所示,每個 fragment 包含顏色及深度等資訊。 fragment shader 除了能接收來自 program 的外部參數外,接收來自 vertex shader 的參數,先前 vertex shader 的頂點位置及資訊,如計算後的向量等做內 插,fragment shader 便利用內插後資訊來 render 每個像素,如此一來便能透過 控制這兩個 shader 來達成不同的目標。. 2.3 Android NDK Android NDK(Android Native Development Kit)可以讓 programmer 使用 native-code 如 C/C++來實作部分的 app,對於重複利用程式碼有很大的幫助,提 供了另一個直接在專寫 Android 程式碼外的方式,也能使用 OpenGL ES 來繪圖, 然而使用 NDK 不見得對速度上有幫助且會讓撰寫 app 變得複雜,需要考量自己的 情況是否適合才選擇使用 [3]。 官方提供下載的 NDK 當中包含很有用的 source code,其中 hello-g12 利用 OpenGL ES 2.0 的 shader 繪三角片,另一個範例 san-angeles 使用 OpenGL ES 1.1 展現了載入 model 後的繪圖成果,以動態做顯示。. 8.

(15) 圖 2.4:Android NDK 範例 hello-g12 圖。簡單的示範了 vertex shader 及 fragment shader 在 NDK 中如何使用,藉由此範例可知道如何銜接 Android 的程式碼與 OpenGL ES 的運作。. 圖 2.5:Android NDK 範例 san-angeles 圖。由此範例可知道模型的頂點資訊及 色彩資訊該如何用 OpenGL ES 顯示。. 9.

(16) 目前除了支援只到 OpenGL ES 2.0 之外,使用 NDK 將專案移植須注意幾點重 要事項,如需建立 Android.mk 以描述要編譯的 native source 及其使用的 library、 在 windows 平台下需安裝 Cygwin 將 C/C++等程式碼轉成 android 能使用.so 檔等 各項準備,官方下載的檔案當中 docs 資料夾裡都有文件可以參考,最方便的做法 推薦使用 Eclipse 搭配 Android NDK、Cygwin 來使用。. 2.4 Precomputed Light Transport For All-Frequency Relighting 除了先前介紹許多使用 shader 的 render 方式外,就能在有限硬體下利用演 算法來加速,Triple Product Wavelet Integrals for All-Frequency Relighting [NRH04] 使用 6x64x64 環境貼圖,透過 wavelet 的演算利用拆開的 Lighting、 Visibility、BRDF 三張圖做三重積分,能在短的時間內達成圖 6 的效果,並能移 動光源或旋轉物體,如此利用演算法加速的方式很適合應用在 Android 上。. 圖 2.6:Triple Product Wavelet Integrals for All-Frequency Relighting 不同環境比較圖。摘錄自 [NRH04]。 10.

(17) 第三章 技術討論 此章詳細說明我們實作在 shader 上的各種繪圖方式,包含能造成眩光的 Phong Shading、造成凹凸錯覺的 Bump Mapping、更有 3D 錯覺的 Relief Mapping, 將先介紹各種繪圖的演算法,接著再說明如何實作。. 3.1 Phong Shading Phong shading 指的是一個 3D 繪圖的表面著色的內插方法,也被稱為 Phong interpolation 或者 normal-vector interpolation shading。Phong shading 和 Phong reflection model [Pho75]在 1973 年 Bui Tuong Phong 的博士論文被公開, 1975 年發表於 ACM,其用意在模擬眩光的現象,至今為圖學領域中最廣泛使用的 照明方法之一。. 3.1.1 Phong interpolation 從 Flat shading 的方式來看,在三角片的繪圖上採用的法向量以平面為基 準,如圖 3.1 中 flat 三角片使用同一個法向量,結果如圖 3.2 中,多邊形的亮 片很明顯,非常不平滑,Gourand shading 考慮的法向量為三角片上的各個頂點, 繪圖的結果眩光較真實,但這方法當眩光發生在大的三角片中間時會產生無法顯 現的問題。 11.

(18) Phong shading 的出現解決了這個問題,其利用在頂點的法向量做內插,每 個像素上都有其內插後的法向量,因此運算過後所繪的眩光滑順許多,然而與 Flat shading 及 Gournd shading 相比,Phong shading 計算的不只是頂點而是 像素,因此運算成本較高 [23]。. Flat shading. Gouraud shading. Phong shading. 圖 3.1:flat、Gouraud、Phong shading 三角片上法向量比較圖。此三種繪圖方 式分別以:三角片同一法向量、各頂點法向量、各像素依照頂點內插後法向量。. 圖 3.2:flat、Gouraud 、Phong shading 比較圖,其繪圖的滑順程度以 Phong shading 最佳,然而其運算成本也為最高,可視需求選擇。摘錄自 [4]。. 12.

(19) 3.1.2 Phong reflection model Phong reflection model 也稱為 Phong illuminatoin 或 Phong lighting,為 局部光模型,如圖 3.3,Phong reflection model 描述了反射光,其有粗糙表面 的散射光(diffuse)、光滑表面的鏡面反射光(specular),並加上了場景當中 所收集到少量的環境光(ambient)。. 圖 3.3:Phong reflection model 示意圖。Diffuse 的密集度與光源的距離相關, specular 則因視角及光源角度影響,環境光源則為常數。摘錄自 [24]。. 3.1.3 實作細節 Phong shading 主要技術方面在於眩光的產生,利用反射光及視角到頂點的 向量作內積,搭配眩光範圍的參數便完成炫光,實作上除了眩光之外,還增加了 貼圖的使用,將使得整體繪圖的成果更佳。 Shader 的實作方面分別有 vertex shader 及 fragment shader,vertex shader 計算出頂點的法向量、座標位置、頂點到光源向量、頂點到視點向量及貼圖座標 位置。 Fragment shader 根據拿到的資訊內插之後,由頂點到光源向量與法向量 計算出反射光向量,以反射光向量與頂點倒視點向量搭配高反光參數. 13.

(20) matShininess 來控制眩光依距離衰弱的程度,由此參數乘上光源顏色與 specular 控制參數便完成了 specular 的計算。 Diffuse 與 ambient 除了光源顏色外,乘上各自的控制參數,為了使繪圖的 成果更佳,再搭配依據先前 vertex shader 取得的貼圖座標所取得的貼圖顏色, 另外,diffuse 多了法向量與入射光源的內積來控制光源對其的影響,詳細參見 附錄 A.1。. 3.2 Bump Mapping Bump mapping 於 1978 年由 Blinn 發表 [Bli78],在電腦圖學領域的應用在於 模擬物體表面的凹凸皺紋,其利用擾亂物體表面法向量的方式來影響期打光的計 算,使得少量三角片下的模型能產生有如大量三角片模型的效果。. 圖 3.4:使用 normal mapping 差異圖。Normal mapping 是最使用的 bump mapping。 摘錄自 [20]。. 14.

(21) 3.2.1 Bump mapping basics Bump mapping 與 displayment mapping 相比並未真實改變物體表面的幾何形 狀,還是能將粗糙的凹凸效果展現出來,如圖 3.5 雖然邊緣及陰影上沒辦法如同 displayment mapping 一般有真實物體的 3D 細節,但也因為沒改變幾何的關係, bump mapping 繪圖速度很快。. 圖 3.5:Bump mapping 與 displayment mapping 比較圖。左邊的 Bump mapping 在物體及陰影邊緣上可以看出破綻,改變幾何的 displayment mapping 則沒有此 問題,但 bump mapping 的優點是效能。摘錄自[18]。. Bump mapping 有兩種方式來實作,第一種為使用 height map,heigh tmap 來自貼圖的灰階圖,白色表示高,黑色表示低,利用 height map 來計算表面的 法向量 [18],最後利用計算出的法向量再做其他繪圖動作。 另一種方式為 normal map,如同上述算出法向量的方式,先把 height map 經過計算產生出一張法向量圖(Normal Map),有現成工具如 CrazyBump 能產生 此圖,簡單產生 normal map 的方法說明如圖 3.6,圖像示意如圖 3.7,利用此 normal. 15.

(22) map 作為該點的法向量,便能在光源的影響下讓人產生 3D 的錯覺,原本用來計算 phong shading 的法向量改用經過擾亂後 normal map 的法向量。 x p1 x p3 p p4 x p2 x x are not important points, p1~p4 is neighbors of p. Normal of p = (p1-p2) X (p3-p4) 圖 3.6:由 Height map 求 normal map 計算示意圖。利用要計算的點 p 相鄰的四 個點做兩個向量的外積便能求得法向量。. 物體表面. 高度圖. 物體模擬深度表面. 擾亂後的法向量圖. 圖 3.7: 利用 height map 擾亂 normal 示意圖。原物體表面經過高度圖模擬深 度後,擾亂了原本的法向量 [Mik08]。. 原法向量 擾亂後法向量. 圖 3.8:擾亂法向量後示意圖。原本能眩光的角度經過擾亂後的法向量內積,可 能無法產生眩光。. 16.

(23) 現今最常使用的 bump mappingz 方式為採用 normal map,稱為 normal mapping, 經過現成工具如 CrazyBump 可從原圖產生 [7],在繪圖上便能直接使用,降低繪 圖的負擔以增進效能,其把法向量資訊利用 RGB 方式儲存,因 RGB 數值只能在 0~255 之間,此為 normal map 顏色偏藍的原因,比較如圖 3.8。. 圖 3.9:原圖與 normal map 比較圖。Normal map 經 height map 計算後,利用 RGB 儲存各點的法向量。. 3.2.2 實作細節 Normal mapping 主要技術在於使用 normal map 來取代繪圖當中模型三角片 上各像素的法向量,利用此經過高度圖(Height Map)所計算出來的法向量擾亂, 搭配入射光與其內積後所產生的明暗效果便能使人產生 3D 的錯覺,使得平面也 能有立體感,借此能大大提升效能。 Vertex shader 需要計算好頂點到光源向量、頂點到視點向量及頂點位置, 以供 fragment shader 做之後的繪圖使用。Fragment shader 除了使用貼圖座標 來取得貼圖顏色之外,最重要的為以此座標取得另一張貼圖-normal map 來取得 法向量,依此法向量與頂點到光源向量算出反射光,在 specular 高反光計算便 17.

(24) 能以此反射光與頂點到視點向量做內積,以此為基底搭配眩光參數借此控制眩光 大小。 Diffuse 與 ambient 都要乘上貼圖顏色,diffuse 必須使用先前用 normal map 計算出的法向量與光源向量做內積,此打光使用方法與先前 phong shading 相同, 本實作上為了區分效果,另外加上了沒有貼圖顏色的繪圖控制,最終只要將 ambient、diffuse、specular 相加便算出每個 pixel 的顏色。. 3.3 Relief Mapping Relief Texture Mapping 由 Oliveira 發表於 2000 年的博士論文[15],與 bump mapping 相同也是一種利用貼圖的繪圖方式,然而比起 bump mapping 更具立體感, 利用物理原理在貼圖上模擬深度(height field),藉由視角向量交集高度場的 點來決定其高度以供後續打光處理,此方法能夠展現出 3D 表面的細節,擁有自 我遮蔽、自我陰影等效果。. 3.3.1 Relief mapping basics Relief texture maping 使用貼圖變形的技巧使得每個像素產生了複雜幾何 細節的錯覺,此深度的資訊來自於表面的一段距離的計算,使用的高度圖如圖 3.9 中所示,用 RGBα貼圖來儲存 normal map [POC05] ,height map 利用原圖做灰 階的原理便能完成,而 normal map 則是利用 height map 做該點的法向量計算而 來,可利用如 CrazyBump 等工具來創建。 18.

(25) 圖 3.10:Color map、height map、normal map 比較圖。. 3.3.2 binary search 首先,將來自 height map 的高度場 normalize 在[0,1]之間,如圖 3.10 所 示,B 點的深度最深為 1,A 點最淺為 0,視點 A 到點 B 的向量 V 由 A 點往 B 點前 進,利用 binary search 來尋找交集點 [POC05],如圖中所示第一次並未找到, 於是進行第二次找尋,直到第三次找尋時找到交集點,然而若一直取中點搜尋都 沒搜尋到呢?所以要訂立一個 binary search 的限制,此限制攸關效能與成果, 搜尋次數太少,則細節差,次數太多則影響運算效能。. 深度 0.0. A. 交集點 深度 1.0. 3 2. 1. B. 圖 3.11:Binary search 於高度場示意圖。第三次 binary search 找到的交集點, 取得該深度為 dv。. 19.

(26) 然而此方式有著一種問題,如圖 3.11 所示,第一次 binary search 後,交 集點還沒找到,於是往更深的地方找,最終找到的交集點卻與視覺上從視點 A 看 過應該碰觸的交集點不同,為了解決這個問題,我們需要採用 linear search 的 方法來完成。 雖然此部分得改用 linear search 方式,但並非表示 binary search 無用, 利用 linear search 找尋到交集點的那個區間後,使用 binary search 完成找到 最後交集點的判斷,如此可以加速運算。. 深度 0.0. A. 正確交集點 1 3 錯誤交集點 2 1.0. B. 圖 3.12:Binary search 交集點錯誤圖 [POC05]。計算出的交集點,向量由 A 點到 B 點之前也有交集點,真正該看到的點便有錯誤。. 3.3.3 linear search 找尋交集點方法改用 linear search,由視點 A 朝 B 點每次前進一小段距離, 如此能確保先碰觸到的交集點為應該看到的點,如此便解決先前交集點錯誤的問. 20.

(27) 題。在最後一個交集點的區間時再交給 bineary search 來做,除了保有上述優 點外,對效能也有幫助。. 深度 0.0. A. 1. 每次前進深度. 2 3. 1.0. B. 圖 3.13:linear search 示意圖 [POC05]。. 3.3.4 Self shadow 自我的陰影遮蔽如圖 3.13 所示,當從視點 A 到點 B 的向量算出交集點後, 利用該點到光源向量做搜尋是否有交集點存在,可以使用原本由視點 A 到點 B 的 判斷交集方式來做,以此便能斷定是否在陰影之內。. 21.

(28) 深度 0.0. C. A. 交集點 深度 1.0. B. 圖 3.14:自我遮蔽示意圖 [POC05]。. 3.3.5 實作細節 Relief mapping 最重要的為產生自我遮蔽的效果,我們必須計算出交集點, 首先自 vertex shader 中取得的貼圖座標做為 A 點,以視點 A 到點 B 的向量 normalize 高度為 1 之後做為向量 V,如此點 B 的表示為點 A 加上向量 V。 完成上述工作後便能開始進行搜尋,首先進行 linear search,根據設定的 linear search steps 算出前進的深度 t,接著透過 height map 取得由點 A 往點 B 前進深度 t 之後 height map 上該處的深度 d,若 t>d 則表示已經有交集點了, 接下來該使用 binary search 來找尋交集點位置。 在先前所計算的發生交集點的區段上,使用前後一個 step 的深度作為上下 界限進行 binary search,一樣設置一個 binear search steps 來控制搜尋次數, 使得找尋到交集點或到達搜尋上限時認定其為交集點,便能得到交集點深度,也 22.

(29) 能由此得知該點座標。 後續則利用此座標取得 color map 的顏色以及 normal map 的法向量,以供 內積的打光處理,最後需要計算自我陰影的問題,方法與先前的搜尋相同,一樣 經過 linear search、binary search,不同的只有進出點用的是交集點往光源向 量所得,算出朝光源方向是否有交集點後便能知道是否有遮蔽到,關閉 diffuse 及 specular 以改變打光方式,使該點呈現陰影,參見附錄 A.3。. 3.4 Cube Mapping Cube mapping 在 1986 年由 Ned Greene 發表 [Gre86],為環境貼圖的一種, 使用六張貼圖所組成的盒子(cube)作為環境,除了可以直接利用現成擁有的六 張貼圖外,其來自以視點依據上下左右前後的六張場景,正交 90 度後的平面表 示每個盒子的面。. 3.4.1 Cube mapping basics Cube mapping 比起傳統的 sphere mapping 來的更好,因為 sphere mapping 使用上會發生圖像變形、計算效能差及視點依賴性等問題,其運算上的花費較大, 因此在 real-time 的繪圖上 cube mapping 比起 sphere mapping 更能做到,然而 cube mapping 也有缺點,當新的物體或光源進入到場景當中,或者物體有了移動, 反射的場景改變了,所以 cube map 需要重繪 [19]。 最常被應用在作為 skybox,為遊戲業廣泛使用技巧之一,利用 pre-rendered 的天空貼圖,由繪圖引擎繪到盒子面上,面與在盒子中心的視有著非常遙遠的距 23.

(30) 離,對於需要使用複雜環境貼圖的遊戲而言沒有太多的運算花費。. 3.4.2 貼圖方式 Cube map 六張貼圖分別對應座標系 xyz 如圖 3.14 所式,當物體在盒子中心 時,盒子如圖 3.15 所示將此六張貼圖貼上,經過反射、折射便能將環境上的顏 色影響到該物體上 [8]。. +Y -X. +Z. +X. -Z. -Y. 圖 3.15:Cube map 示意圖一,環繞 360 度的場景,包含上下共六面。. y +Y -X. +Z. Z +X. -Z. x. -Y. 圖 3.16:Cube map 示意圖二,此六張貼圖把盒子包起來便能作為環境貼圖。 24.

(31) 3.4.3 反射環境貼圖 取得環境貼圖顏色的技術在於,入射的 ray 經過該點的法向量,計算出反射 光,取得 cube 上的貼圖顏色,折射跟反射相同,但多考慮了折射係數,經過折 射係數得到的顏色,再經過設定的比率與反射的顏色累加到最終的顯示顏色。. 反射向量 法向量. 物體. 入射向量. 圖 3.17:Cube map 反射示意圖 [25]。反射環境貼圖所取得的顏色後即為該點顯 示的顏色。. 3.4.4 實作細節 首先,必需準備好六張環境貼圖以供 shader 使用,vertex shader 利用點到 視點向量及該點法向量計算出反射向量(reflect),如需要亦可計算折射向量 (refract),其物理原理如下圖表示:. 25.

(32) 入射向量. 反射向量 θ. θ. 1. θ. 1. 2. 折射向量. 圖 3.17:入射、反射及折射圖 [17]。入射角與反射角相等,折射角度與材質係 數相關,. Fragment shader 使用 vertex shader 算出的反射、折射向量自 cube map 中 取得貼圖的顏色,此兩者經過設定的比例混和後,乘上原先計算好的 ambient 以 及經過法向量與光源向量內積後給予明暗變化的 diffuse,再加上反射向量與法 向輛內積給予的 specular,便完成了 cube mapping,由於反射的物理運作上較 為正確,本論文僅使用反射,詳細參見附錄 A.4。. 3.5 Android 繪圖環境設置 本環境設置採用 Eclipse + Android SDK,Eclipse 版本為 4.2.1,專案版 本為 Android 2.3.3,運行的實體機器為 Android 4.0.3 的 ASUS Transformer PAD TF700T,程式碼改自 Shayan Javed 的 OpenGL ES 2.0 examples for Android [11]。 基礎的 Eclipse 與 Android 環境請自行參考網站設置,推薦先行安裝 Eclipse, 再用其內部的 HELP->Install New Software 安裝 Android SDK,另外,要在實體 機器上運作,需要開啟 USB 偵錯及允許模擬位置。 26.

(33) 3.5.1 基礎設置 首先,我們先來知道需要哪些函式才能利用 OpenGL ES 繪出布幕,根據 Android 官方網站提供 [5],當使用 OpenGL ES 繪圖時需擁有一個 view container, 最直接的方法就是實作 GLSurfaceView 和 GLSurfaceView.Renderer, GLSurfaceView 是個 view container,而 GLSurfaceView.Renderer 控制要畫什 麼到那個 view 上。 Application 中要使用 OpenGL ES 2.0 API,需要載入 android.opengl.GLES20 的 package,其所支援的版本自 Android 2.2(API Level 8) [6],另外,需要在 manifest 中加入此行: <uses-feature android:glEsVersion="0x00020000" android:required="true" />. 若 application 中有貼圖壓縮的話,需要告知支援的壓縮格式,裝置在不支 援的情況下便不會跑該 application,如下: <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /> <supports-gl-texture android:name="GL_OES_compressed_paletted_texture" /. Application 要使用 OpenGL ES 需要有 activities,其他 application 在放 其中的可能為 TextView、Button 等,程式碼參見附錄 A.5(1),若我們的 OpenGL ES 繪圖只佔 layout 的一部份的話用 TextureView,而我們要放的為佔全畫面的. 27.

(34) GLSurfaceView,GLSurfaceView 我們可以直接使用,若要實作也很簡單,參見附 錄 A.5(2): 由於我們要使用 OpenGL ES 2.0,需要告知 GLSurfaceView,需加 mGLView.setEGLContextClientVersion(2),GLSurfaceView 直接使用則將上述 mGLView 改為 mGLView = new GLSurfaceView(this);簡化後的版本參見 附錄 A.5(3)。 GLSurfaceView.Renderer 有三個部分,onSurfaceCreated 在 OpenGL ES 環 境建置起來會呼叫一次,onDrawFrame 會一直重繪 view,onSurfaceChanged 當 view 改變時會呼叫,例如轉動物體、放大縮小等,參見附錄 A.5(4),使用以上 最基本的設置便能繪出一個灰色的布幕,對於入門的基礎很重要,下一節將提到 更多重要的部分。. 3.5.2 進階設置 讓我們來使用 shader,首先透過 glCreateShader 根據給予的是 vertex shader/pixel shader 來創立,glShaderSource 告知使用的來源,之後 glCompileShader。Vertex shader/pixel shader(fragment shader)的內容為 字串,可另外存到檔案,方便讀取及抽換使用不同的 shader,相關程式碼參見附 錄 A.5(5)。 接下來我們create program並告知使用哪個vertex shader及 fragment 28.

(35) shader,最後link program,如此我們的application便能使用shader,相關程 式碼參見附錄A.5(6)。 知道如何使用shader之後,我們來理解該如何處理投射、視點轉換矩陣的問 題以及如何將矩陣及其他參數如光源、視點等資訊傳遞到shader使用,投射的矩 陣藉由frustumM來計算,視點轉換矩陣由setLookAtM計算,參見附錄A.5(7)。 接下來我們透過multiplyMM計算rotate、scale、projection、view、normal matrix,參見附錄A.5(8),透過glUniformMatrix4fv告知使用的矩陣, glUniform4fv、glUniform3fv、glUniform1f告知使用的其他參數, glVertexAttribPointer及 glEnableVertexAttribArray來使用點座標及法向量, glActiveTexture及glBindTexture來綁定cube map及2D貼圖,參見附錄A.5(9)。. 3.5.3 其他設置 除了先前章節的繪圖設置之外,以下介紹我們常用的函式包括觸控、選單, onOptionsItemSelected利用getItemId控制不同選項所做的動作,根據 ACTION_DOWN、ACTION_UP及ACTION_MOVE等來控制碰觸放開等各種行為,參見附 錄A.5(10)。 專案下的AndroidManifest.xml主要負責控制對應的應用程式名稱、圖示以 及告知android程式碼與OpenGL ES版本,values/strings.xml負責應用程式名稱 與各個選項的名稱設置、menu/game_menu.xml負責strings.xml與選單中的名稱 29.

(36) 對應,參見附錄A.5(11)。. 第四章 實驗結果與分析 我們開發的作業系統為 Android,以記憶體 1GB,搭配四核心、Full HD 的 ASUS Transformer Pad TF700T 為實驗的機器,透過 Eclipse 與 Android SDK, 以 OpenGL ES 2.0 實驗各種繪圖方式。 ASUS PAD 實驗環境如下表: 硬體 實體機器. ASUS Transformer Pad TF700T. 中央處理器(CPU). Tegra®3 Quad-core CPU 1.6 GHz. 主記憶體. 1GB DDR3. 螢幕解析度. 1920 × 1200 Full HD. 繪圖解析度. 752x1280 軟體. 作業系統. Android 4.0.3. 開發軟體. Eclipse 4.2.1. OpenGL ES SDK. OpenGL ES 2.0. 表 4.1:ASUS Transformer Pad TF700T 實驗環境表。. 經過 3.5 節描述的繪圖環境設置,我們實驗四種不同的繪圖方式—Phong Shading、Bump Mapping、Relief Mapping、Cube Mapping,藉此以了解各種繪圖效果 之間的差異,並比較其效能,可做為程式設計師開發時的選擇參考。. 30.

(37) 4.1 Phong Shading Phong shading 的實作,vertex shader 取得法向量後經過內插給 fragment shader 使用, fragment shader 以 phong reflection model 做 ambient、diffuse、 specular 的打光。 實驗中除了 phong shading,為了使整體畫面更為優美,我們還增加了磚塊 貼圖,使得由 12 個三角片所組成的盒子看起來如同一堆磚塊所組成,如下圖:. 圖 4.1:Phong shading 成果圖. 透過簡單的貼圖與 Phong shading,使得平但無奇的盒子如此美麗,此方式 運算簡單,對效能影響很低,外加上開發容易,遊戲或模型展示的應用都能採用 此方式,其低成本的運算對於平板、手機等嵌入式平台很適合使用。. 4.2 Bump Mapping Bump mapping 除了顏色貼圖外,使用了由顏色貼圖灰階後的高度圖(height map)所轉變而成的向量圖(normal map),利用高低差產生的向量圖使得原本物 31.

(38) 體上的法向量有了不同方向的擾亂,因此有了 3D 立體的錯覺,搭配上 phong shading 的打光,成果如下:. 圖 4.2:Bump Mapping 成果圖. 相對於貼圖純粹使用 phong shading,利用法向量圖擾亂法向量的 bump mapping,其光影的變化更為逼真,擾亂的步驟也僅在於使用的法向量改用法向 量圖的法向量,只要先創建法向量圖,bump mapping 花費成本應該與 phong shading 差異不大。 此方法因為運算成本不高且效果逼真,除了需要另外創建法向量圖,演算很 的開發簡單,兼具繪圖速度與成果逼真的優勢,對於目前硬體效能頗受限制且日 趨要求畫面品質的手機平台遊戲開發最為推薦。. 4.3 Relief Mapping Relief mapping 與先前提到的 bump mapping 相比,Relief mapping 使用三 張貼圖,包含顏色貼圖、高度圖與法向量圖,借由高度圖模擬物體表面的深度, 32.

(39) 利用物理原理,由視角入射計算出碰觸的交集點,利用交集點到光源之間是否另 有交集點判斷是否在陰影之內。 因為模擬高度場的關係,利用上述的方式能做到自我遮蔽與自我陰影的效果, 比起先前提到的 bump mapping,其 3D 細節更為逼真,打光方面同樣都使用 phong shading,結果如下圖:. 圖 4.3:Relief Mapping 成果圖. 此方式為目前提到模擬 3D 細節當中最為逼真卻也最為耗費運算成本,除了 需要創建高度圖與法向量圖外,實作上向量交集等也教先前提到的方法複雜,雖 然運算成本較先前只用 phong shading 或 bump mapping 高,但相對使用複雜的 3D 模型加上貼圖能達到類似的視覺效果,所需要的花費少非常多。 對於視覺效果越來越重視的時代,尤其強調精細的光影變化效果,雖然手機、 平板的硬體規格與作業系統所帶來的限制,還是希望維持擬真的 3D 繪圖細節, 使用 Relief mapping 是個不錯的選擇。. 33.

(40) 4.4 Cube Mapping 先前提到的都是屬於利用 2D 貼圖來擬真 3D 效果的方法,然而對於物體本身 來自周遭的顏色影響也很重要,cube mapping 透過六面的盒子貼圖將物體包住, 利用視點看往物體的反射及折射取得來自盒子的環境貼圖,便能使物體除了自身 之外,得到來自環境的影響。 實作中的物體本身採用幾近透明的方式以顯示反射、折射來自環境貼圖的顏 色影響,結果及環境貼圖如下:. 圖 4.4:Cube Mapping 成果圖. 圖 4.5:六面展開環境貼圖。. 環境貼圖最常應用於遊戲之中,一個場景可能包含了天空地面與周遭環境, 利用 cube mapping 能以很低的成本影響其中的物體如遊戲人物或房間樹木等, 將此技巧結合上述的其他 3D 細節擬真,便能產生非常華麗的畫面,為追求畫面 精緻程度的遊戲甚至動畫都能使用的一個低成本方式。. 34.

(41) 4.5 分析比較 本論文實驗了負責打光的 phong shadinhg,模擬 3D 細節的 bump mapping 及 relief mapping,以及最後的環境貼圖 cube mapping,除了理論演算方法 的區別之外,我們測試並統計其效能如下圖:. 圖 4.6:效能比較圖。分別經過十次的 FPS 平均,800 與 12 個三角片的模型,展 現各種繪圖方式的效能比較。. 從圖中可以看的出來,三角片數量對效能影響很大,越複雜的 rendering 方 式如 relief mapping,除了比其他繪圖方法花費較大外,受 pixel 數量影響很大, 因此選用越少三角片的模型越好,或者採用 fragment shader 有龐大計算的方法 時需考慮 pixel 數量是否夠少。 35.

(42) phong shading 與 bump mapping,差異僅在於 bump mapping 使用的法向量 取自 normal map 的法向量,兩者的 FPS 很相近,都是非常快速的繪圖方式,可 作為效能取向的開發選擇優先考量。 使用不同模型的產生結果如下圖:. (a). (b). (b). (d). 圖 4.7:不同模型成果比較圖。(a)、(b)為 phong shading,(c)、(d)為 bump mapping, 以效能考量為優先選擇。. Cube mapping 與 relief mapping 相對前兩種繪圖方式,花費運算成本較高, 雖然使用 relief mapping 擬真效果更好,但在效能的考量之上須斟酌使用,本 實驗中的 cube mapping 僅反射、折射環境貼圖,其 FPS 便超越 phong shading、 bump mapping,若希望開發的程式以最好效果的 relief mapping 搭配 cube 36.

(43) mapping,所產生的運算成本需要好好考量。. 圖 4.8:畫質優先考量圖。Cube mapping 搭配 relief mapping 相對使用複雜 3D 模型有效能上的優勢,更為介紹幾種繪圖方式最佳畫質的搭配組合。. 綜合以上四種繪圖方式,我們分別以效能、畫質、開發難度等作比較,以協 助程式設計師作開發選擇,如下表: 開發導向. Cube Mapping Phong shading Bump Mapping Relief Mapping. 效能優先. 上. 上. 上. 下. 畫質優先. 上. 下. 中. 上. 開發難度. 下. 下. 下. 上. 效能優先推薦. Bump Mapping. 畫質優先推薦. Cube Mapping+Relief Mapping. 表 4.2:效能、畫質、開發難度比較表。. Bump mapping 效能上與純粹使用 phong shading 幾乎沒差距,但 3D 擬真效 果卻對畫面有很大的幫助,以最佳畫質考量則選擇兼具環境貼圖效果與最佳擬真 的 relief mapping,然而其耗費成本很高,需謹慎評估使用。. 37.

(44) 第五章 結論與未來方向 經過本論文中所提到的繪圖環境設置,使用目前最為推薦支援 shader 的 OpenGL ES 2.0,雖然比起 OpenGL 有許多限制如 Texutre3D、glVertex3f 等無法 使用,但現有的 API 足夠開發各種原本發展於 PC 平台上 OpenGL 的技術。 Android 應用程式的開發受限其硬體,講求效能又兼具畫質,使用搭配貼圖 的 phong shading 以及模擬 3D 細節的 bump mapping、relief mapping 最為恰當, 另外,搭配上 cube mapping 便能使得在平板、手機等嵌入式平台展現的效果不 輸給 PC 平台。 本論文的實驗除了知道各種繪圖方式的使用及效能上的差距外,更從實驗所 得的 FPS 經過比較列出開發程式時採用繪圖方式的選擇參考,如以效能優先則推 薦使用與 phong shading 運算成本相近,擬真效果很好的 Bump mapping,最佳畫 質則以 cube mapping 搭配 relief mapping,既能擁有環境貼圖的影響又有良好 的自我遮蔽、自我陰影的效果。 未來除了可以將更多的繪圖技術透過 OpenGL ES 實作到 Android 上之外,還 可以透過 Android NDK 的方式,使得可利用 C++完成的專案,可以經過函式作為 介面,轉成能與 Android 溝通的編碼,以降低移植到 Android 平台的花費。. 38.

(45) 附錄 A.1 Phong Shading 主要繪圖部分 void main() vec3 N = vec3 E = vec3 L =. { normalize(EyespaceNormal); normalize(eyeVec); normalize(lightDir);. vec3 reflectV = reflect(-L, N); vec4 basecolor = texture2D(texture1, tCoord); vec4 ambientTerm = lightColor * matAmbient * basecolor; vec4 diffuseTerm = lightColor * matDiffuse * basecolor* max(dot(N, L), 0.0); vec4 specularTerm = lightColor * matSpecular * pow(max(dot(reflectV, E), 0.0), matShininess); gl_FragColor =. ambientTerm + diffuseTerm + specularTerm;. }. A.2 Bump Mapping 主要繪圖部分 uniform sampler2D texture2; // normal map texture //normal from the normal map, from [0,1] to [-1,1], other the same with phong shading vec3 N = normalize( texture2D(texture2, tCoord).xyz * 2.0 - 1.0);. A.3 Relief Mapping 主要繪圖部分 (1) search float linearSearch(vec2 A, vec2 B) { float t = 0.0; for( int i = 0; i <LINEAR_STEPS; i++){ t += 1.0 / float(LINEAR_STEPS); float d = texture2D(texture3, mix(A, B, t)).r; if(t > d) break; } return t; } float binarySearch(vec2 A, vec2 B, float a, float b) { float depth=0.0; for(int i = 0; i < BINARY_STEPS; i++){ depth = mix(a, b, 0.5); float d = texture2D(texture3, mix(A, B, depth)).r; if(d > depth) a = depth; else if(d<depth) b = depth; else break; } return depth; 39.

(46) } float fullSearch(vec2 A, vec2 B) { float depth = linearSearch(A, B); return binarySearch(A, B, depth-(1.0 / float(LINEAR_STEPS)), depth); }. (2)計算交集點 vec2 A = tCoord; //entry point of view ray in texture coordinates vec3 V = (eyeVec / -eyeVec.z) * scale; //vector from A to the exit B vec2 B = A + V.xy; float depth = fullSearch(A, B); vec3 P = vec3(mix(A, B, depth), depth);. (3)自我陰影 vec3 l_entry,l_exit,H; float l_depth; l_entry = P + (p_to_light / p_to_light.z) * depth* scale; l_exit = l_entry + (p_to_light / -p_to_light.z)* scale ; l_depth = fullSearch(l_entry.xy, l_exit.xy); if(l_depth < depth-(1.0/float(LINEAR_STEPS))) { ... } //in shadow. (4)取得法向量及顏色 vec4 diffuse_col = texture2D(texture1, P.xy); vec3 norm = normalize(texture2D(texture2, P.xy).rgb * 2.0 - 1.0); float n_dot_l = max( dot(norm, normalize(p_to_light)) , 0.0); vec4 ambientTerm = lightColor * matAmbient * baseColor; vec4 diffuseTerm = lightColor * matDiffuse * baseColor *n_dot_l; vec4 specularTerm = lightColor * matSpecular * pow(max(dot(norm,H),0.0), matShininess);. A.4 Cube Mapping 主要繪圖部分 (1)vertex shader reflectvec = reflect(-eyevec, norm);. (2) fragment shader vec4. reflectcolor = textureCube(CubeMap, reflectvec);. gl_FragColor =(ambientTerm + diffuseTerm)*reflectcolor + specularTerm;. A.5 Android OpenGL ES 環境設置 (1)基本實作 Activity 40.

(47) public class OpenGLES20 extends Activity { private GLSurfaceView mGLView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLView = new MyGLSurfaceView(this); setContentView(mGLView); } }. (2)基本實作 GLSurfaceView class MyGLSurfaceView extends GLSurfaceView { public MyGLSurfaceView(Context context){ super(context); setRenderer(new MyRenderer()); } }. (3)簡化版本 Activity public class OpenGLES20 extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLView = new GLSurfaceView(this); mGLView.setEGLContextClientVersion(2);//Create GLES 2.0 context setContentView(mGLView); } }. (4)基本實作 Renderer public class MyGL20Renderer implements GLSurfaceView.Renderer { public void onSurfaceCreated(GL10 unused, EGLConfig config) { GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); } public void onDrawFrame(GL10 unused) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); } public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); } }. (5) 讀取並編譯 shader private int _program, _vertexShader, _pixelShader; private String _vertexS, _fragmentS; // Vertex shader,load pixel shader the same way with vertex shader _vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, _vertexS); if (_vertexShader == 0) { return 0; } 41.

(48) private int loadShader(int shaderType, String source) { int shader = GLES20.glCreateShader(shaderType); if (shader != 0) { GLES20.glShaderSource(shader, source); GLES20.glCompileShader(shader); } return shader; }. (6) 創建 program 綁定 shader _program = GLES20.glCreateProgram(); if (_program != 0) { GLES20.glAttachShader(_program, _vertexShader); GLES20.glAttachShader(_program, _pixelShader); GLES20.glLinkProgram(_program); }. (7) projection matrix、view matrix private float[] mProjMatrix = new float[12]; public void onSurfaceChanged(GL10 glUnused, int width, int height) { Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 2.0f, 10); } public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { Matrix.setLookAtM(mVMatrix, 0, 0, eyePos[0], eyePos[1], eyePos[2], 0f, 0f, 0f, 1.0f, 0.0f); }. (8) 計算各矩陣 Matrix.scaleM(mScaleMatrix, 0, scaleX, scaleY, scaleZ); Matrix.setRotateM(mRotXMatrix, 0, this.mAngleY, -1.0f, 0.0f, 0.0f); Matrix.setRotateM(mRotYMatrix, 0, this.mAngleX, 0.0f, 1.0f, 0.0f); float tempMatrix[] = new float[12]; float mVPMatrix[] = new float[12]; Matrix.multiplyMM(tempMatrix, 0, mRotYMatrix, 0, mRotXMatrix, 0); Matrix.multiplyMM(mMMatrix, 0, mScaleMatrix, 0, tempMatrix, 0); Matrix.multiplyMM(mMVMatrix, 0, mVMatrix, 0, mMMatrix, 0);. (9)綁定矩陣、光源、視點、點座標、法向量及貼圖等參數 GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(_program, "uMVPMatrix"), 1, false, mMVPMatrix, 0); GLES20.glUniform4fv(GLES20.glGetUniformLocation(_program, "lightPos"), 1, lightPos, 0); GLES20.glUniform3fv(GLES20.glGetUniformLocation(_program, "eyePos"), 1, eyePos, 0); // bind the normal info the same with vertex coordinates _vb.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 42.

(49) GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(_program, "aPosition"), 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, _vb); GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(_program, "aPosition")); //bind cube map, bind texture the same way with GLES20.GL_TEXTURE_2D GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, ShaderActivity.CreateCubeTexture()); GLES20.glUniform1i(GLES20.glGetUniformLocation(_program, "cubemap"),_texIDs.length);. (10)選單及觸控動作 public class ShaderActivity extends Activity { public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.game_menu, menu); return true; } public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.cubemap: renderer.setShader(this.renderer.CUBEMAP_SHADER); default: return super.onOptionsItemSelected(item); } } @Override public boolean onTouchEvent(MotionEvent e) { switch (e.getAction()) { case MotionEvent.ACTION_DOWN: mode = DRAG; break; } }. (11) AndroidManifest.xml <activity android:name=".ShaderActivity" ...> ... </activity> <uses-feature android:glEsVersion="0x00020000" android:required="true" />. (12)values/ strings.xml <resources> <string name="cubemap">Shader: Cube Mapping</string> <string name="app_name">OpenGL ES 2.0</string> </resources>. (13)menu/ game_menu.xml <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/cubemap" android:title="@+string/cubemap"></item> </menu>. 43.

(50) 參考文獻 [Bli78]. Blinn, J.-F.: Simulation of Wrinkled Surfaces, Computer Graphics, Vol. 12 (3), pp. 286-292 SIGGRAPH-ACM, August 1978.. [BM08]. Blythe, D., Munshi, A.: OpenGL ES Common/Common-Lite Profile Specification Version 1.1.12 (Difference Specification) (Annotated), 2008.. [Gre86]. Greene, N.: Environment mapping and other applications of world projections, 1986.. [Mik08]. Mikkelsen, M.: Simulation of Wrinkled Surfaces Revisited, March 26, 2008. [ML08]. Munshi, A., Leech, J.:OpenGL ES Common/Common-Lite Profile Specification Version 1.1.12 (Full Specification), 2008. [ML10]. Munshi, A., Leech, J.: OpenGL ES Common Profile Specification Version 2.0.25 (Full Specification), November 2, 2010.. [NRH04] Ng, R., Ramamoorthi, R., Hanrahan, P.: Triple Product Wavelet Integrals for All-Frequency Relighting. ACM SIGGRAPH, 2004. [Pho75]. Phong, B.-T.: Illumination for Computer Generated Pictures, Comm. ACM, Vol 18(6):311-317, June 1975.. [POC05]. Policarpo, F., Oliveira, M.-M, Comba, J.-L.: Real-Time Relief Mapping on Arbitrary Polygonal Surfaces, ACM 2005.. 44.

(51) 其他參考資料. [1]. ARIESS.: OpenGL ES:Tegra 5 才完全支援,未來或融合到 OpenGL 中 - 電腦硬體情報版 鐵之狂傲. http://www.gamez.com.tw/thread-580832-1-1.html.. [2]. Android and Me.: HTC leaks new features of Android 4.3 [Updated] | Android and Me. http://androidandme.com/2013/05/news/htc-leaks-new-features-of-android-4-3/.. [3]. Android Developers.: Android NDK | Android Developers. http://developer.android.com/tools/sdk/ndk/index.html.. [4]. Andreassen, Ø ., Helgeland, A.: Introduction to UNIK-4660/TMA-4235. http://prosjekt.ffi.no/unik-4660/lectures04/chapters/Introduction.html.. [5]. Android Developers.: Building an OpenGL ES Environment | Android Developers. http://developer.android.com/training/graphics/opengl/environment.html.. [6]. Android Developers.: OpenGL | Android Developers. http://developer.android.com/guide/topics/graphics/opengl.html.. [7]. Construct Wiki.: SourceForge.net: Bumpmapping - construct. http://sourceforge.net/apps/mediawiki/construct/index.php?title=Bumpmapping.. [8]. Friedrich, A.-L.: How to create realistic skies with POV-Ray - part 9 - Cubic Environment Mapping: skyboxes and cubemaps. http://www.f-lohmueller.de/pov_tut/backgrnd/p_sky9.htm.. [9]. IDL Online Help.: About Shader Programs. http://climserv.ipsl.polytechnique.fr/documentation/idl_help/About_Shader_Programs.html. 2007.. [10]. iOS Developer Library.: OpenGL ES Programming Guide for iOS: OpenGL ES on iOS. http://developer.apple.com/library/iOS/#documentation/3DDrawing/Conceptual/OpenGLES_Pro grammingGuide/OpenGLESontheiPhone/OpenGLESontheiPhone.html.. [11]. Javed , S.: OpenGL ES 2.0 examples for Android, 2011. https://code.google.com/p/androidshaders/source/browse/?r=dfb2745160cb5f98da1b135218a0d1 92922a5e36.. [12]. Khronos Group.: OpenGL ES - The Standard for Embedded Accelerated 3D Graphics. http://www.khronos.org/opengles/1_X/.. [13]. Khronos Group.: OpenGL ES 2_X - The Standard for Embedded Accelerated 3D Graphics. http://www.khronos.org/opengles/2_X/.. [14]. Khronos Group.: Khronos Releases OpenGL ES 3.0 Specification to Bring Mobile 3D Graphics to the Next Level - Khronos Group Press Release. http://www.khronos.org/news/press/khronos-releases-opengl-es-3.0-specification.. [15]. Oliveira, M.-M.: Manuel's Relief Texture Mapping Page. http://www.inf.ufrgs.br/~oliveira/RTM.html.. [16]. OpenGL Wiki.: Vertex Shader - OpenGL.org. http://www.opengl.org/wiki/Vertex_Shader. 45.

(52) [17]. Photonics Wiki.: Propagation, Reflection and Refraction - CMDITRWIKI. http://photonicswiki.org/index.php?title=Propagation,_Reflection_and_Refraction.. [18]. Wikipedia.: Bump mapping - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://en.wikipedia.org/wiki/Bump_mapping#cite_note-Mikkelsen-2.. [19]. Wikipedia.: Cube mapping - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://en.wikipedia.org/wiki/Cube_mapping.. [20]. Wikipedia.: Normal mapping - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://en.wikipedia.org/wiki/Normal_mapping.. [21]. Wikipedia.: OpenGL - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://zh.wikipedia.org/wiki/OpenGL.. [22]. Wikipedia.: OpenGL ES - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://en.wikipedia.org/wiki/OpenGL_ES.. [23]. Wikipedia.: Phong shading - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://en.wikipedia.org/wiki/Phong_shading#cite_ref-3.. [24]. Wikipedia.: Phong reflection model - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://en.wikipedia.org/wiki/Phong_reflection_model.. [25]. Wikipedia.: Reflection mapping - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://en.wikipedia.org/wiki/Reflection_mapping.. [26]. Wikipedia.: Shader - Wikipedia, the free encyclopedia. Retrieved July 19, 2013, from http://en.wikipedia.org/wiki/Shader.. 46.

(53)

參考文獻

相關文件

Windows/ Linux/ Mac 各種平台的開發套件,使我們能夠透過各種平台來開發 Android 軟體,所有的 Android 應用程式都是使用 Java

由於 Android 作業系統的開放性和可移植性,它可以被用在大部分電子產品 上,Android 作業系統大多搭載在使用了 ARM 架構的硬體設備上使裝置更加省電

本研究採用的方法是將階層式與非階層式集群法結合。第一步先運用

過去有許多學者使用過幾種方法來評估組織績效,以下舉出常用的八種 方法:(1)比例分析法(Ratio Approach)。(2)平衡計分卡(Balanced Scorecard)

計算統一設備架構(Compute Unified Device Architecture, CUDA)為 nVIDIA 所 提出的 API,是有別於傳統 OpenGL 以及 DirectX,CUDA 讓使用者能夠透過 C

其實 Eclipse 本身只是一個平台,因為眾多外掛的支持讓 Eclipse 具有廣 大的支援性,其中也支援本論文的 android 開發研究,許多 android

本研究是以景觀指數進行對 1993 年、2008 年與擴大土地使用三個時期之評 估,其評估結果做比較討論。而目前研究提供研究方法的應用-GIS 與 FRAGSTATS 之使用方法。從 1993 年至

本研究在於國內汽車產業的經營策略之分析,藉由對已選定的個案進行仔 細地資料蒐集與分析,以期最終從中獲致結論。本研究方法,基本上依 Porter 競 爭分析及