U3D Distortion
2016-05-30 22:48
459 查看
我们的美术希望游戏可以更炫一点,想在刀光特效上加上空气扭曲的效果,就是类似燃烧的火焰上方空气扰动的那种效果。这个效果其实很多游戏都有。网络上流传的有一个叫heat_distortion的shader,这个shader使用grabTexture实现的,实现方法很多人都讲过,这里就不细说了。grabTexture比较坑爹,在移动设备上效率很成问题,而且有些机型也不支持,所以我们需要用其他办法实现。
我们用的是后处理的办法.
1. 我们在特效上挂一个片A,给A单独设一个layer L1,然后在Main Camera上挂一个带摄像机的子节点Sub(back ground清成黑色),MainCamera的mask剔除掉L1 ,让Sub只渲染L1。
2. A的材质shader使用heat_distortion,这个shader通过一张噪声图计算出一个UV值,从mainTex中取颜色给后面后处理的时候当UV用。
3. main camera挂载脚步DistortImageEffect。在OnRenderImage中获取Sub的RenderTexture,将这个RT给shader:IE_heat_distortion使用并生成最终结果。
代码:
我们用的是后处理的办法.
1. 我们在特效上挂一个片A,给A单独设一个layer L1,然后在Main Camera上挂一个带摄像机的子节点Sub(back ground清成黑色),MainCamera的mask剔除掉L1 ,让Sub只渲染L1。
2. A的材质shader使用heat_distortion,这个shader通过一张噪声图计算出一个UV值,从mainTex中取颜色给后面后处理的时候当UV用。
3. main camera挂载脚步DistortImageEffect。在OnRenderImage中获取Sub的RenderTexture,将这个RT给shader:IE_heat_distortion使用并生成最终结果。
代码:
using UnityEngine; using System.Collections; public class DistortImageEffect : MonoBehaviour { // 记录参数的rt RenderTexture rt; public Material IEHeatMaterial = null; public Camera sub = null; // Use this for initialization void Start() { Camera cam = GetComponent<Camera>(); sub.fieldOfView = cam.fieldOfView; sub.nearClipPlane = cam.nearClipPlane; sub.farClipPlane = cam.farClipPlane; sub.aspect = cam.aspect; int w = Screen.width / 2; int h = Screen.height / 2; if (w > SystemInfo.maxTextureSize) { h = h * SystemInfo.maxTextureSize / w; w = SystemInfo.maxTextureSize; } if (h > SystemInfo.maxTextureSize) { w = w * SystemInfo.maxTextureSize / h; h = SystemInfo.maxTextureSize; } rt = RenderTexture.GetTemporary(Screen.width / 2, Screen.height / 2); sub.targetTexture = rt; } void OnDestroy() { RenderTexture.ReleaseTemporary(rt); } void OnRenderImage(RenderTexture source, RenderTexture destination) { if (sub == null) { Graphics.Blit(source, destination); return; } IEHeatMaterial.SetTexture("_NormalTex", rt); Graphics.Blit(source, destination, IEHeatMaterial, 0); } }
Shader "Distortion" { Properties { _NoiseTex ("Noise (RG)", 2D) = "white" {} _MainTex ("Alpha (A)", 2D) = "white" {} _HeatTime ("Heat Time", range (0,1.5)) = 1 _HeatForce ("Heat Force", float) = 0.1 } Category { Tags { "RenderType"="Opaque" } Cull Off Lighting Off ZWrite Off Blend Off Fog {Mode Off} LOD 100 SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 texcoord: TEXCOORD0; }; struct v2f { float4 vertex : POSITION; float4 uvgrab : TEXCOORD0; float2 uvmain : TEXCOORD1; float2 uv : TEXCOORD2; }; sampler2D _NoiseTex; float4 _NoiseTex_ST; sampler2D _MainTex; float4 _MainTex_ST; float _HeatForce; float _HeatTime; v2f vert (appdata_t v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); #if UNITY_UV_STARTS_AT_TOP float scale = -1.0; #else float scale = 1.0; #endif o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5; o.uvgrab.zw = o.vertex.zw; o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex ); o.uv = v.texcoord; return o; } half4 frag( v2f i ) : COLOR { half4 offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.xz*_HeatTime); half4 offsetColor2 = tex2D(_NoiseTex, i.uvmain - _Time.yx*_HeatTime); i.uvgrab.x += ((offsetColor1.r + offsetColor2.r) - 1) * _HeatForce; i.uvgrab.y += ((offsetColor1.g + offsetColor2.g) - 1) * _HeatForce; return tex2D(_MainTex, i.uvgrab); } ENDCG } } } Fallback off }
Shader "IEHeatDistortion" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _NormalTex ("Noise Texture (RGB)", 2D) = "white" {} } Category { ZTest Off Cull Off ZWrite Off Blend Off SubShader { Pass { Fog { Mode off } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 texcoord: TEXCOORD0; }; struct v2f { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; float4 _MainTex_ST; float4 _NormalTex_ST; sampler2D _NormalTex; sampler2D _MainTex; v2f vert (appdata_t v) { v2f o; v.vertex.z = 0.1; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = v.texcoord; return o; } half4 frag( v2f i ) : COLOR { half4 col = tex2D( _NormalTex, i.uv); half4 tint = tex2D( _MainTex, i.uv + col); return tint; } ENDCG } } } }
相关文章推荐
- Kinect结合Unity3D引擎开发体感游戏(一)
- Unity3D中脚本的执行顺序和编译顺序
- Unity3D动态对象优化代码分享
- Unity3D获取当前键盘按键及Unity3D鼠标、键盘的基本操作
- Unity3d获取系统时间
- unity3d发布apk在android虚拟机中运行的详细步骤(unity3d导出android apk)
- Unity3D游戏引擎实现在Android中打开WebView的实例
- unity3d调用手机或电脑摄像头
- Unity3d发布IOS9应用时出现中文乱码的解决方法
- 分享一个开源的网络游戏服务器架构—HouHai
- Unity3D插件详细评测及教学下载
- Unity3D上路_01-2D太空射击游戏
- Unity3D上路_02-第一视角射击游戏
- Unity3D上路_03-塔防游戏
- Unity3D上路_04-基础资源介绍
- Unity3D上路_05-网络相关