ue3dUnity制作故障和线框流动效果

Unity制作故障和线框流动效果

分类:
ue3d - Unity制作故障和线框流动效果

这个Unity特效严格意义上讲并不是一个真正的线框着色器,但它是一个技巧,一个可以帮助大家延伸思维的内容。

图中它将网格将被顶点位移分割,并且通过向背面添加颜色,线框效果是非常酷的。

该效果在 Shader Graph 中完成,有关更深入的信息,请查看带注释的代码

法线设置
法线设置

该效果不会真正适用于平滑法线,大家可以在 Unity 中网格的导入设置中将法线设置为硬。

此外,还需要在相机上启用 DepthTexture

示例设置:

示例效果
示例效果

带注释的代码:

Shader "Custom/GlitchWireframeEffect"
{
  Properties
  {
    [Header(Vertex Displacement)]
    _Intensity ("Vertex Intensity", Range(0,1)) = 0.3
    _Width("Pulse Width", Range(0,1)) = 0.5
    _PulseFreq("Pulse Freq", Range(0,1)) = 0.2
    _Scale("Pulse Scale", Range(0,5)) = 2 
    _Speed("Speed", Range(-5,5)) = 0.3
    _Random("Random Offset", Range(0,5)) = 0.0

    [Header(Tinting)]
    _TintingBrightness("Tinting Brightness", Range(0,5)) = 1.0
    _Stretch("Stretch Tinting Gradient", Range(0,5)) = 2
    _Tinting("Albedo Tinting", Color) = (0,0,1,1)
    _Tinting2("Albedo Tinting 2", Color) = (0,0,0,1)

    [Header(Backfaces)]
    _Brightness ("Backface Brightness", Range(0,5)) = 4
    _BackfaceCol ("Backface Color", Color) = (0,0.5,1,1)
    _BackfaceCol2 ("Backface Color2", Color) = (0,1,1,1)
    _StretchBackface("Stretch BackFace Gradient", Range(0,5)) = 0.0

    [Header(Rim)]
    _RimBrightness("Rim Brightness", Range(0,20)) = 5
    _RimPower("RImPOwer", Range(0,20)) = 10
    _StretchRim("Stretch Rim Gradient", Range(0,5)) = 2
    _RimCol ("Rim Color", Color) = (1,0,1,1)
    _RimCol2 ("Rim Color 2", Color) = (1,1,1,1)

    [Header(Other)]
    _Clipping("Front Face Clipping", Range(0,1)) = 0.0
    _Distortion("Distortion", Range(0,1)) = 0.2
  }
  SubShader
  {
    Tags { "RenderType"="Opaque" "Queue"="Geometry+2"}
    LOD 200
    Cull Off
    GrabPass { "_GrabTex" }
    CGPROGRAM
    #include "UnityCG.cginc"

    
    // Physically based Standard lighting model, and enable shadows on all light types
    #pragma surface surf Simple vertex:vert addshadow 

    // Use shader model 3.0 target, to get nicer looking lighting
    #pragma target 4.0
    

    sampler2D _GrabTex;
    float4 _GrabTex_TexelSize;
    

    #pragma lighting Simple exclude_path:prepass
    inline half4 LightingSimple(SurfaceOutput s, half3 lightDir, half atten)
    {
      half4 c;
      c.rgb = s.Albedo * _LightColor0.rgb *atten; 
      c.a = s.Alpha;
      return c;
    }

    struct Input
    {
      float4 screenPos;
      float facing : VFACE;
      float3 viewDir;
      float3 worldPos;
      float glitchPosFront;
      float glitchPos;      
    };

    fixed4 _BackfaceCol2, _BackfaceCol;
    fixed4 _Tinting, _Tinting2;
    fixed4 _RimCol,_RimCol2;
    float _Intensity,_Width, _PulseFreq;
    float _Stretch, _StretchBackface, _StretchRim;
    float _Random,_Scale,_Speed;
    float _Brightness,_TintingBrightness,_RimBrightness;
    float _RimPower;
    sampler2D _CameraDepthTexture;
    float _Distortion;
    float _Clipping;

    float rand(float n)
    {
      return frac(sin(n) * 43758.5453123);
    }



    void vert (inout appdata_full v, out Input o)
    {
      UNITY_INITIALIZE_OUTPUT (Input, o);
      
      // vertex y position, with optional randomness
      float randomPos = (rand(v.texcoord.x) * _Random ) + (v.vertex.y * _Scale);
      float moveSpeed = _Time.y * _Speed;

      // repeat position on model, and move it up/down
      float glitchPos = frac((randomPos +moveSpeed ) * _PulseFreq)  ;// position on model
      
      // clamp the width with a smoothstep
      float glitchPosClamped =  smoothstep(glitchPos , glitchPos + 1, _Width );

      // only split on the camera viewing part
      float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));
      float frontFacing =saturate(dot(normalize(v.normal), normalize(viewDir))) ;
      frontFacing = step(0.1, frontFacing);

      // move vertices outward based on the glitchy position
      v.vertex.xyz += (glitchPosClamped * normalize(v.normal)) * _Intensity * frontFacing;

      // send positions through to the fragment function
      o.glitchPos = glitchPos;
      o.glitchPosFront = glitchPosClamped* frontFacing;
    }

    // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    // #pragma instancing_options assumeuniformscaling
    UNITY_INSTANCING_BUFFER_START(Props)
    // put more per-instance properties here
    UNITY_INSTANCING_BUFFER_END(Props)

    float3 GetFaceNormal(float3 position) {
      float3 dx = ddx(position);
      float3 dy = ddy(position);
      return normalize(cross(dy, dx));
    }

    void surf (Input IN, inout SurfaceOutput o)
    {
      // grabtex uv
      float2 uv = IN.screenPos.xy / IN.screenPos.w;
      
      // get an evened out facenormal, will make the distortions move more with the vertex movement
      float3 faceNormal = GetFaceNormal(IN.worldPos.xyz);
      
      // distorted uv 
      float2 distortedUV = lerp(uv, (faceNormal + uv) * 0.5,  _Distortion) ;
      // grabtex
      float4 grabPassTex = tex2D (_GrabTex, distortedUV );

      //base albedo is the grabtex
      o.Albedo =  grabPassTex.rgb ;
      
      // backfaces colors, lerped over glitchpos
      float3 backGlitchCol = lerp(_BackfaceCol2, _BackfaceCol, saturate(IN.glitchPos*  _StretchBackface));

      // tinted grabtex colors, lerped over glitchpos
      float3 albedoTinting = lerp( _Tinting, _Tinting2,saturate(IN.glitchPos* _Stretch));
      albedoTinting *=  grabPassTex.rgb;
      // add tinting
      o.Albedo += (albedoTinting * _TintingBrightness) ;
      
      // use vface to only add color to the front faces
      o.Albedo = (IN.facing>0) ? o.Albedo : 0;
      
      // create a rim
      float Rim = 1.0 - saturate(dot(normalize(faceNormal), normalize(IN.viewDir)));
      float softRim = pow(Rim, _RimPower)  ;

      
      // color rim based on glitchpos
      float3 rimCol = lerp(_RimCol, _RimCol2,  saturate(IN.glitchPos * _StretchRim) );

      // rimcol on frontfacing, backglithcol on backfacing
      o.Emission = ((IN.facing>0) ?  ( rimCol * _RimBrightness) * softRim: backGlitchCol * _Brightness ) ;
      
      // clip front to show into the mesh more
      clip( ((1-IN.glitchPosFront)- _Clipping));
      
      o.Alpha = 1;
    }
    ENDCG
  }
  FallBack "Diffuse"
}

1条评论

相关信息

  • 类型:知识
  • 字数:157
  • 字符:380
  • 适用软件:Unity
  • 说明:无
  • 编号:61281

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!