文章目录

  • 一、前言
  • 二、思考
  • 三、实操
    • 1、Render Texture
    • 2、笔刷图案
    • 3、写脚本:DrawOn3D.cs
    • 4、ShaderGraph
    • 5、模型
    • 6、材质球
    • 7、挂脚本
  • 四、运行测试
  • 五、结束

一、前言

点关注不迷路,持续输出Unity干货文章。

嗨,大家好,我是新发,之前写了一篇文章:《ShaderGraph使用教程与各种特效案例:Unity2020》。
昨天,又有个同学问了我一个问题:

昨天太忙了,今天趁下班后的业余时间,就来讲讲这个问题吧:
如何使用Unity ShaderGraph实现在模型涂鸦的效果?

本文最终效果如下:

本文Demo工程已上传到CodeChina(最近GitHub貌似有问题,经常连不上),感兴趣的同学可自行下载学习。
CodeChina地址:https://codechina.csdn.net/linxinfa/UnityShaderGraphGraffiti
注意,我使用的Unity版本是2020.2.7f1c1ShaderGraph版本是Version 10.3.2 - March 01, 2021,如果你使用的版本比我的版本低,则可能运行我的Demo工程会有问题。

二、思考

首先,我们思考一下,实现这个功能需要解决的问题:
1 我们怎么知道鼠标点击在模型上的具体位置?
2 我们怎么在这个位置画笔刷图案?
3 我们画的图案如何与模型的主贴图融合?

第一个问题,我们可以利用摄像机射线碰撞检测来获取鼠标点击到模型上的具体位置。
用到Camera.ScreenPointToRayPhysics.Raycast接口。

第二个问题,我们可以把鼠标画的点画在一张RenderTexture上,
基于第一个问题答案,我们可以得到射线碰撞检测的RaycastHit,而RaycastHit有一个textureCoord成员变量,这个就是uv坐标,有了uv值,就可以换算出在RenderTexture图上的具体位置,再使用Graphics.DrawTexture接口在RenderTexture上画笔刷图案即可。

第三个问题,两张图片的融合,这就交给ShaderGraph来处理吧。

所以,其实这个功能的核心不是ShaderGraphShaderGraph只是做最后的图片融合处理。
当然,这只是其中一种思路,如果各位大佬有更好的方法,欢迎指出。

三、实操

1、Render Texture

首先,创建一个Render Texture

设置一下Render Texture的尺寸和格式,尺寸的大小决定我们最后画图案的精度。

我们可以看到,Render Texture默认是黑乎乎的一张图。

2、笔刷图案

photoshop做两张图,一张纯黑色的方图(用于初始化填充Render Texture),一张笔刷图,简单起见,笔刷图案我就用一个白点。
如下:

3、写脚本:DrawOn3D.cs

开始写代码,就一个脚本:DrawOn3D.cs。代码的注释我写得比较清晰了,大家应该能看懂。
代码如下:

// DrawOn3D.csusing UnityEngine;/// <summary>
/// 在3D模型上涂鸦
/// </summary>
public class DrawOn3D : MonoBehaviour
{/// <summary>/// 绘制的目标图片/// </summary>public RenderTexture rt;/// <summary>/// 笔刷/// </summary>public Texture brushTexture;/// <summary>/// 空白图/// </summary>public Texture blankTexture;/// <summary>/// 主摄像机/// </summary>public Camera cam;/// <summary>/// 模型/// </summary>public Transform modelTransform;void Start(){cam = Camera.main;DrawBlank();}// 初始化RenderTextureprivate void DrawBlank(){// 激活rtRenderTexture.active = rt;// 保存当前状态GL.PushMatrix();// 设置矩阵GL.LoadPixelMatrix(0, rt.width, rt.height, 0);// 绘制贴图Rect rect = new Rect(0, 0, rt.width, rt.height);Graphics.DrawTexture(rect, blankTexture);// 弹出改变GL.PopMatrix();RenderTexture.active = null;}// 在RenderTexture的(x,y)坐标处画笔刷图案private void Draw(int x, int y){// 激活rtRenderTexture.active = rt;// 保存当前状态GL.PushMatrix();// 设置矩阵GL.LoadPixelMatrix(0, rt.width, rt.height, 0);// 绘制贴图x -= (int)(brushTexture.width * 0.5f);y -= (int)(brushTexture.height * 0.5f);Rect rect = new Rect(x, y, brushTexture.width, brushTexture.height);Graphics.DrawTexture(rect, brushTexture);// 弹出改变GL.PopMatrix();RenderTexture.active = null;}private void Update(){if (Input.GetMouseButton(0)){Ray ray = cam.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if (Physics.Raycast(ray, out hit)){// hit.textureCoord是碰撞点的uv值,uv值是从0到1的,所以要乘以宽高才能得到具体坐标点var x = (int)(hit.textureCoord.x * rt.width);// 注意,uv坐标系和Graphics坐标系的y轴方向相反var y = (int)(rt.height - hit.textureCoord.y * rt.height);Draw(x, y);}}// 按左右方向键,旋转模型if(Input.GetKey(KeyCode.LeftArrow)){modelTransform.Rotate(0, 360 * Time.deltaTime, 0);}else if (Input.GetKey(KeyCode.RightArrow)){modelTransform.Rotate(0, -360 * Time.deltaTime, 0);}}
}

4、ShaderGraph

创建一个PBR ShaderGraph,实现模型主贴图和RenderTexture的融合。

暴露出四个变量,方便在材质球中设置参数。

5、模型

为了体现我的艺术天分,我找了个手模。

6、材质球

创建一个材质球HandMat,使用上面做的ShaderGraph,给材质球赋值贴图。

最后将材质赋给模型。

7、挂脚本

DrawOn3D脚本挂到Main Camera上,并设置好参数。
RtRender Texture,用于画图案;
Brush Texture:笔刷图案,一个白点;
Blank Texture:一张纯黑色的空白图;
Cam:主摄像机,用于做射线检测;
Module Transform:用于旋转模型。

四、运行测试

运行Unity,测试效果如下:

可以通过材质球调节图案颜色和透明度。

五、结束

写完了,现在是23:01,收拾睡觉,大家晚安。

【游戏开发创新】使用Unity ShaderGraph实现在模型上涂鸦的效果,那么,纹个手吧相关推荐

  1. 【游戏开发创新】Unity+人工智能,让小朋友的画成真,六一儿童节一起来画猫猫吧(Unity | 人工智能 | 绘图 | 爬虫 | 猫妖)

    文章目录 一.前言 二.一起来画猫猫 三.爬虫,无穷只猫 四.猫猫作品展 五.Unity制作讲解 1.界面素材 2.UGUI制作界面 3.分辨率适配 4.如何检测鼠标事件 5.世界坐标转局部坐标 6. ...

  2. 【游戏开发渲染】Unity ShaderGraph使用教程与各种特效案例:Unity2022(持续更新)

    文章目录 一.ShaderGraph前言 二.ShaderGraph科普 1.渲染管线(Render Pipline) 2.可编程渲染管线,SRP(Scriptable Render Pipline) ...

  3. 【游戏开发实战】Unity ShaderGraph 2D描边效果、不规则描边效果

    文章目录 一.前言 二.2D描边效果 1.导入一张png素材图片 2.创建一个Unlit Graph 3.使用Sample Texture 2D采样图片 4.显示描边的思路 5.使用Tilling A ...

  4. 【游戏开发实战】Unity ShaderGraph实现图片的高斯模糊效果

    文章目录 一.前言 二.最终效果 三.高斯模糊的原理 四.ShaderGraph的高斯模糊实现 一.前言 之前我写了一篇文章:ShaderGraph使用教程与各种特效案例:Unity2020 有网友私 ...

  5. 【游戏开发创新】Unity 2D图片任意形状破碎碎裂效果,以此纪念我的牙光荣牺牲

    文章目录 一.前言 二.效果演示 三.Demo工程下载 四.操作步骤 1.牙图片:SrpiteRenderer 2.碎裂:Explodable 3.多边形碰撞体组件:PolygonCollider2D ...

  6. 【游戏开发进阶】带你玩转模型法线,实验一下大胆的想法(法线贴图 | shader | Unity | python | 爬虫)

    文章目录 一.前言 二.直观感受法线贴图 三.表面法线 1.表面法线的概念 2.空间与坐标系 2.1.世界空间--世界坐标系 2.2.局部空间--局部坐标系 2.3.切线空间--切线坐标系 2.4.小 ...

  7. 【游戏开发实战】Unity手游第一人称视角,双摇杆控制,FPS射击游戏Demo(教程 | 含Demo工程源码)

    文章目录 一.前言 二.实现方案 1.无主之地,第一人称视角 2.我之前做的摇杆控制 3.第一人称视角 + 摇杆控制 三.开始实战 1.资源获取:Unity AssetStore 2.Low Poly ...

  8. 【游戏开发教程】Unity Cinemachine快速上手,详细案例讲解(虚拟相机系统 | 新发出品 | 良心教程)

    文章目录 一.前言 二.插件下载 三.案例1:第三人称自由视角,Free Look character场景 1.场景演示 2.组件参数 2.1.CinemachineBrain:核心 2.2.Cine ...

  9. 【游戏开发教程】Unity Cinemachine快速上手,详细案例讲解(虚拟相机系统 新发出品 良心教程)

    文章目录 一.前言 二.插件下载 三.案例1:第三人称自由视角,Free Look character场景 1.场景演示 2.组件参数 2.1.CinemachineBrain:核心 2.2.Cine ...

最新文章

  1. 【转】摄像头编程实例
  2. Python标准模块--asyncio
  3. Winform 绘制圆形的图片
  4. 苹果电脑macbook怎样强制关闭软件
  5. 图解Linux的Socket
  6. 第八九章 正态分布与超越正态
  7. css过渡transition
  8. inx的c语言表达式,Spninx 解决的问题
  9. js 动态拼接html 正则,在JavaScript中使用动态(可变)字符串作为正则表达式模式...
  10. A Quantization-Friendly Separable Convolution for MobileNets
  11. timer控件的使用
  12. pg_upgrade升级数据库9.1.1-9.4.5
  13. python3 数据结构_python系列十一:python3数据结构
  14. 通过一段代码发现 emu8086 和 DOSBox 的一点区别
  15. 数学建模大赛准备方法及资源分享
  16. GMM-HMM 详解
  17. matlab 相机焦距,matlab – 给定焦距和摄像机位置/旋转的正确透视图像
  18. ELK 可视化分析热血电影《长津湖》15万+影评
  19. cs1.6服务器修改游戏类型,如何自己架设CS1.6服务器?
  20. sox处理mp3_sox :音频文件转换命令

热门文章

  1. FLANN 快速特征匹配
  2. 以色列摩萨德针对伊朗核设施进行破坏性网络攻击导致断电
  3. 计算机开机后桌面放大,win10系统电脑重启后桌面图标变大的修复方法
  4. 基于Qt的图像处理技术和算法(灰度、暖色、冷色、模糊、锐化、添加相框纹理)
  5. Mercer's Theorem的证明
  6. 前端面试整理JavaScript
  7. C#中的群集, 泛型和计时类
  8. 蓝桥杯基础视频 笔记
  9. 台达vfd-m变频器配合mcgs恒压供水资料
  10. 关于POE供电的优缺点