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

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

使用Python快速实现链接转word文档

《使用Python快速实现链接转word文档》这篇文章主要为大家详细介绍了如何使用Python快速实现链接转word文档功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 演示代码展示from newspaper import Articlefrom docx import

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2