Unity可视化Shader工具ASE介绍——7、ASE实现Matcap效果和自定义节点

本文主要是介绍Unity可视化Shader工具ASE介绍——7、ASE实现Matcap效果和自定义节点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  大家好,我是阿赵。继续介绍Unity可视化Shader编辑工具ASE。上一篇用了很长的篇幅来做了一个遮挡X光的效果。这一篇来做一个MatCap效果。不过做MatCap并不是目的,是想说明一下,怎样在ASE里面自定义方法节点。

一、在ASE里面做MatCap材质

  由于在上一篇里面说得比较详细,所以一些小操作在这一篇就不会很啰嗦,稍微说得快一点。
  先把上一篇的模型找出来,然后建一个叫做Matcap的Unlit模板shader。然后把之前的漫反射贴图部分的节点拷贝过来。于是现在有了这样的效果:
在这里插入图片描述

  在这个基础上,继续做MatCap效果。
  MatCap效果的原理是normalView.xy*0.5+0.5,然后作为UV坐标采样MatCap贴图。如果不明白原理,可以在我的CSDN博客搜索一下,有2篇文章专门说明了MatCap的做法,这里就不重复了。
  先来获得观察空间的法线方向:
在这里插入图片描述

  然后乘以0.5再加上0.5
在这里插入图片描述

  建一个贴图采样节点,命名为matcapTex,然后把刚才算出的uv值连到matcapTex的uv入口
在这里插入图片描述

  最后,把原来的漫反射颜色,加上matcapTex的颜色,输入到FragColor
在这里插入图片描述

  这时候,这个 Shader已经做完了,保存Shader,然后在材质球赋予一张MatCap贴图:
在这里插入图片描述

  这时候模型就已经有了MatCap效果了
在这里插入图片描述

  为了可以控制MatCap的范围和强度,增加两个参数,用先乘再power的方式连接
在这里插入图片描述

  通过控制这两个参数,就能调整MatCap的效果。
在这里插入图片描述

二、自定义节点

   在模拟假高光效果的时候,MatCap算是一个很常用的效果。但如果每次都需要像上面的例子一样连接一次MatCap效果,感觉很麻烦。如果能把MatCap做出一个节点就好了。
   这是可以的,接下来看看怎样实现把自己的效果做成自定义节点。
   先创建一个Amplify Shader Function。
在这里插入图片描述

   这里我命名为azhapMatCap。建好之后,打开的效果和新建一个Shader时差不多, 只有一个输出节点。
在这里插入图片描述

   接下来回到之前做的MatCap的Shader里面,稍微修改一下,把输入的Matcap贴图从TextureSampler改成新增一个TextureObject来输入。
在这里插入图片描述

  然后把这些和MatCap相关的节点全部选择,ctrl+c复制。
在这里插入图片描述

  然后到新建的自定义节点azhaoMatCap里面,把这些节点复制进去,并把输出的结果连接到output里面。
在这里插入图片描述

  我们来思考一下,一个节点一般会有输入和输出,现在输出有了,我们需要输入哪些参数才能让这个节点可以自由控制呢?这个例子有这些参数可以输入:
1.MatCap贴图
2.WorldNormal世界法线方向
3.MatCapIntensity控制MatCap的强度
4.MatCapPow控制MatCap的范围
  于是开始修改这个自定义节点。搜索input,可以找到Function Input节点
在这里插入图片描述

  选择这个输入节点,在属性栏里面可以看到,可以修改属性的名称,还有类型。
在这里插入图片描述
  这个新建的输入节点我打算用来做MatCap贴图的输入,所以我把名字改成matcapTex,然后把类型改成Sampler2D,并把原来的TextureObject节点删掉,用这个输入节点代替,连接到TextureSampler节点。
在这里插入图片描述

  接下来,按照设想,通过新建3个输入节点,把worldNormal、MatCapIntensity和MatCapPowMatCapPow替代了。
在这里插入图片描述

  接下来,保存这个节点。然后回到之前做的MatCap的shader节点编辑界面。
  右键搜索azhaoMatCap,可以看到已经有刚才新建的节点可以选择了
在这里插入图片描述
在这里插入图片描述

  可以看到这个节点,有4个输入,一个输出。那四个输入的,就是我们刚才新建的Input节点了。把之前的代码删掉,然后输入这个四个节点,并把output输入到之前的结果里面。
在这里插入图片描述

  发现得到的结果和之前一样的。所以这个节点是成功的。
在这里插入图片描述

  接下来有一些优化的空间:
  现在返回的节点只有一个output,首先output这个名字比较不好看,不清楚含义,然后有些节点可以有多个输出,这是怎样实现?
  回到自定义节点azhaoMatCap,选择output,发现在属性栏可以改名字的,所以我这里把它改成RGBA。
  然后再新建4个Output节点,命名为R、G、B、A,然后把前一步的结果用BreakToComponent拆分,连接到RGBA四个输出节点:
在这里插入图片描述在这里插入图片描述

  保存节点,回去MatCap编辑界面看看
在这里插入图片描述

  发现刚才新增的输出接口都出现了。不过接口的顺序不太好看。其实这些输入和输出的接口顺序可以在自定义节点的下面指定顺序
在这里插入图片描述

  调整一下顺序
在这里插入图片描述

  然后节点的接口顺序就被调整过来了
在这里插入图片描述

  到这里,这个azhaoMatCap的自定义节点就做完了。下次如果想复用MatCap效果,就可以直接创建这个节点,不需要重复拖节点了。
  最后给一下这个自定义节点的源码,只要在项目内新建一个文本,把源码拷贝进去,然后重命名为azhaoMatCap.asset,应该就能变成自定义节点,可以打开编辑或者使用:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:m_ObjectHideFlags: 0m_CorrespondingSourceObject: {fileID: 0}m_PrefabInstance: {fileID: 0}m_PrefabAsset: {fileID: 0}m_GameObject: {fileID: 0}m_Enabled: 1m_EditorHideFlags: 0m_Script: {fileID: 11500000, guid: 78b2425a2284af743826c689403a4924, type: 3}m_Name: azhaoMatCapm_EditorClassIdentifier: m_functionInfo: "// Made with Amplify Shader Editor\n// Available at the UnityAsset Store - http://u3d.as/y3X \n/*ASEBEGIN\nVersion=18500\n195;310;1661;651;955.3268;334.6914;1.3;True;True\nNode;AmplifyShaderEditor.ViewMatrixNode;2;-1489.023,-20.07257;Inherit;False;0;1;FLOAT4x4;0\nNode;AmplifyShaderEditor.FunctionInput;13;-1073.171,-170.9945;Inherit;False;matcapTex;9;0;False;1;0;SAMPLER2D;;False;1;SAMPLER2D;0\nNode;AmplifyShaderEditor.FunctionInput;16;-354.2866,132.0066;Inherit;False;MatCapPow;1;3;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.FunctionInput;15;-615.2866,128.0066;Inherit;False;MatCapIntensity;1;2;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.FunctionInput;14;-1489.287,144.0066;Inherit;False;worldNormal;3;1;False;1;0;FLOAT3;0,0,0;False;1;FLOAT3;0\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;10;-350.9913,-9.497155;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;FLOAT;0;False;1;COLOR;0\nNode;AmplifyShaderEditor.PowerNode;11;-185.8009,-9.497064;Inherit;False;False;2;0;COLOR;0,0,0,0;False;1;FLOAT;1;False;1;COLOR;0\nNode;AmplifyShaderEditor.SimpleAddOpNode;6;-931.623,177.1276;Inherit;False;2;2;0;FLOAT3;0,0,0;False;1;FLOAT;0;False;1;FLOAT3;0\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;4;-1276.023,45.92745;Inherit;False;2;2;0;FLOAT4x4;0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1;False;1;FLOAT3;0,0,0;False;1;FLOAT3;0\nNode;AmplifyShaderEditor.RangedFloatNode;3;-1234.923,254.1276;Inherit;False;Constant;_Float0;Float0;2;0;Create;True;0;0;False;0;False;0.5;0;0;0;0;1;FLOAT;0\nNode;AmplifyShaderEditor.SamplerNode;8;-784.1555,-96.65796;Inherit;True;Property;_matcapTex;matcapTex;2;0;Create;True;0;0;False;0;False;-1;None;d1adcd85d9c7bc646a30b7c1e4bb684b;True;0;False;black;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4\nNode;AmplifyShaderEditor.BreakToComponentsNode;22;-41.42676,108.6085;Inherit;False;COLOR;1;0;COLOR;0,0,0,0;False;16;FLOAT;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4;FLOAT;5;FLOAT;6;FLOAT;7;FLOAT;8;FLOAT;9;FLOAT;10;FLOAT;11;FLOAT;12;FLOAT;13;FLOAT;14;FLOAT;15\nNode;AmplifyShaderEditor.SimpleMultiplyOpNode;5;-1079.223,91.12754;Inherit;False;2;2;0;FLOAT3;0,0,0;False;1;FLOAT;0;False;1;FLOAT3;0\nNode;AmplifyShaderEditor.FunctionOutput;18;198.4805,-42.67558;Inherit;False;False;-1;R;1;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.FunctionOutput;19;200.8805,38.9244;Inherit;False;False;-1;G;2;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.FunctionOutput;21;197.7805,215.4245;Inherit;False;False;-1;A;4;False;1;0;FLOAT;0;False;1;FLOAT;0\nNode;AmplifyShaderEditor.FunctionOutput;0;182.2821,-166.8074;Inherit;False;True;-1;RGBA;0;False;1;0;COLOR;0,0,0,0;False;1;COLOR;0\nNode;AmplifyShaderEditor.FunctionOutput;20;197.0805,133.7243;Inherit;False;False;-1;B;3;False;1;0;FLOAT;0;False;1;FLOAT;0\nWireConnection;10;0;8;0\nWireConnection;10;1;15;0\nWireConnection;11;0;10;0\nWireConnection;11;1;16;0\nWireConnection;6;0;5;0\nWireConnection;6;1;3;0\nWireConnection;4;0;2;0\nWireConnection;4;1;14;0\nWireConnection;8;0;13;0\nWireConnection;8;1;6;0\nWireConnection;22;0;11;0\nWireConnection;5;0;4;0\nWireConnection;5;1;3;0\nWireConnection;18;0;22;0\nWireConnection;19;0;22;1\nWireConnection;21;0;22;3\nWireConnection;0;0;11;0\nWireConnection;20;0;22;2\nASEEND*/\n//CHKSM=10A9D6D01C6AE2DB216075889F902D5308EDF5B1"m_functionName: m_description: m_additionalIncludes:m_additionalIncludes: []m_outsideIncludes: []m_additionalPragmas:m_additionalPragmas: []m_outsidePragmas: []m_additionalDirectives:m_validData: 0m_isDirty: 0m_moduleName: ' Additional Directives'm_independentModule: 1m_additionalDirectives: []m_shaderFunctionDirectives: []m_nativeDirectives: []m_nativeDirectivesIndex: -1m_nativeDirectivesFoldout: 0m_directivesSaveItems: []m_nodeCategory: 3m_customNodeCategory: m_previewPosition: 0m_hidden: 0

这篇关于Unity可视化Shader工具ASE介绍——7、ASE实现Matcap效果和自定义节点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/217202

相关文章

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

MYSQL查询结果实现发送给客户端

《MYSQL查询结果实现发送给客户端》:本文主要介绍MYSQL查询结果实现发送给客户端方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql取数据和发数据的流程(边读边发)Sending to clientSending DataLRU(Least Rec

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

使用SpringBoot整合Sharding Sphere实现数据脱敏的示例

《使用SpringBoot整合ShardingSphere实现数据脱敏的示例》ApacheShardingSphere数据脱敏模块,通过SQL拦截与改写实现敏感信息加密存储,解决手动处理繁琐及系统改... 目录痛点一:痛点二:脱敏配置Quick Start——Spring 显示配置:1.引入依赖2.创建脱敏

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

如何自定义一个log适配器starter

《如何自定义一个log适配器starter》:本文主要介绍如何自定义一个log适配器starter的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求Starter 项目目录结构pom.XML 配置LogInitializer实现MDCInterceptor

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)

《MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)》掌握多表联查(INNERJOIN,LEFTJOIN,RIGHTJOIN,FULLJOIN)和子查询(标量、列、行、表子查询、相关/非相关、... 目录第一部分:多表联查 (JOIN Operations)1. 连接的类型 (JOIN Types)

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流