7.Fragment Shaders and Grab Passes
-
vertex and fragment shader
-
对光照如何影响物体表面不感兴趣,不受物理限制,对非真实感的效果很好
-
使用#pragma指令来关联两个函数
#pragma vertex vert
#pragma fragment frag
-
往往使用vertInput和vertOutput结构体做参数传递,Unity负责初始化输入,我们负责初始化输出(结构体的每个字段都使用绑定语义)
-
-
绑定语义
- 允许我们用绑定语义来标记变量,于是这些变量会自动的被某些数据初始化,如法向量、顶点位置等
- Input 语义:POSITION/SV_POSITON、NORMAL、COLOR/COLOR0/DIFFUSE、COLOR1/SPECULAR、SV_TARGET、TEXCOORD0/TEXCOORD1/TEXCOORDi
- Output语义:POSITION/SV_POSITON/HPOS、COLOR/COLOR0/COL0/SV_TARGET、COLOR1/COL1、TEXCOORD0/TEXCOORD1/TEXCOORDi/TEXi、WPOS
- 举例:float4 vertex : POSITION;
-
抓取通道Grab Pass
-
在一个着色器中使用两个通道1-GrabPass 2-Pass
-
Grab Pass会自动创建一个纹理 (访问到目前为止在屏幕上绘制的内容)
GrabPass{ }
-
在vert中,计算出GrabPass的UV
o.uvgrab = ComputeGrabScreenPos(o.vertex);
-
在frag中对纹理进行取样
fixed4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
-
GrabPass是非常昂贵的操作,在游戏中该实例的数量需要受到限制
优化:使用GrabPass{ “_GrabTexture” }
为纹理命名,并可以对用到该名称的所有GrabPass共享该纹理(不允许叠加效果)
-
-
制作窗户材质
-
实现透过窗户时的扭曲变形效果:使用带GrabPass的着色器,对抓取纹理进行取样,并对UV数据做一定的改变
-
使用一张法线贴图,把它加到UV数据上即可
half2 distortion = UnpackNormal(bump).rg;
i.uvgrab.xy += distortion * _Magnitude;
fixed4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
-
-
制作2D水材质
-
与窗户材质对比,只是将UV的偏移从固定的法线贴图获取改为用正弦波、时间和噪声纹理来生成
-
float sinT = sin(_Time.w / _Period);
float distX = tex2D(_NoiseTex, i.worldPos.xy / _Scale + float2(sinT, 0) ).r - 0.5;
float distY = tex2D(_NoiseTex, i.worldPos.xy / _Scale + float2(0, sinT) ).r - 0.5;
float2 distortion = float2(distX, distY);
i.uvgrab.xy += distortion * _Magnitude;
fixed4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
-