阿赵的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 Back
CGPROGRAM
#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