其实目的是从相机得到的透视图片中,得到目标图片的正交效果图。通过高通插件 和 shader实现透视变换(其实就是为了获得一张正交图片),也有多种实现方式,有些只能在pc端使用,这里只介绍一种可以在pc和移动端都正常实现的方式。

实现思路:

1、首先要有一个shader处理脚本传入的原始图片四个顶底坐标,在vert方法中通过UV坐标调整和差值运算得到目标位置,再通过一世界坐标-》裁剪坐标-》屏幕坐标的变换,最终得到视口坐标内的uv信息,在从frag方法中通过vert计算出来的uv信息从原始图片(相机得到的图片)获取像素, 从而获取识别图中所需区域的正交图。具体算法见 AdjustTextureShader 脚本。在项目中创建一个材质球命名为AdjustTextureMaterial,shader选择为 AdjustTextureShader 。

2、通过在ImageTarget上挂四个空物体,位置拖放到需要截取区域的对应四个角,通过脚本传给shader作为uv变换的原始参数。

3、写一个脚本,用来传递ImageTarget上的四个位置信息给shader做处理。具体见GetTextureByShader脚本。

4、创建一个Plane 命名为 TargetObj,翻转x轴翻转90度 调整合适的大小,因为需要整个画面固定在屏幕上固定位置,所以把这个TargetObj挂在ar相机下,并把ar相机的world center设置为camera。

5、给4步骤创建的TargetObj的材质球换成步骤1创建的材质球,挂上步骤3写的脚本,把ImageTarget下的四个顶点位置信息拖入脚本暴露出的对应接口中。

6、在ImageTarget的脚本DefaultTrackableEventHandler脚本中添加一个公共变量TargetObj,用于相机识别状态改变的时候 显示和关闭这个物体,把步骤4创建的物体,拖入该公共变量。

Shader "Custom/AdjustTextureShader" {Properties{_MainTex("Base (RGB)", 2D) = "white" {}_UvpointTL("point1", Vector) = (0 , 0 , 0 , 0)_UvpointBL("point2", Vector) = (0 , 0 , 0 , 0)_UvpointTR("point3", Vector) = (0 , 0 , 0 , 0)_UvpointBR("point4", Vector) = (0 , 0 , 0 , 0)}SubShader{Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }LOD 200Pass{Blend SrcAlpha OneMinusSrcAlphaCGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"sampler2D _MainTex;//_MainTex_ST.xy存储的是缩放,_MainTex_ST.zw存储的是偏移float4 _MainTex_ST;float4 _UvpointTL;float4 _UvpointBL;float4 _UvpointTR;float4 _UvpointBR;struct v2f {float4 pos : SV_POSITION;//裁剪空间的顶点坐标float2 uv : TEXCOORD0;//第一组纹理坐标float4 fixedPos : TEXCOORD2;//第三组纹理坐标};/*默认顶点坐标参数结构体struct appdata_base {float4 vertex : POSITION;//位置float3 normal : NORMAL;//法线float4 texcoord : TEXCOORD0;//纹理坐标};*/v2f vert(appdata_base v){v2f o;o.pos = mul(UNITY_MATRIX_MVP,v.vertex);o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);o.uv.x = o.uv.x;o.uv.y = 1 - o.uv.y;float4 top = lerp(_UvpointTL, _UvpointTR, o.uv.x);float4 bottom = lerp(_UvpointBL, _UvpointBR, o.uv.x);float4 fixedPos = lerp(bottom, top, o.uv.y);//UNITY_MATRIX_VP:用于将顶点/矢量从世界空间变换到裁剪空间//ComputeScreenPos:裁剪空间坐标转换为屏幕空间坐标o.fixedPos = ComputeScreenPos(mul(UNITY_MATRIX_VP, fixedPos));return o;}float4 frag(v2f i) : COLOR{//i.fixedPos.xy / i.fixedPos.w得到视口空间中的坐标,视口坐标范围[(0,0),(1,1)]//i.fixedPos是屏幕坐标,齐次除法后得到视口坐标return tex2D(_MainTex, i.fixedPos.xy / i.fixedPos.w);}ENDCG}}
}
using UnityEngine;
using Vuforia;public class GetTextureByShader : MonoBehaviour
{public Transform posTL;public Transform posTR;public Transform posBL;public Transform posBR;Camera cam;private RenderTexture renderTexture;ImageTargetBehaviour targetBehaviour;void Start(){targetBehaviour = GameObject.Find("ImageTarget").GetComponent<ImageTargetBehaviour>(); //GetComponentInParent<ImageTargetBehaviour>();gameObject.layer = 31;}void Renderprepare(){if (!cam){GameObject go = new GameObject("__cam");cam = go.AddComponent<Camera>();go.transform.parent = transform.parent;cam.hideFlags = HideFlags.HideAndDontSave;}cam.CopyFrom(Camera.main);cam.depth = 0;cam.cullingMask = 31;if (!renderTexture){renderTexture = new RenderTexture(Screen.width, Screen.height,-50);}cam.targetTexture = renderTexture;cam.Render();GetComponent<Renderer>().material.SetTexture("_MainTex", renderTexture);}void OnWillRenderObject(){if (!targetBehaviour || targetBehaviour.ImageTarget == null)return;Vector3 targetAnglePointTL = posTL.position;Vector3 targetAnglePointBL = posBL.position;Vector3 targetAnglePointTR = posTR.position;Vector3 targetAnglePointBR = posBR.position;Renderprepare();//设置Shader参数GetComponent<Renderer>().material.SetVector("_UvpointTL", new Vector4(targetAnglePointTL.x, targetAnglePointTL.y, targetAnglePointTL.z, 1f));GetComponent<Renderer>().material.SetVector("_UvpointBL", new Vector4(targetAnglePointBL.x, targetAnglePointBL.y, targetAnglePointBL.z, 1f));GetComponent<Renderer>().material.SetVector("_UvpointTR", new Vector4(targetAnglePointTR.x, targetAnglePointTR.y, targetAnglePointTR.z, 1f));GetComponent<Renderer>().material.SetVector("_UvpointBR", new Vector4(targetAnglePointBR.x, targetAnglePointBR.y, targetAnglePointBR.z, 1f));}void OnDestroy(){if (renderTexture)DestroyImmediate(renderTexture);if (cam)DestroyImmediate(cam.gameObject);}
}

涂涂乐 通过shader实现目标区域正交图片提取,移动端可用相关推荐

  1. Unity 涂涂乐(不使用shader)

    一般来说他们做涂涂乐都用到shader,可惜渣渣的我不会shader,就算用了shader,我看不懂里面的原理,会让我很烦,所以就另寻他法 无意中看到unity的商店里有一个涂涂乐的免费教程 最终的实 ...

  2. unity3D 涂涂乐使用shader实现上色效果

    之前我博文里面发过一个简单的通过截图方式来实现的模型上色方法,但是那个方法不合适商用,因为你需要对的很准确才可以把贴图完美截取下来,只要你手抖了一下就会发现贴歪了.那么有没有更好的方法来实现这个效果呢 ...

  3. 手把手教你做个AR涂涂乐

    前段时间公司有一个AR涂涂乐的项目,虽然之前接触过AR也写过小Demo,但是没有完整开发过AR项目.不过经过1个多星期的学习,现在已经把项目相关的技术都学会了,在此向互联网上那些乐于分享的程序员前辈们 ...

  4. ​手把手教你做个AR涂涂乐 ​

    前段时间公司有一个AR涂涂乐的项目,虽然之前接触过AR也写过小Demo,但是没有完整开发过AR项目.不过经过1个多星期的学习,现在已经把项目相关的技术都学会了,在此向互联网上那些乐于分享的程序员前辈们 ...

  5. (示例3)涂涂乐开发教程

    涂涂乐开发教程 本文将向您介绍如何使用 HiAR SDK 创建一个简单的涂涂乐应用. Step 1.基础开发及设置 请先按照"创建 Hello World"中的 Step1-Ste ...

  6. 涂涂乐的详细实现之一--画笔核心功能

    涂涂乐绘图板算是我独立完成的第二个项目,从无到有算起来大概花了一个多月的时间.其中碰到了许许多多的坑,同时也补充了各种各样的知识,总之收获挺大.接下来大概分成五个部分详细介绍各部分功能的实现方法. ( ...

  7. 涂涂乐的详细实现之三--文件IO操作

    这篇内容旨在详细介绍我在完成涂涂乐这个项目中用到的关于文件存储命名等的思路和操作. (一)截图操作 截图的基本思路:在绘图区域确定一个矩形,创建一个Texture2D获取这部分像素并生成图片存储在文件 ...

  8. unity3D AR涂涂乐制作浅谈

    unity3D AR涂涂乐制作浅谈 AR为现在是虚拟现实较为火爆的一个技术,其中有个比较炫酷的就是AR涂涂乐的玩法,这个技术可以把扫描到的图片上的纹理 粘贴到模型上实现为模型上色的功能,但是我们需要怎 ...

  9. hiar sdk for android,HiAR | HiAR SDK for Unity | 涂涂乐开发教程

    本文将向您介绍如何使用 HiAR SDK 创建一个简单的涂涂乐应用. Step 1.基础开发及设置 请先按照"创建 Hello World"中的 Step1-Step4,完成以下工 ...

最新文章

  1. Android 自定义控件开发入门(一)
  2. Linux查看程序端口占用情况【转】
  3. Memcache mutex设计模式
  4. 人工智能时代背景下,NLP方向或将悄悄崛起
  5. android的rgb转bitmap,Android: 格式为RGB_565的bitmap问题
  6. scala学习手记28 - Execute Around模式
  7. 今天网站都变成灰色了,这其中是怎么实现的?
  8. TTS技术简单介绍和Ekho(余音)TTS的安装与编程
  9. docker学习5--docker数据卷(volume)
  10. Gcc 完全参考手册,参数说明,操作指南-Gcc Complete referene
  11. VS2017开发.net core 时默认发布路径文件夹多个BPC
  12. 如何成为优秀的程序员?
  13. kubectl命令补全
  14. laravel 生成二维码
  15. 多校HDU.5724 Chess
  16. M1 Mac Ps2022如何不转译使用拓展插件
  17. 【日常记录】函数指针与回调函数
  18. 大学生职业生涯规划书性格特征_大学生职业生涯规划书【十篇】
  19. pcb图3d模型丢失的情况解决
  20. pkg打包egg (win7/win10通用)

热门文章

  1. 深度学习中各种图像库的图片读取方式
  2. 和绅的女人们——汉人、黑人、白人、还有他的“干”女儿
  3. maven 出现:Failed to execute goal on project...Could not resolve dependencies for project
  4. 除了小程序游戏之外,同样备受外界关注的还有小程序电商
  5. android 高德卫星地图数据,白马地图 Bmap for Android v7.3.81 强大高德百度地图应用|张小北...
  6. Loki 收集Nginx日志以 grafana 可视化展示
  7. Linux PXE无盘工作站
  8. 缓冲技术之四:LRU缓冲管理策略分析
  9. PlantUML(程序员绘制流程图专用工具)
  10. 增强 Jupyter Notebook 的功能,这里有四个妙招