• Unity3D手游开发日记(4)


    热浪扭曲效果的实现,分两部分,一是抓图,二是扭曲扰动.其中难点在于抓图的处理,网上的解决方案有两种,在移动平台都有很多问题,只好自己实现了一种新的方案,效果还不错.

    网上方案1. 用GrabPass抓图

    GrabPass在有的手机上是不支持的...效率也是问题,所以...

    代码可以看看:

    [csharp] view plain copy
     
    1. Shader "Luoyinan/Distortion/HeatDistortion"   
    2. {  
    3.     Properties  
    4.     {  
    5.         _NoiseTex ("Noise Texture (RG)", 2D) = "white" {}  
    6.         _MainTex ("Alpha (A)", 2D) = "white" {}  
    7.         _HeatTime  ("Heat Time", range (0,1.5)) = 1  
    8.         _HeatForce  ("Heat Force", range (0,0.1)) = 0.1  
    9.     }  
    10.   
    11.     Category   
    12.     {  
    13.         Tags { "Queue"="Transparent+1" "RenderType"="Transparent" }  
    14.   
    15.         Blend SrcAlpha OneMinusSrcAlpha  
    16.         AlphaTest Greater .01  
    17.         Cull Off   
    18.         Lighting Off   
    19.         ZWrite Off  
    20.       
    21.         SubShader   
    22.         {  
    23.             GrabPass   
    24.             {                             
    25.                 Name "BASE"  
    26.                 Tags { "LightMode" = "Always" }  
    27.             }  
    28.   
    29.             Pass   
    30.             {  
    31.                 Name "BASE"  
    32.                 Tags { "LightMode" = "Always" }  
    33.               
    34.                 CGPROGRAM  
    35.                 #pragma vertex vert  
    36.                 #pragma fragment frag  
    37.                 #pragma fragmentoption ARB_precision_hint_fastest  
    38.                 #include "UnityCG.cginc"  
    39.   
    40.                 struct appdata_t   
    41.                 {  
    42.                     float4 vertex : POSITION;  
    43.                     fixed4 color : COLOR;  
    44.                     float2 texcoord: TEXCOORD0;  
    45.                 };  
    46.   
    47.                 struct v2f   
    48.                 {  
    49.                     float4 vertex : POSITION;  
    50.                     float4 uvgrab : TEXCOORD0;  
    51.                     float2 uvmain : TEXCOORD1;  
    52.                 };  
    53.   
    54.                 float _HeatForce;  
    55.                 float _HeatTime;  
    56.                 float4 _MainTex_ST;  
    57.                 float4 _NoiseTex_ST;  
    58.                 sampler2D _NoiseTex;  
    59.                 sampler2D _MainTex;  
    60.   
    61.                 v2f vert (appdata_t v)  
    62.                 {  
    63.                     v2f o;  
    64.                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  
    65.                     o.uvgrab = ComputeGrabScreenPos(o.vertex);  
    66.                     o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );  
    67.                     return o;  
    68.                 }  
    69.   
    70.                 sampler2D _GrabTexture;  
    71.   
    72.                 half4 frag( v2f i ) : COLOR  
    73.                 {  
    74.                     // noise effect  
    75.                     half4 offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.xz*_HeatTime);  
    76.                     half4 offsetColor2 = tex2D(_NoiseTex, i.uvmain - _Time.yx*_HeatTime);  
    77.                     i.uvgrab.x += ((offsetColor1.r + offsetColor2.r) - 1) * _HeatForce;  
    78.                     i.uvgrab.y += ((offsetColor1.g + offsetColor2.g) - 1) * _HeatForce;  
    79.       
    80.                     half4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));  
    81.                     // Skybox's alpha is zero, don't know why.  
    82.                     col.a = 1.0f;  
    83.                     half4 tint = tex2D( _MainTex, i.uvmain);  
    84.   
    85.                     return col*tint;  
    86.                 }  
    87.   
    88.                 ENDCG  
    89.             }  
    90.         }  
    91.   
    92.         // ------------------------------------------------------------------  
    93.         // Fallback for older cards and Unity non-Pro  
    94.         SubShader   
    95.         {  
    96.             Blend DstColor Zero  
    97.             Pass   
    98.             {  
    99.                 Name "BASE"  
    100.                 SetTexture [_MainTex] { combine texture }  
    101.             }  
    102.         }  
    103.     }  
    104. }  


    网上方案2:用RenderTexture来代替抓图

    这种方法很坑爹,把场景再渲染一次?想想就很恐怖

    我的方案: 后处理

    换种思路,后处理其实就已经有了我们需要抓取的图,我们只需要渲染一个掩码图,就能实现局部的扭曲了,以前做次世代引擎的开发,很多特效都是后处理的实现的,比如人在水里面走水面泛起的涟漪,其实热浪扭曲也可以用类似的方法.

    原理:

    1.先用后处理实现全屏的扰动

    2.用RenderTexture做实时的掩码图.

    这样的话,效率开销只在两部分,一是后处理,二是把扭曲面片渲染到掩码图,

    优化:

    1.掩码图RenderTexture尽可能简单,关掉深度,抗锯齿等,用最简单的格式RenderTextureFormat.RGB565,黑白掩码图,不要alpha通道,掩码面片的shader可以用粒子的add shader

    2.不需要扭曲的时候应该关闭掉扭曲用的后处理.不要一直开着.这个实现起来需要对掩码面片的存在有一个计数统计,才知道什么时候能关掉.

    3.掩码图的比例一定要和屏幕保持一致,大小可设置为屏幕宽高的1/2或者1/4,

    后处理的脚本:

    后处理shader:

    [csharp] view plain copy
     
      1. Shader "Luoyinan/ImageEffect/HeatDistortion"   
      2. {  
      3.     Properties   
      4.     {  
      5.         _MainTex ("Base (RGB)", 2D) = "white" {}  
      6.         _NoiseTex ("Noise Texture (RG)", 2D) = "white" {}  
      7.         _MaskTex ("Mask Texture", 2D) = "white" {}  
      8.         _HeatTime  ("Heat Time", range (0,1.5)) = 1  
      9.         _HeatForce  ("Heat Force", range (0,0.1)) = 0.1  
      10.     }  
      11.       
      12.     SubShader   
      13.     {  
      14.         Pass  
      15.         {  
      16.             CGPROGRAM  
      17.             #pragma vertex vert_img  
      18.             #pragma fragment frag  
      19.             #pragma fragmentoption ARB_precision_hint_fastest  
      20.             #include "UnityCG.cginc"  
      21.               
      22.             float _HeatForce;  
      23.             float _HeatTime;  
      24.   
      25.             uniform sampler2D _MainTex;  
      26.             uniform sampler2D _NoiseTex;  
      27.             uniform sampler2D _MaskTex;  
      28.   
      29.             fixed4 frag(v2f_img i) : COLOR  
      30.             {  
      31.                 // 为了效率,掩码图是黑白的,so...  
      32.                 fixed mask = tex2D(_MaskTex, i.uv).r;  
      33.   
      34.                 // 扭曲效果  
      35.                 half4 offsetColor1 = tex2D(_NoiseTex, i.uv + _Time.xz*_HeatTime);  
      36.                 half4 offsetColor2 = tex2D(_NoiseTex, i.uv - _Time.yx*_HeatTime);  
      37.                 i.uv.x += ((offsetColor1.r + offsetColor2.r) - 1) * _HeatForce * mask;  
      38.                 i.uv.y += ((offsetColor1.g + offsetColor2.g) - 1) * _HeatForce * mask;  
      39.   
      40.                 fixed4 renderTex = tex2D(_MainTex, i.uv);  
      41.           
      42.                 return renderTex;  
      43.             }  
      44.       
      45.             ENDCG  
      46.         }  
      47.     }   
      48.     FallBack off  
      49. }  
  • 相关阅读:
    Shell基础:变量类型 & 运算符
    Ant基础入门
    Shell基础:Shell和Mysql交互
    Linux配置邮箱发送(MUTT/MSMTPQ)
    [转载]JMeter源码导入Eclipse
    [转载]Badboy使用教程
    工程目录 Java/Web/Maven
    Maven基础知识和环境搭建
    Github/Eclipse管理Maven项目
    Git分支管理详解
  • 原文地址:https://www.cnblogs.com/czaoth/p/5785632.html
Copyright © 2020-2023  润新知