1. 程式人生 > >AR兒童繪本技術實現-靜態著色

AR兒童繪本技術實現-靜態著色

使用vuforia的AR技術+Unity3d實現兒童繪本,市面上的大部分是靜態著色:我們在塗鴉了圖片以後掃描圖片,把圖片上著色的部分貼到3d模型上,實現著色互動兒童繪本玩具。

大概的流程是:
1. 製作3d Model以及對應的著色貼圖
2. 將著色貼圖作為vuforia的識別體
3. 在識別貼圖的時候把texture區域裁剪出來
4. 把裁剪的貼圖貼到3d模型上

單步驟分析:

製作3d Model以及對應的著色貼圖:
這裡有一個檢查UV有沒有做對的方法,把做好的貼圖直接貼到3d模型上面,如果uv不對的話,在需要著色的部分,一般是白色區域裡會有填充色。假如uv沒對上的話,會出現,你或許是把圖片確實著色了,但模型上卻沒有顏色的情況,或者你還沒著色,模型上已經有顏色填充了。

將著色貼圖作為vuforia的識別體:
http://developer.vuforia.com/
在上傳識別圖的時候,最好是圖片在上傳到高通以後顯示是5星,星值越高,越容易識別,更穩定

在識別貼圖的時候把texture區域裁剪出來:
當我們在獲取螢幕貼圖的時候,其實獲取的是整個螢幕上vuforia相機照到的場景資訊,如果我們把這個含有除識別圖以外還有其他資訊的貼圖,貼到3d模型上,此時的模型UV是無法對上。
這個時候,我們需要定義一個面片:
1. 面片的大小一定得跟識別圖大小一致
2. 面片的x軸旋轉90度,為了跟高通相機的投影垂直
3. 將面片設定為透明

然後我可以開始獲取MVP資訊,首先說明一下MVP座標轉換的意義:
M - model world 經過該座標,3d物體由自身的座標轉到空間(世界)座標
V - camera view 經過該座標,3d物體有空間座標轉換到相機座標
P - camera projection 經過該座標,我們可以在螢幕上看到了

Matrix4x4 M = mPlane.GetComponent<Renderer>().localToWorldMatrix;
Matrix4x4 V = Camera.main.worldToCameraMatrix;
Matrix4x4 P = GL.GetGPUProjectionMatrix(Camera.main.projectionMatrix, false);

經過MVP計算以後,我們已經得到的資訊:
1. 面片在空間中的座標位置
2. AR Camera在空間的位置
3. AR Camera在空間中的投影位置
然後我們把MVP相乘,得到了相機投影的剪輯位置,此時可以通過ShaderLab來接受MVP位置資訊,參考資料(

http://wiki.ceeger.com/script:unityengine:classes:gl:gl.getgpuprojectionmatrix
Shader:

Shader "Custom/Test" {
    Properties {
        _MainTex("Texture", 2D) = "white" { }  
    }

    SubShader{ 

    Pass{

    Cull Back

    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag

    #include "UnityCG.cginc"

    sampler2D _MainTex;
    float4x4 _MATRIX_MVP;

    struct v2f{
        float4  pos : SV_POSITION;
        float2  uv : TEXCOORD0;
    };

    v2f vert(appdata_base v){

        v2f o;
        float2 screenSpacePos;
        float4 clipPos;

        //Convert position from world space to clip space.
        //Only the UV coordinates should be frozen, so use a different matrix
        clipPos = mul(_MATRIX_MVP, v.vertex);

        //Convert position from clip space to screen space.
        //Screen space has range x=-1 to x=1
        screenSpacePos.x = clipPos.x / clipPos.w;
        screenSpacePos.y = clipPos.y / clipPos.w;

        //the screen space range (-1 to 1) has to be converted to
        //the UV range 0 to 1
        o.uv.x = (0.5f*screenSpacePos.x) + 0.5f;
        o.uv.y = (0.5f*screenSpacePos.y) + 0.5f;

        //The position of the vertex should not be frozen, so use
        //the standard UNITY_MATRIX_MVP matrix
        o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

        return o;
    }

    half4 frag(v2f i) : COLOR{

        half4 texcol = tex2D(_MainTex, i.uv);
        return texcol;
    }

    ENDCG

    }
    }
} 

*把裁剪的貼圖貼到3d模型上:
將material的mainTexture設定為我們獲取螢幕的texture,高通獲取當前螢幕截圖的方法:

CameraDevice.Instance.SetFrameFormat(Vuforia.Image.PIXEL_FORMAT.RGB888, false);
image = CameraDevice.Instance.GetCameraImage(Vuforia.Image.PIXEL_FORMAT.RGB888);

如果是Editor模式,可以使用:

CameraDevice.Instance.SetFrameFormat(Vuforia.Image.PIXEL_FORMAT.GRAYSCALE;, false);

此為簡化版的教程,本人已經開發多款AR產品,有任何問題可以聯絡我:11413947