(AR)获取摄像头的画面并将其设置为模型贴图之无敌陀螺大回环之实现篇

在说之前,先来说说涂涂乐,涂涂乐的原理也类似于获取摄像头的画面,并且通过shader设置捕捉的画面的某一部分为模型的贴图来实现的。

首先是shader部分:

Shader "Custom/CameraTargetPatch" {

Properties {

_MainTex("Texture", 2D) = "white" { }

}

SubShader{

Pass{

Cull Back

CGPROGRAM

#pragma vertex vert

#pragma fragment frag

#include "UnityCG.cginc"

sampler2D _MainTex;

float4x4 _MATRIX_MVP;

float _yScale;

float _xScale;

struct v2f {

float4  pos : SV_POSITION;

float2  uv : TEXCOORD0;

};

v2f vert(appdata_base v){

v2f o;

float4 uvTmp;

// calculate new uv in camera image

uvTmp = mul(_MATRIX_MVP, float4(v.texcoord.x-0.5f,v.texcoord.y-0.5f,0,1));

uvTmp.x = uvTmp.x/uvTmp.w;

uvTmp.y = uvTmp.y/uvTmp.w;

uvTmp.z = uvTmp.z/uvTmp.w;

// some swap for different coordinate system

uvTmp.x = (uvTmp.x + 1.0f)/2.0f;

uvTmp.y = (uvTmp.y + 1.0f)/2.0f;

o.uv = uvTmp.xy;

//The position of the vertex should not be frozen, so use

//the standard UNITY_MATRIX_MVP matrix for that.

o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

return o;

}

half4 frag(v2f i) : COLOR{

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

return texcol;

}

ENDCG

}

}

}

然后是代码部分:

// 设置模型贴图

public void SetTexture()    {        

// 在ARCamera下新建TextureCamera来捕捉画面,参数要和arcamera保持一直        

cameraObj = new GameObject("TextureCamera");        

cameraObj.transform.SetParent(NewFarmSceneControl.Instance.arCameraTran);        

cameraObj.transform.localPosition = Vector3.zero;        

cameraObj.transform.localRotation = Quaternion.identity;       

 cameraObj.transform.localScale = Vector3.one;        

Camera renderCamera = cameraObj.AddComponent();       

 renderCamera.fieldOfView = NewFarmSceneControl.Instance.ARCamera.fieldOfView;        

renderCamera.clearFlags = CameraClearFlags.SolidColor;        

renderCamera.farClipPlane = 2000.0f;        

renderCamera.nearClipPlane = 0.05f;        

//只开启ARBackground层(这里是为了让该摄像头只获取ARCamra下的Background所拍到的画面)        

renderCamera.cullingMask = LayerMask.GetMask("ARBackground");       

 RenderTexture renderTexture = new RenderTexture(Screen.width / 2, Screen.height / 2, 0);       

 renderCamera.targetTexture = renderTexture;        

GetComponentInChildren().material.mainTexture = renderTexture;        

hasSet = true;       

 P = GL.GetGPUProjectionMatrix(renderCamera.projectionMatrix, false);       

 V = renderCamera.worldToCameraMatrix;        

GetComponentInChildren().material.SetFloat("_xScale", 1.0f);        

GetComponentInChildren().material.SetFloat("_yScale", 1.0f);        

if (boxPosTran == null)        {            boxPosTran = transform.FindChild("BoxPos");        }       

 // 获取模型的本地到世界的矩阵变换       

 M = boxPosTran.localToWorldMatrix;       

 MVP = P * V * M;        

// 设置MVP矩阵       

 GetComponentInChildren().material.SetMatrix("_MATRIX_MVP", MVP);

}

上面方法中有个hasSet布尔值,这里设置为true的目的是为了在Update函数中实时获取摄像头的画面,保证每帧都渲染相同的贴图,否则会出现获取到贴图后,摄像头晃动时模型的贴图发生变化。

所以当hasSet为true时,在Update中也需要重新再设置MVP矩阵

void Update () {        

if (hasSet)        {           

 P = GL.GetGPUProjectionMatrix(NewFarmSceneControl.Instance.ARCamera.projectionMatrix, false);          

 V = NewFarmSceneControl.Instance.ARCamera.worldToCameraMatrix;           

 GetComponentInChildren().material.SetFloat("_xScale", 1.0f);            

GetComponentInChildren().material.SetFloat("_yScale", 1.0f);           

 M = boxPosTran.localToWorldMatrix;            

MVP = P * V * M;           

 GetComponentInChildren().material.SetMatrix("_MATRIX_MVP", MVP);

}

}

最终效果如下图所示


(AR)获取摄像头的画面并将其设置为模型贴图之无敌陀螺大回环之实现篇_第1张图片
效果展示

哇哈哈,是不是很酷炫!

喜欢的话请点个赞哦~~

你可能感兴趣的:((AR)获取摄像头的画面并将其设置为模型贴图之无敌陀螺大回环之实现篇)