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

刚好看到了一篇有关于涂涂乐原理的实现方法,EsayAR的官方案例里面就是使用的这个方法,EsayAR的官方案例其实基本完成这个涂涂乐的效果在看过涂涂乐原理,结合案例的是用Vuforia实现的一个效果,发现利用Shader的方式来实现涂涂乐UV图片的修正这个方式比利用对准框的方法要好,而且也避免了UV在位置偏移的问题。(PS:点击打开链接 Vuforia的案例,注意PC上是没有问题的,但是移动端UV会出现破面的问题)

这里要注意PC上实现的效果并不代表手机上能实现涂涂了得效果,就如Vuforia的案例一样PC上是没有任何问题,但是在移动端就会出现一些问题。(PS:这里我使用的EsayAR的来实现Vuforia的方法)

注意这里提供的源码是使用EsayAR来写的(PS:移动端是有问题)

using System;
using UnityEngine;
using System.Collections;
using EasyAR;public class Coloring3D : MonoBehaviour
{public MeshRenderer realityPlane;public Camera rendercamera;private Vector3[] marks;private Material cubeMat;private Vector2 sizeVector2;private Vector2 webcamTex2ScreenScale;private ImageTargetBehaviour imageTargetBehaviour;private Texture2D scanTexture2D;private bool isSetupScale = false;// Use this for initializationvoid Start (){Init();}public void Init(){marks = new Vector3[4];sizeVector2 = new Vector2();imageTargetBehaviour = transform.GetComponentInParent<ImageTargetBehaviour>();sizeVector2 = imageTargetBehaviour.Size;//计算识别Plane的4个角的位置for (int i = 0; i < marks.Length; i++){float x = -1, y = -1;if ((i + 1) % 2 == 0)x = 1;elsex = -1;if (i >= 2)y = 1;marks[i] = new Vector3(sizeVector2.x / 2 * x, 0, sizeVector2.y / 2 * y);}}void SetupScale(){//if (!imageTargetBehaviour.GetIsShow())//判断模型是不是显示出来,可以注释掉//return;if (!isSetupScale){cubeMat = this.transform.GetComponent<MeshRenderer>().material;var texture = realityPlane.material.mainTexture;//获取摄像头照到的纹理图片cubeMat.mainTexture = texture;//将纹理赋值到材质球上//计算屏幕和整张图片的比例var maxScale = Mathf.Max((float)Screen.width / texture.width, (float)Screen.height / texture.height);var t2sWidth = texture.width * maxScale;var t2sHeight = texture.height * maxScale;webcamTex2ScreenScale.x = Screen.width / t2sWidth;webcamTex2ScreenScale.y = Screen.height / t2sHeight;isSetupScale = true;}for (int i = 0; i < marks.Length; i++){marks[i] = marks[i] + this.transform.parent.position;var pos =AdjustUV(rendercamera.WorldToViewportPoint(marks[i]));string posName = String.Format("p{0}", i);cubeMat.SetVector(posName, pos);//传入到shader进行纹理的拉伸}}Vector4 AdjustUV(Vector3 v){//识别图在屏幕的位置var webcamX = FixWebcamTextureToScreenUV(v.x, webcamTex2ScreenScale.x);var webcamY = FixWebcamTextureToScreenUV(v.y, webcamTex2ScreenScale.y);return new Vector4(webcamX*v.z, (1 - webcamY)*v.z, v.z, 1.0f);}float FixWebcamTextureToScreenUV(float value, float scale){return (1.0f - scale) * 0.5f + value * scale;}// Update is called once per framevoid OnWillRenderObject(){SetupScale();}
}

接下来是shader:

Shader "Unlit/PaintingShader"
{Properties{_MainTex ("Texture", 2D) = "white" {}}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 p0;float4 p1;float4 p2;float4 p3;v2f vert (appdata v){v2f o;o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);o.uv.x = v.uv.x;o.uv.y = v.uv.y;return o;}fixed4 frag (v2f i) : SV_Target{float2 mid;float3 newUV;//计算纹理的位置if (i.uv.x + i.uv.y >= 1) {mid = i.uv;newUV = p0 * (1 - mid.x - mid.y) + p1 * mid.x + p2 * mid.y;} else {mid = float2(1 - i.uv.y, i.uv.x + i.uv.y - 1);newUV = p2 * (1 - mid.x - mid.y) + p1 * mid.x + p3 * mid.y;}//返回计算好的纹理位置return tex2D(_MainTex, newUV.xy / newUV.zz);}ENDCG}}
}

这里看看效果PC的效果图片吧!

(PS:这里要注意移动端是会出现问题的,但是PC端是没有问题的)

最后附上一张移动端的涂涂乐效果图出来

功能有实时渲染,点击屏幕后就取消实时渲染然后上色到模型上。(PS:移动端的和PC端的代码编写差异挺大的,但是还是离不上面用到的源码)

Vuforia的移动端问题有待解决,如果解决这个问题我会第一时间写博客告诉大家。

(如果想交流一下涂涂乐的问题,可以私信我..)我发现给出QQ老是有人想不劳而获...

unity3D 涂涂乐使用shader实现上色效果相关推荐

  1. unity3D AR涂涂乐制作浅谈

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

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

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

  3. 涂涂乐的详细实现之四--unity3d调用EmguCV实现图片识别

    涂涂乐严格来说有两个版本,一种是前面详细介绍过的,鼠标控制画图截图发送给服务端实现模型上色:另一种是通过实物图彩笔绘图之后通过扫描仪生成图片发送给服务端来实现模型上色. 动物模型有多种,贴图有多种,在 ...

  4. EasyAR4.0使用说明(Unity3D)三----平面图像跟踪扩展:视频播放,涂涂乐

    播放视频 平面图像识别以后播放视频也是一种经常被用到的增强现实的表现方式.通常是截取视频第一帧的图片作为识别图片,识别以后播放视频.这样就给人一个图片动起来的错觉. 在场景中设置Main Camera ...

  5. EasyAR涂涂乐代码分析

    来说一下对EasyAR sdk中自带的unity Samples中的Coloring3D这个项目的理解(例子程序可以去官网下载 最后会列出所有用到网站的网址). 这个项目的效果就是我们常见的" ...

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

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

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

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

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

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

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

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

最新文章

  1. sublime配置python开发环境_win7 下搭建sublime的python开发环境的配置方法
  2. idea的pom变成橙色的xml文件
  3. Javascript 对象二(Number、String、Boolean、Array、Date、Math、RegExp)
  4. 如何创建_重庆市百科如何创建
  5. NoSQL之MongoDB安装
  6. hadoop安装教程学习
  7. Unity3D游戏开发之反编译AssetBundle提取游戏资源
  8. android 地球仪源码,android OpenGL ES 地球仪绘制——球体绘制及纹理映射
  9. 软件开发中需求分析的过程、层次、阶段、重点都在这里
  10. 索尼a7c语言没有英语,索尼A7C的三大优点和缺点,看完再决定要不要买
  11. zone2021 E-Sneaking
  12. 使用jq简单实现导航栏切换对应展现内容
  13. 不忘初心,砥砺前行——移宇科技助力泸州市内分泌学术年会
  14. 哪个软件可以识别手写字?推荐好用的办法
  15. Oracle数据库常用语句使用记录
  16. Java练习题:算法(冒泡排序)
  17. https小灰锁(带黄色三角)如何变成安全的小绿锁
  18. matlab random 均匀分布,Matlab 的随机函数(高斯分布 均匀分布 其它分布)
  19. 互联网日报 | 7月13日 星期二 | 张近东辞任苏宁易购董事长;斗鱼虎牙宣布终止合并;联想集团二季度蝉联全球PC销量冠军...
  20. Qt读写JSON,以及使用QTreeView展示和编辑JSON数据

热门文章

  1. SparkSteaming使用
  2. 2022.6.14日新selenium写法
  3. python控制软件自动化测试,资讯详情-用python来使用Airtest 自动化工具-柠檬班-自动化测试-软件测试培训-自学官网...
  4. Java-Tcp/Ip-CS控制台聊天应用Demo
  5. CORS请求的简单请求和非简单请求
  6. WRP Ultimate 3D Endless Runner Kit - 狂徒末路跑酷角色替换教程
  7. 近世代数:同构、同态
  8. Unreal 4 更改Engine位置
  9. Selenium使用中的SSL错误
  10. 初级算法_数组 --- 有效的数独