• 沒有找到結果。

結論與未來方向

經過本論文中所提到的繪圖環境設置,使用目前最為推薦支援 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 平台的花費。

39

附錄

A.1 Phong Shading 主要繪圖部分

void main() {

vec3 N = normalize(EyespaceNormal);

vec3 E = normalize(eyeVec);

vec3 L = 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;

float binarySearch(vec2 A, vec2 B, float a, float b) { float depth=0.0;

40 }

float fullSearch(vec2 A, vec2 B) { float depth = linearSearch(A, B);

return binarySearch(A, B, depth-(1.0 / float(LINEAR_STEPS)), depth);

}

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

41

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;

}

42

private int loadShader(int shaderType, String source) { int shader = GLES20.glCreateShader(shaderType);

if (shader != 0) {

_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);

43

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);

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>

44

參考文獻

[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.

45

其他參考資料

[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.

[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.

46

[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.

相關文件