【猫猫的Unity Shader之旅】之扭曲模型

  之前我们介绍的一些Shader效果都是在surf函数中做文章,也就是对渲染过程中的片段进行操作,实现的是模型表面的一些显示效果。然而,Unity Shader还提供对顶点阶段进行控制,来实现顶点的位置,颜色,法线等信息的修改。

一个简单的例子

  之前我们给过一个完整的Shader,用#pragma可以指定顶点函数。我们可以写一个简单的顶点函数,它什么也没有做:

Shader “Custom/VertShader” {Properties {_MainTex (“Base (RGB)”, 2D) = “white” {}}SubShader {Tags { “RenderType”=”Opaque” }LOD 200CGPROGRAM#pragma surface surf Lambert vertex:MyVertsampler2D _MainTex;struct Input {float2 uv_MainTex;};void MyVert(inout appdata_full v, out Input IN){}void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);o.Albedo = c.rgb;o.Alpha = c.a;}ENDCG}FallBack “Diffuse”}

  这时可能会出现这样的错误:

  

  这主要是Shader的默认渲染目标是DirectX 11,必须手动初始化Input。我们可以在Edit->Project Setting->Player界面设置,选择Other Setting,可以找到use Direct3D 11的选项。如果我们不想改或者确实需要Direct3D 11,也可以直接用Unity给的方式初始化一下:

void MyVert(inout appdata_full v, out Input IN){UNITY_INITIALIZE_OUTPUT(Input, IN);}

  另一个需要注意的地方是appdata_full类型,它是在UnityCG.cginc中定义的一个结构体:

struct appdata_full {float4 vertex : POSITION;float4 tangent : TANGENT;float3 normal : NORMAL;float4 texcoord : TEXCOORD0;float4 texcoord1 : TEXCOORD1;fixed4 half4 texcoord2 : TEXCOORD2;half4 texcoord3 : TEXCOORD3;half4 texcoord4 : TEXCOORD4;half4 texcoord5 : TEXCOORD5;#endif};

  可以看到这个结构体实际定义了许多和模型信息有关的变量,冒号后面的信息被称作语义,简单来说就是表示这个变量究竟代表什么东西。这就像大家都是人,为啥人家就是司令我们就是小兵呢,这背后的东西就是语义。

扭动吧,模型!

  顶点函数给了我们很大的自由操作的空间,appdata_full变量v被标记为inout,表示我们既可以用里面的信息也可以修改它,这里面的信息修改了,,就相当于模型传进来的信息都被改掉了。我们还可以通过修改Input中的值传递给surf函数。

Shader “Custom/VertShader” {Properties {_MainTex (“Base (RGB)”, 2D) = “white” {}}SubShader {Tags { “RenderType”=”Opaque” }LOD 200Cull OffCGPROGRAM#pragma surface surf Lambert vertex:MyVertsampler2D _MainTex;struct Input {float2 uv_MainTex;float4 vertCol;};void MyVert(inout appdata_full v, out Input IN){UNITY_INITIALIZE_OUTPUT(Input, IN);v);float absh = abs(v= float4(absh, absh, absh, 1.0);}void surf (Input IN, inout SurfaceOutput o) {half4 c = tex2D (_MainTex, IN.uv_MainTex);o* c.rgb;o.Alpha = c.a;}ENDCG}FallBack “Diffuse”}

  上面代码实现了一个平面扭动的效果:

  

  我们首先在vert函数中修改了模型顶点的y值,实现了y值随时间变化的效果(可以回忆一下UV动画),同时将Input中的顶点颜色赋值。在surf中,对vert传入的颜色,计算出片段颜色。需要注意的是我们有一句Cull Off,它是在CGPROGRAM和CGEND外面的,也就是说它不是Cg代码。那么这句是做什么的呢?默认情况下,网格的背面是不会被绘制的(因为一般情况下看不见),但是我们这个例子中,当平面扭动的时候可以看到网格背面。如果没有Cull Off,就会看到网格背面是透明的,Cull Off就是关闭隐藏表面消除。

结束语

  在Surface Shader的使用中,很多人都只把视线集中在surf函数中。诚然,surf是很重要的,由于是逐片段的处理,效果也是比较好的。然而,代价就是会造成效率问题。很多计算,既可以放在顶点阶段,也可以放在片段阶段,效率不同,效果也有很大差异,这中间的取舍,就需要各位慢慢衡量了。

无做什么,记得为自己而做,那就毫无怨言。

【猫猫的Unity Shader之旅】之扭曲模型

相关文章:

你感兴趣的文章:

标签云: