2014年2月25日 星期二

WebGL Demo 01: 3D transformation and Lambert lighting


This demo would talk about some 3D computer graphics background knowledge, and to show how to use WebGL to do 3D transformation and Lambert lighting.


Using maximus.js, author by Ellis Mu


     In this demo, I develop a WebGL framework named maximus.js to proof the functions which been implemented by three.js. I choose the same 3d coordinate system as three.js, which is Y-up and right-hand system.

1. Vertex buffer
     In the 3d graphics pipeline, the data format of primitive which GPU can accept, They are vertex buffer and index buffer.

What is vertex buffer? Each primitive must be constructed by vertices. In the case of cube, we create a mesh which has 24 vertices, because it has six faces and per face has four vertices.
     _cubeVertexBuffer = gl.createBuffer();  // create a buffer
     gl.bindBuffer( gl.ARRAY_BUFFER, _cubeVertexBuffer ); // bind this buffer as vertex buffer
    
     var vertices = [             // Create these vertices
              // Front face
              -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,  
              1.0, -1.0, 1.0,  0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0,
              1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
              -1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0,....
    ];
    
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW ); // And then uploading these vertices data to vertex buffer
2. Index buffer
     Index buffer can help us reduce the usage number of vertices. For example, when we want to draw a quad which has two triangle, so we need to define six vertices. But while using index buffer, we just need to record 4 vertices of this quad, and use indices to define as two primitives. This approach can help us reduce massive data while using high-polygon models.
         
In the index buffer, we record [0,1,2,2,3,0] to define two primitives that will search the no.0,1,2,3 order in the vertex data in the GPU primitive assembly stage.


3. 3D transformation
     In the 3D space, we must use lots of Matrix transformation. In this figure, we describe we want to transform our objects to the near clipping plane which is the final 2D screen space. Every model has its own modelToWorld matrix to transform to world space. While a camera moving in a 3D scene, the camera has its own camera view matrix, and the screen space define the projection matrix. Therefore, we use this formula to transform model from object space to screen space.

        Modelscreen = obj2worldMtx X world2cameraMtx X projectionMtx X Modelobject

4. Shader
    Graphics pipeline has several generation, From fixed-function, shader model pipeline, deferred rendering, to physical-based lighting. In this WebGL demo, this is a basic shader model pipeline. We have to send vertex and fragment shader to link program. There are three types of variable we need to know.
  • Attribute
    Attribute means the vertex input from vertex buffer data. This has its own order based on vertexPositionAttribute.
  • Varying
    Varying means the vertex output of vertex shader, that will be interpolated by Rasterizer and be sent to pixel shader.
  • Uniform
    Uniform variable are be set from your application program by uniformMatrix4fv or uniform4fv
5. Lighting
     Lambert lighting is a basic lighting algorithm in the 3D computer graphics. It just has to compute the dot of light vector and pixel normal vector. If the angle >= 90, that means no lighting, else it has lighting.


6. Using three.js
     Finally, I write the same demo by using three.js. It becomes so simple. We just need to the several lines code like this.
              function init() {
                renderer = new THREE.WebGLRenderer();
                renderer.setSize( 400, 300 );
                renderer.setClearColor( 0x000000, 1.0 );  // set frame buffer clear color
                document.body.appendChild( renderer.domElement );
                
                scene = new THREE.Scene();
                camera = new THREE.PerspectiveCamera( 45, 400/300, 0.1, 10000 ); // Projection matrix setup
                
                camera.position.set( 0, 0, 20 );  // Setup camera 
                camera.lookAt( scene.position );
                
                var geometry = new THREE.CubeGeometry( 5, 5, 5 );  // Create cube geometry and material
                var material = new THREE.MeshLambertMaterial( { color: 0xFF0000 } );
                mesh = new THREE.Mesh( geometry, material );
                
                scene.add( mesh );  // Add cube to scene manager
                
                var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); // Create lighting
                light.position.set( 10, 0, 10 );
                scene.add( light );
            }

            function updateFrame() {
                requestAnimationFrame( updateFrame );       
                mesh.rotation.y += THREE.Math.degToRad( 5 ); // Rotate the cube
                
                render();
            }
            
            function render() {
                renderer.render( scene, camera );  // render the meshes of the scene using this camera viewport.
            }

Using three.js


Github: https://github.com/DaoshengMu/Maximus-WebGL

2014年2月19日 星期三

Move your Wordpress website

  1. 簡介
    Wordpress網頁會用到的資料只有兩大區塊,一個為Wordpress安裝檔另一個為MySQL資料庫
  2. Wordpress備份
    直接將www目錄下的Wordpress檔案抓下來,裡面絕大部分都是Wordpress的系統檔,只有wp-content下的資料是網站資料.為了將整體環境一致最好還是都一次拷貝下來,未來如果需要升級也是直接取代新的Wordpress目錄就可以,不過保險起見wp-content目錄以及wp-config.php要先留備份.
  3. MySQL備份
    使用MySQL輸出database指令,將Wordpress所用到的database輸出.使用下列指令:
    mysqldump -u ellis -p wordpress > xxx.sql
    以上列指令為例,是在使用MySQL中的ellis帳號,並且需要密碼驗證,來將wordpress這個database輸出到xxx.sql檔案.
  4. 整合安裝
    首先,將要被移往的主機安裝好Wordpress環境,包含了Apache, MySQL, PHP.接著在MySQL創建一個database(以此說明文件為例我們用wordpress當作database名稱).匯入我們先前匯出的xxx.sql.
    接著,將之前主機抓下來Wordpress檔案取代到現在的Wordpress目錄.最後打開wp-cofig.php調整現在的設定,主要檢查這幾個欄位:
    // ** MySQL settings - You can get this info from your web host ** //
    /** The name of the database for WordPress */
    define('DB_NAME', 'wordpress');  /**資料庫的名稱?*/
    /** MySQL database username */
    define('DB_USER', 'ellis');   /**登入MySQL後台的使用者帳號*/
    /** MySQL database password */
    define('DB_PASSWORD', 'xxxxxxx');  /**使用者的密碼*/
    /** MySQL hostname */
    define('DB_HOST', 'localhost');   /** host的位置也是localhost?*/
    這時候,連到你的網址,應該就可以看到移機後的結果.
  5. 問題排解
    移機可能會遇到幾個問題,在這裡整理一下:
    • 移完機顯示網站不成功
      這個可能是資料表認定的網站位址不是目前新的位址,需要修正資料表,修正方式為,在你的wp-config.php加上
      define('WP_HOME','http://localhost/xxx/');  /**你的新網址*/
      define('WP_SITEURL','http://localhost/xxx/');
      然後在wp-content/themes/%目前所使用的theme檔%/function.php加上
      update_option('siteurl','http://localhost/xxx/'); /**你的新網址*/
      update_option('home','http://localhost/xxx/');
      重新進入網站,成功後記得要上面這幾行都移除,因為不應該永遠存在這些設定.
    • wp-admin登入不進去
      這有兩個原因,一個是管理員將登入的連結改掉,像我就改成booya-admin,另外一個就是有些plugin移機不成功,這時就先把wp-content/plugins目錄名稱先改掉,讓他在抓不到plugins的情況下帶我進去wp-admin,進去之後就可以看到所有plugin都unactivate,再把plugins目錄名稱改回來,重新登入後再一個一個activate.
    • 修改Wordpress語言設定
      首先去下載語言函示庫,繁體中文會在(http://tw.wordpress.org/),將wp-content/languages全部的檔案放到wp-content/languages,或是單獨複製zh_TW.mo亦可.接著修改wp-config.php

      定義你想用的語言,ex:
      define('WPLANG', 'zh_TW'); /** zh_TW is your zh_TW.mo file name */

2014年2月17日 星期一

回首2013年

2013年發生了很多事,我們自己的團隊大家宣布要休息一陣子,大家生活的重心從創業移轉到家庭以及未來的工作上了,可能是這次的開發讓大家都累了。也嘗試接一下案子來做,了解自己在談判能力的不足,有時候會給對方帶來期待,但其實自己的技術和伙伴的投入度並沒有到達水準。還是應該在初期就問問自己的初心是不是真的喜歡這個案子,如果不喜歡還是應該即時回絕,避免傷害到客戶的情誼。

之後我就開始繼續研究我有興趣的HTML5,從做出一個簡單的遊戲到開始能夠跟社群的人互動,了解到動機能夠幫助我們學習到很多東西。

2013年我結婚了,我實在沒想到我會這麼快結婚,其實很多事情都還沒做,一出社會就一直跟同學誏誏我錢存夠了我就要出國念書,結果國防役四年下來存的比我想像中還要少,只夠我出國念一年...也發現我最愛的電腦科學碩士會排斥已經有過國內碩士的學生...一切都不如我以前規劃那樣,這才發現在成長過程中能夠給我良性建議的人實在太少。

今年已經是我第三次做3D引擎了,只要跟我說要做,我其實大概都知道要怎麼做要多少時間,風險已經都會降到10%左右。但是要做的時候難免會想這次我做好了,我會因為這個成就甚麼嗎? 第一套引擎算是我的學習試驗品,但做完沒有人要用,就連想要做商業化宣傳也被老闆直接砍掉。第二套算是一個很有商業化的引擎,公司之前超過一半的專案都在用,但我們也害了很多人趕案子加班,逼了很多人離職,它其實是一個凶器。 第二套引擎的開發讓我開始在國外技術社群認識了很多有野心的團隊,他們是以團隊方式在做技術開發,有一個很強力的leader,團隊規模不會超過十人,但做得很有成就感。再看看我自己,我雖然已經可以跟他們leader討論重要的關鍵議題,也被認為很專業,但我自己語言能力還是沒辦法問得很詳細,再來也一直深耕一個念頭,為什麼我需要在大公司做這樣小團隊就能做到的事,反而會因為大公司的決策速度導致在市場面進展的緩慢,我們東西明明不錯,但社群的人就是不認識我們...

 第三套引擎做起來我已經有點像是機器人在做了,看到我最想競爭的Minko還是這麼的有野心,我曾經嘗試要跟他們一樣做出最棒的產品,但我的動力真的不足,做完我也大概知道它可能會比凶器好一點,因為可能會沒人用。而且他其實並不會幫我們改善周遭的生活,因為它的願景存在是有點模糊。

所以我離職了,離開了待了快六年的公司,曾經有人說公司跟員工的關係有三層,最下層就是建立在錢的關係,第二層是建立在情感關係,第三層是理念關係。第三層的最高境界就是雙方為了一個願景彼此努力甚至爭吵,但成就之後彼此會很開心的聊聊過往,分享成就,這是最喜歡的工作環境,也是我一直努力增進自己的原因,我想要出去尋找那樣的桃花源。


2014年2月11日 星期二

Mozilla can produce near-native performance on the Web

asm.js 有多快?

此文章整理了一連串的效能評比,asm.js對於我們帶來了可期待的效能,但並不是所有情形都能夠比native javascript快,甚至使用asm.js/Emscripten來處理我們的game engine會造成debugging以及與WebGL銜接上的麻煩,在設計前請多加考慮。

http://arstechnica.com/information-technology/2013/05/native-level-performance-on-the-web-a-brief-examination-of-asm-js/


2014年2月5日 星期三

移动GPU全解读

下列文章分析ARM Mali, PowerVR, Adreno等mobile GPU廠商的架構,會提到graphics pipepline對於mobile devices的演進,以及各家廠商為了節能及提高效能上所做的努力。

Reference:
http://www.igao7.com/1217-vv-gpu.html
http://www.igao7.com/1218-vv-gpu.html