简单的分析下Unity Shader·屏幕抖音效果

2,317 阅读1分钟

Unity Shader·屏幕抖音效果

前言

最近在做一个新的MMD(用Unity来实现),其中用到了一些好看的渲染技术在这里分享一下。

视频链接

www.bilibili.com/video/av863…

效果截图

Shader

  Shader "Douyin"
  {
      Properties 
      {
          _MainTex("MainTex", 2D) = "white" {}
          scale("scale", float) = 1
      }
      SubShader
      {
          Pass
          {
              CGPROGRAM
              #pragma vertex vert
              #pragma fragment frag
              #include "UnityCG.cginc"
              struct a2v
             {
                  float4 vertex : POSITION;
                  float2 uv : TEXCOORD0;
                  };
            
              struct v2f
              {
                  float2 uv : TEXCOORD0;
                  float4 vertex : SV_POSITION;
              };
              sampler2D _MainTex;
              float scale;
            
              v2f vert (a2v v)
              {
                  v2f o;
                  o.vertex = UnityObjectToClipPos(v.vertex);
                  o.uv = v.uv;
                  return o;
              }
              //为了达到最佳效果,将所有计算都写在了片段着色器内。
              fixed4 frag (v2f i) : SV_Target
              {
                  float2 textureCoordinate = i.uv;
                  float2 newTextureCoordinate = float2((scale - 1.0) *0.5 + 
  textureCoordinate.x / scale ,(scale - 1.0) *0.5 + textureCoordinate.y /scale);
                  fixed4 textureColor = tex2D(_MainTex, newTextureCoordinate);
                  fixed4 shiftColor1 = tex2D(_MainTex, 
  newTextureCoordinate+float2(-0.05 * (scale - 1.0), - 0.05 *(scale - 1.0)));
                 fixed4 shiftColor2 = tex2D(_MainTex, newTextureCoordinate+float2(-0.1 
  * (scale - 1.0), - 0.1 *(scale - 1.0)));
                  fixed3 blendFirstColor = fixed3(textureColor.r , textureColor.g, 
  shiftColor1.b);
                  fixed3 blend3DColor = fixed3(shiftColor2.r, blendFirstColor.g, 
  blendFirstColor.b);
                  return fixed4(blend3DColor, textureColor.a);
              }
              ENDCG
          }
      }
  }

C#脚本

  using System;
  using System.Collections;
  using System.Collections.Generic;
  using UnityEngine;

  public class DouYin : PostEffectsBase
  {
      public Shader DouYinShader;
      private RenderTexture RTex;

      private Material douyintMaterial = null;
      public Material material
      {
          get
          {
              douyintMaterial = CheckShaderAndCreateMaterial(DouYinShader, 
   douyintMaterial);
              return douyintMaterial;
           }
      }
      public float scale = 1.0f;

      private void OnRenderImage(RenderTexture source, RenderTexture 
   destination)
      {
          if (material != null)
          {
              material.SetTexture("_MainTex", RTex);
              material.SetFloat("scale", scale);
              Graphics.Blit(source, destination, material);
              material.SetFloat("_EdgeOnly", 1);
              Graphics.Blit(source, RTex, material);
          }
          else
          {
              Graphics.Blit(source, destination);
          }
      }
  }