基于unity的AR开发中使用shader遮盖原图像的解决办法

  解决问题:当识别图像并显示虚拟物体成功后,将原图片中存在的物体图像遮盖

①使用的识别图形(图中含有瓶子)


②将该瓶子模型添加为为ImageTarget的子物体


③将这个模型位置移动到与图片中瓶子位置一致


④create plane 作为ImageTarget的子物体

将该plane的y值调到bottle2和ImagetTarget中间

⑤为plane添加unlitshader

Shader "Unlit/NewUnlitShader"
//透明贴图
{
                 Properties
                {
                    _MainTex ("MainTexture" , 2D) = "white" {} //默认值白色
                                 _AlphaTex ("AlphaTex" , 2D) = "white" {} //默认值白色
                                 _Dispear_offset("Dispear offset" ,Range(-6,6))=0 //滚动条
                }
                 SubShader
                {
                                 Tags { "RenderType" ="Opaque" }

                                LOD 100

                                 Pass
                                {
                                                 CGPROGRAM
                                                #pragma vertex vert
                                                #pragma fragment frag
                                                 // make fog work
                                                #pragma multi_compile_fog
                                                
                                                #include "UnityCG.cginc"

                                                 //顶点函数的输入结构
                                                 struct appdata
                                                {
                                                                 float4 vertex : POSITION;
                                                                 float2 uv : TEXCOORD0;
                                                };

                                                 struct v2f
                                                {
                                                                 float2 uv : TEXCOORD0;
                                                                 UNITY_FOG_COORDS(1)
                                                                 float4 vertex : SV_POSITION;
                                                };

                                                 sampler2D _MainTex;
                                                 float4 _MainTex_ST;
                                                 float _Dispear_offset;
                                                 sampler2D _AlphaTex;

                                                v2f vert (appdata v)
                                                {
                                                                v2f o;

                                                                o.vertex = UnityObjectToClipPos (v.vertex);
                                                                o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex);//只对x和y进行变换,z不进行
                                                                 UNITY_TRANSFER_FOG(o,o.vertex);
                                                                return o;
                                                }
                                                
                                                 fixed4 frag (v2f i) : SV_Target
                                                {
                                                                 fixed4 mAlpha = tex2D (_AlphaTex,i.uv.xy);
                                                                 clip(mAlpha.r-0.1);//-0.1是爲了涂黑的部分小于0被裁切掉
                                                                 fixed4 col = tex2D (_MainTex,i.uv.xy);
                                                                 UNITY_APPLY_FOG(i.fogCoord, col);
                                                                return col;
                                                }
                                                 ENDCG
                                }
                }
}

创建材质


其中MainTexture用的是没有瓶子的图片



AlphaTex用的是把瓶子部分以外涂黑的二值图


以上就实现了在该plane中截取瓶子轮廓部分覆盖在原图片上,其余部分为透明不覆盖的效果


最后给瓶子挂上移动代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move : MonoBehaviour
{

    public Vector3 fristPos;//接触时的position   
    public Vector3 twoPos;//移动后的position   
    public float speed = 0.001f;        //移动速度   
    void Update()
    {
        float moveY = 0;// 上下移动的速度           
        float moveX = 0;//左右移动的速度   
        if (Input.GetTouch(0).phase == TouchPhase.Began)
        {
            //获取接触屏幕的坐标   
            fristPos = Input.GetTouch(0).position;
        }
        //判断移动                   
        if (Input.GetTouch(0).phase == TouchPhase.Moved)
        {
            //获取在屏幕上移动后的坐标   
            twoPos = Input.GetTouch(0).position;
            //判断向上移动,并且不出上方屏幕   
            if (fristPos.y < twoPos.y && Camera.main.WorldToScreenPoint(transform.position).y < Screen.height)
            {
                moveY += speed * Time.deltaTime;
            }
            //判断向下移动,并且不出下边屏幕   
            if (fristPos.y > twoPos.y && Camera.main.WorldToScreenPoint(transform.position).y > 0)
            {
                moveY -= speed * Time.deltaTime;
            }
            //判断向左移动,并且不出左边屏幕   
            if (fristPos.x > twoPos.x && Camera.main.WorldToScreenPoint(transform.position).x > 0)
            {
                moveX -= speed * Time.deltaTime;
            }
            //判断向右移动,并且不出右边屏幕   
            if (fristPos.x < twoPos.x && Camera.main.WorldToScreenPoint(transform.position).x < Screen.width)
            {
                moveX += speed * 2.0f * Time.deltaTime;
            }
            //改变物体坐标   
            transform.Translate(moveX, moveY, 0);
        }
    }
}
 
 

效果展示

瓶子移动前


瓶子移动后


猜你喜欢

转载自blog.csdn.net/yyyerica/article/details/79841242