Unity可视化Shader工具ASE介绍——10、ASE实现曲面细分

2024-03-15 00:50

本文主要是介绍Unity可视化Shader工具ASE介绍——10、ASE实现曲面细分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

阿赵的Unity可视化Shader工具ASE介绍目录
  大家好,我是阿赵。
  之前介绍地面交互的时候,介绍了曲面细分着色器的使用。这个过程,在ASE里面也是可以实现的。关于曲面细分的具体作用,这里就不再重复,如果有兴趣了解可以看看我的地面交互系列的博文。

一、通过选项开启曲面细分

  在ASE里面,只有Surface类型的模板支持曲面细分,所以先建一个Surface模板的Shader
在这里插入图片描述

  先来看这个地方,在OutputNode里面,有一个Tessellation的选项,把它勾选上,然后用这个shader创建一个材质球,赋给地面,就会看到地面已经出现了细分了。
在这里插入图片描述

  之前介绍曲面细分的Surface类型着色器写法的时候,介绍过,Surface类型里面内置了3种方式的曲面细分实现方法,分布是Fixed、DistanceBased和EdgeLength。在ASE里面,也可以选择这些类型来实现:
在这里插入图片描述

  在勾选了之后,默认选择的是EdgeLength方式,也就是以边的长度来细分。可以手段选择其他的类型。

1、Fixed方式细分

在这里插入图片描述

  如果改成Fixed,下面的参数会变成Tess,实际上就是细分的固定数值了。
  然后上面有一个Phong的选项,Phone细分是一种会沿着法线方向做细分的方式,如果开启了之后,模型会圆滑,如果不开启,则是在原有的三角面的基础上做细分,不会改变基础形状,会比较有棱有角。
在这里插入图片描述

2、DistanceBased方式细分

在这里插入图片描述

  如果选择了DistanceBased细分方式,除了Tess参数以外,还会多了Min和Max两个数值,用于控制距离范围。

在这里插入图片描述

3、EdgeLength方式细分

在这里插入图片描述

  选择这种方式之后,参数会变成EdgeLength

在这里插入图片描述

  如果选择EdgeLengthCull,那么还会有一个MaxDisp参数,代表的是Max DisplaceMent

二、通过节点连线实现曲面细分

  用上面的方式实现曲面细分,会有一个问题,由于参数都是固定输入了,不能很灵活的去修改。
  所以ASE也可以通过节点来指定曲面细分的参数的。
在这里插入图片描述

  在输出模块的节点上面,可以看到Tessellation的输入接口。
在这里插入图片描述

  搜索一下节点,可以看到,刚才介绍的几种方式基本都有对应的节点。

1、Fixed方式:

  Fixed方式不需要节点,直接输入数值就行了。
在这里插入图片描述

  注意看,如果我们连了节点到Tessellation上面,之前在输出节点属性里面的Tessellation选项就会变成灰色,不可以再编辑参数了,但Phong选项还在。
在这里插入图片描述

2、DistanceBased方式

  如果通过距离控制:
在这里插入图片描述
在这里插入图片描述

  这样就可以在材质球上面控制这些参数了。

3、EdgeLength方式

  根据边长
在这里插入图片描述

4、EdgeLengthCull方式

在这里插入图片描述

三、动态计算曲面细分范围

  上面用节点的方式可以解决固定参数的问题,可以在材质球上面修改参数。但其实也不太灵活,只是能改参数,实现不了很多效果。
  这里来讲一下怎样实现更复杂的效果,比如我连了这么一个线:
在这里插入图片描述

  现在的效果是:
在这里插入图片描述

  这个计算结果得到的是,指定一个中心点和半径,然后在范围内做曲面细分。那么剩下的问题就比较简单了,用这个计算出来的值,连线给Tessellation就行。
在这里插入图片描述

  但保存之后,并没有出现我们想要的结果,发现Shader报错了
在这里插入图片描述

  打开生成的Shader看看,可以发现问题:
在这里插入图片描述

  在细分的函数里面,传入了v0、v1、v2三个点,但下面却是使用了v.vertex,这里v并没有定义。
  既然这样,可以分开三个点分别计算距离,或者三个点求平均值再计算距离。我这里就简单的使用平均值:
在这里插入图片描述

  修改完之后,效果就出来了。
在这里插入图片描述

四、源码

  也不算什么源码,给一下最后ASE生成的Shader源码,有兴趣的朋友可以通过ASE编辑器打开看看节点的连接方式:

// Made with Amplify Shader Editor
// Available at the Unity Asset Store - http://u3d.as/y3X 
Shader "ASETessellation"
{Properties{_max("max", Float) = 1_min("min", Float) = 0_tessVal("tessVal", Float) = 1_range("range", Float) = 1_centerPos("centerPos", Vector) = (0,0,0,0)[HideInInspector] __dirty( "", Int ) = 1}SubShader{Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry+0" }Cull BackCGPROGRAM#include "Tessellation.cginc"#pragma target 4.6#pragma surface surf Standard keepalpha addshadow fullforwardshadows vertex:vertexDataFunc tessellate:tessFunction struct Input{float3 worldPos;};uniform float _min;uniform float _max;uniform float3 _centerPos;uniform float _range;uniform float _tessVal;float4 tessFunction( appdata_full v0, appdata_full v1, appdata_full v2 ){float3 vert = (v0.vertex + v1.vertex + v2.vertex) / 3;float3 ase_worldPos = mul( unity_ObjectToWorld, vert );float4 appendResult14 = (float4(ase_worldPos , 0.0));float smoothstepResult22 = smoothstep( _min , _max , ( 1.0 - ( distance( float4( _centerPos , 0.0 ) , appendResult14 ) / _range ) ));float4 temp_cast_1 = (( max( saturate( smoothstepResult22 ) , 0.01 ) * _tessVal )).xxxx;return temp_cast_1;}void vertexDataFunc( inout appdata_full v ){}void surf( Input i , inout SurfaceOutputStandard o ){o.Alpha = 1;}ENDCG}Fallback "Diffuse"CustomEditor "ASEMaterialInspector"
}
/*ASEBEGIN
Version=18500
0;0;1920;1019;1799.171;493.4954;1.3;True;True
Node;AmplifyShaderEditor.WorldPosInputsNode;12;-1200.876,90.80692;Inherit;False;0;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.Vector3Node;11;-1175.583,-133.3799;Inherit;False;Property;_centerPos;centerPos;4;0;Create;True;0;0;False;0;False;0,0,0;0,0,0;0;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.DynamicAppendNode;14;-986.2843,80.69485;Inherit;False;FLOAT4;4;0;FLOAT3;0,0,0;False;1;FLOAT;0;False;2;FLOAT;0;False;3;FLOAT;0;False;1;FLOAT4;0
Node;AmplifyShaderEditor.DistanceOpNode;13;-796.7131,9.478409;Inherit;False;2;0;FLOAT3;0,0,0;False;1;FLOAT4;0,0,0,0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;16;-818.4869,167.191;Inherit;False;Property;_range;range;3;0;Create;True;0;0;False;0;False;1;10;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleDivideOpNode;21;-658.8125,78.10852;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;23;-620.457,190.956;Inherit;False;Property;_min;min;1;0;Create;True;0;0;False;0;False;0;0;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;24;-628.964,288.5267;Inherit;False;Property;_max;max;0;0;Create;True;0;0;False;0;False;1;2.51;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.OneMinusNode;17;-575.0996,-24.93669;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SmoothstepOpNode;22;-467.9477,49.72478;Inherit;False;3;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;1;False;1;FLOAT;0
Node;AmplifyShaderEditor.SaturateNode;18;-280.739,67.37544;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;26;-290.9912,142.4471;Inherit;False;Constant;_Float0;Float 0;6;0;Create;True;0;0;False;0;False;0.01;0;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMaxOpNode;25;-147.9912,87.44708;Inherit;False;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;19;-329.5429,269.0027;Inherit;False;Property;_tessVal;tessVal;2;0;Create;True;0;0;False;0;False;1;15;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;20;-154.6485,251.0924;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.StandardSurfaceOutputNode;0;0,0;Float;False;True;-1;6;ASEMaterialInspector;0;0;Standard;ASETessellation;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;Back;0;False;-1;0;False;-1;False;0;False;-1;0;False;-1;False;0;Opaque;0.5;True;True;0;False;Opaque;;Geometry;All;14;all;True;True;True;True;0;False;-1;False;0;False;-1;255;False;-1;255;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;True;3;15;10;25;False;0.5;True;0;0;False;-1;0;False;-1;0;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;0;0,0,0,0;VertexOffset;True;False;Cylindrical;False;Relative;0;;-1;-1;-1;2;0;False;0;0;False;-1;-1;0;False;-1;0;0;0;False;0.1;False;-1;0;False;-1;False;16;0;FLOAT3;0,0,0;False;1;FLOAT3;0,0,0;False;2;FLOAT3;0,0,0;False;3;FLOAT;0;False;4;FLOAT;0;False;5;FLOAT;0;False;6;FLOAT3;0,0,0;False;7;FLOAT3;0,0,0;False;8;FLOAT;0;False;9;FLOAT;0;False;10;FLOAT;0;False;13;FLOAT3;0,0,0;False;11;FLOAT3;0,0,0;False;12;FLOAT3;0,0,0;False;14;FLOAT4;0,0,0,0;False;15;FLOAT3;0,0,0;False;0
WireConnection;14;0;12;0
WireConnection;13;0;11;0
WireConnection;13;1;14;0
WireConnection;21;0;13;0
WireConnection;21;1;16;0
WireConnection;17;0;21;0
WireConnection;22;0;17;0
WireConnection;22;1;23;0
WireConnection;22;2;24;0
WireConnection;18;0;22;0
WireConnection;25;0;18;0
WireConnection;25;1;26;0
WireConnection;20;0;25;0
WireConnection;20;1;19;0
WireConnection;0;14;20;0
ASEEND*/
//CHKSM=CB82F0A63384ACEE4428BD338EEB87DE1C372740

这篇关于Unity可视化Shader工具ASE介绍——10、ASE实现曲面细分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

Nexus安装和启动的实现教程

《Nexus安装和启动的实现教程》:本文主要介绍Nexus安装和启动的实现教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Nexus下载二、Nexus安装和启动三、关闭Nexus总结一、Nexus下载官方下载链接:DownloadWindows系统根

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

MySQL 横向衍生表(Lateral Derived Tables)的实现

《MySQL横向衍生表(LateralDerivedTables)的实现》横向衍生表适用于在需要通过子查询获取中间结果集的场景,相对于普通衍生表,横向衍生表可以引用在其之前出现过的表名,本文就来... 目录一、横向衍生表用法示例1.1 用法示例1.2 使用建议前面我们介绍过mysql中的衍生表(From子句

MybatisPlus service接口功能介绍

《MybatisPlusservice接口功能介绍》:本文主要介绍MybatisPlusservice接口功能介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录Service接口基本用法进阶用法总结:Lambda方法Service接口基本用法MyBATisP

Mybatis的分页实现方式

《Mybatis的分页实现方式》MyBatis的分页实现方式主要有以下几种,每种方式适用于不同的场景,且在性能、灵活性和代码侵入性上有所差异,对Mybatis的分页实现方式感兴趣的朋友一起看看吧... 目录​1. 原生 SQL 分页(物理分页)​​2. RowBounds 分页(逻辑分页)​​3. Page

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