22.01.23 《Unity 2018 Shaders and Effects Cookbook》笔记Chapter7

7.Fragment Shaders and Grab Passes

  1. vertex and fragment shader

    1. 对光照如何影响物体表面不感兴趣,不受物理限制,对非真实感的效果很好

    2. 使用#pragma指令来关联两个函数

      #pragma vertex vert

      #pragma fragment frag

    3. 往往使用vertInput和vertOutput结构体做参数传递,Unity负责初始化输入,我们负责初始化输出(结构体的每个字段都使用绑定语义)

  2. 绑定语义

    1. 允许我们用绑定语义来标记变量,于是这些变量会自动的被某些数据初始化,如法向量、顶点位置等
    2. Input 语义:POSITION/SV_POSITON、NORMAL、COLOR/COLOR0/DIFFUSE、COLOR1/SPECULAR、SV_TARGET、TEXCOORD0/TEXCOORD1/TEXCOORDi
    3. Output语义:POSITION/SV_POSITON/HPOS、COLOR/COLOR0/COL0/SV_TARGET、COLOR1/COL1、TEXCOORD0/TEXCOORD1/TEXCOORDi/TEXi、WPOS
    4. 举例:float4 vertex : POSITION;
  3. 抓取通道Grab Pass

    1. 在一个着色器中使用两个通道1-GrabPass 2-Pass

    2. Grab Pass会自动创建一个纹理 (访问到目前为止在屏幕上绘制的内容)

      GrabPass{ }

    3. 在vert中,计算出GrabPass的UV

      o.uvgrab = ComputeGrabScreenPos(o.vertex);

    4. 在frag中对纹理进行取样

      fixed4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));

    5. GrabPass是非常昂贵的操作,在游戏中该实例的数量需要受到限制

      优化:使用GrabPass{ “_GrabTexture” }

      为纹理命名,并可以对用到该名称的所有GrabPass共享该纹理(不允许叠加效果)

  4. 制作窗户材质

    1. 实现透过窗户时的扭曲变形效果:使用带GrabPass的着色器,对抓取纹理进行取样,并对UV数据做一定的改变

    2. 使用一张法线贴图,把它加到UV数据上即可

      half2 distortion = UnpackNormal(bump).rg;

      i.uvgrab.xy += distortion * _Magnitude;

      fixed4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));

  5. 制作2D水材质

    1. 与窗户材质对比,只是将UV的偏移从固定的法线贴图获取改为用正弦波、时间和噪声纹理来生成

    2. 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));

你可能感兴趣的:(CG,unity,游戏引擎,mesh)