转自:http://blog.sina.com.cn/s/blog_89d90b7c0102vaqy.html

热空气扭曲在大自然中形成是比较复杂的,这里只是通过取屏幕纹理和移动UV来模拟热扭曲效果。

先看效果:

详细的原理和实现在下面的代码中。

Shader "Xffect/my_distortion" {
Properties {
_NoiseTex ("絮乱图", 2D) = "white" {} // 絮乱图
_AreaTex ("区域图(Alpha):白色为显示区域,透明为不显示区域", 2D) = "white" {} // 区域图
_MoveSpeed ("絮乱图移动速度", range (,1.5)) = // 絮乱图移动速度
_MoveForce ("絮乱图叠加后移动强度", range (,0.1)) = 0.1 // 絮乱图叠加强度,多张运动纹理叠加后再相乘的系数
} Category {
// 【渲染队列】在透明物体前,类型为【透明】
Tags { "Queue"="Transparent+1" "RenderType"="Transparent" }
// 最终透明混合 = 贴图RGB*贴图A + 背景RGB*(1-贴图A)
// 透明混合【源的A值】【1-SrcAlpha】
Blend SrcAlpha OneMinusSrcAlpha // 该写法为最常用最真实的透明混合显示,半透明图的正常显示
// GEuqal 点的alpha值大于等于0.01时渲染
AlphaTest Greater . // 在PS区域图时,不显示的地方透明度为0即可。
// 关闭剔除,关闭灯光,不记录深度
Cull Off Lighting Off ZWrite Off SubShader {
GrabPass {
Name "BASE"//在后续的通道中可以使用给定的名字来引用这个纹理。当你在1个场景中有多个对象使用grab pass 时候,这样做会提高效率。
Tags { "LightMode" = "Always" }
} Pass {
Name "BASE"
Tags { "LightMode" = "Always" } 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; // 输出的纹理做标集0
float2 uvmain : TEXCOORD1; // 输出的纹理坐标集1
}; float _MoveSpeed; // 声明絮乱图移动速度
float _MoveForce; // 声明运动强度
float4 _NoiseTex_ST; // 絮乱图采样
float4 _AreaTex_ST; // 区域图采样 sampler2D _NoiseTex; // 絮乱图样本对象
sampler2D _AreaTex; // 区域图样本对象
sampler2D _GrabTexture; // 全屏幕纹理的样本对象,由GrabPass赋值 v2f vert (appdata_t v)
{
v2f o;
// 从模型坐标-世界坐标-视坐标-(视觉平截体乘以投影矩阵并进行透视除法)-剪裁坐标
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
// 将裁剪坐标中的【顶点信息】进行换算给uvgrab赋值
#if UNITY_UV_STARTS_AT_TOP // Direct3D类似平台scale为-1;OpenGL类似平台为1。
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; // 区域图纹理:获取输入的纹理坐标集,并且使用_MainTex_ST采样图,支持在视检器调节缩放和偏移值
o.uvmain = TRANSFORM_TEX(v.texcoord, _AreaTex);
return o;
} half4 frag( v2f i ) : COLOR
{
// 控制【UV的运动】,这样在进行采样时,offsetColor1拿到的颜色也是运动的。
half4 offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.xz * _MoveSpeed);// 将xy与xz交叉位移
half4 offsetColor2 = tex2D(_NoiseTex, i.uvmain - _Time.yx * _MoveSpeed);// 将xy与yx交叉位移
// 将【正在移动的絮乱图纹理信息】的rg用于给uvgrab累加,加2个col就会出现2个絮乱图纹理
i.uvgrab.x += ((offsetColor1.r + offsetColor2.r) - ) * _MoveForce; // 叠加强度
i.uvgrab.y += ((offsetColor1.g + offsetColor2.g) - ) * _MoveForce; // 本来只会显示物体背后的屏幕纹理(视觉上该物体透明了)
// 但是上面给x,y叠加了运动的rg值,所以就形成透明絮乱图运动的效果
half4 noiseCol = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
// 屏幕纹理不需要透明,所以设置为1。
noiseCol.a = 1f;
// 对区域图进行采样。
half4 areaCol = tex2D(_AreaTex, i.uvmain);
// 纹理相乘:区域纹理RBG都为1,区域纹理A为O的像素将不会显示
// 即可达到絮乱图在区域图中才显示的效果。
return noiseCol * areaCol;
}
ENDCG
}//end pass
}//end subshader // 用于老式显卡
SubShader {
Blend DstColor Zero
Pass {
Name "BASE"
SetTexture [_MainTex] { combine texture }
}
}
}
}
配合粒子的发射,就可以在刀光上实现热扭曲效果等。

注:

此shader在部分手机上会有问题,是因为对grabpass的支持不够,

这里可以采用摄像机获取屏幕纹理的方式代替_GrabTexture。

原理在http://blog.sina.com.cn/s/blog_89d90b7c0102va4m.html的最下面。

(转)热空气扭曲效果shader的更多相关文章

  1. Unity Shader-热空气扭曲效果

    GrabPass GrabPass是Unity为我们提供的一个很方便的功能,可以直接将当前屏幕内容渲染到一张贴图上,我们可以直接在shader中使用这张贴图而不用自己去实现渲染到贴图这样的一个过程,大 ...

  2. 扭曲效果 效率优化 GrapPass,CommandBuffer对比

    屏幕图像捕捉: Shader的GrabPass GrabPass可以很方便地捕获当前渲染时刻的FrameBuffer中的图像. 其原理就是从当前FrameBuffer中copy一份纹理,通过SetTe ...

  3. Unity3D Shader 空气扭动效果

    //预览图 //原理 一个摄像机CullingMask设置只可见"Distortion"的Layer(需要自己手动加),输入到一张RenderTexture,其实就是用于确定哪里要 ...

  4. Unity3D-Shader-热扭曲效果

    [旧博客转移 - 2016年1月13日 13:18 ] 前面的话: 本来我是想写一个水的原理的,但是发现涉及的知识太多,还有好多不懂的,所以就先一步一步来 最近呢,我在网上捡到了一本<热扭曲秘籍 ...

  5. 高达渐出现效果Shader

    原地址: http://liweizhaolili.blog.163.com/blog/static/1623074420140591864/ 最近在玩游戏<高达破坏者>,里面的高达出现的 ...

  6. 图片循环滚动效果shader

    背景无限循环滚动效果,有X和Y轴的速度控制,方便控制.见下图,操作步骤同之前的背景循环设置. shader如下: Shader "Custom/Scroll" { Properti ...

  7. Unity喷墨效果Shader实现

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...

  8. 技能CD 效果 shader

    技能CD特效 这个效果主要是利用反正切函数完成.atan2(x,y)的返回值是[-PI,PI],这个支持4个象限的反正切函数.关于圆角计算,在上篇文章中有介绍. 现在,我们来看看反正切函数的效果: 在 ...

  9. MatCap冰冻效果Shader

    MatCap方案 使用说明 制作合适的MatCap贴图 这张图决定冰像不像,网上找.Vray渲个球.ASE或者ShaderForge连,甚至直接手绘,总之只要一张长得像下面的图 注意MatCap图只有 ...

随机推荐

  1. 使用vmware提示无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件

    问题描述 打开虚拟机时候提示 “vmware没有正常关闭,再次打开使用时蓝屏,在安全模式下再次打开不会蓝屏,但提示“无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件,你想要安 ...

  2. .NetCore源码阅读笔记系列之Security (四) Authentication & AddJwtBearer

    接下来我们在来看下AddJwtBearer,这个与AddOpenIdConnect不太一样,后者是远程发起身份认证请求是一种主动发起式的,多用于web等客户端,验证发生在身份认证服务端,而前者是一种被 ...

  3. .NetCore源码阅读笔记系列之Security (三) Authentication & AddOpenIdConnect

    通过第二篇文章我们已经知道了授权的内部实现通过自定义的授权Handler来的,同样的道理 OpenIdConnect 同样是通过 OpenIdConnectHandler来请求授权的 那么它内部又是怎 ...

  4. 如何获取JMX监控WebSphere所需的com.ibm.ws.admin.client_8.5.0等jar包

    https://blog.csdn.net/weixin_38645718/article/details/83346007

  5. [CodeChef]GERALD07/[JZOJ4739]Ztxz16学图论

    题解: 考虑从小到大枚举右端点 对于每个点,令它的权值等于它的编号 那么我们可以用lct维护出一颗最大生成树 维护方法是每次插入一条判断他们在不在一颗树上 若不在直接加,若在就找到链上的最小值 之后看 ...

  6. python面试笔试题,你都会了吗?快来复习

    1.一行代码实现1--100之和 利用sum()函数求和 >>> sum(range(0,101)) 5050 2.如何在一个函数内部修改全局变量 利用global 修改全局变量 a ...

  7. threeSum问题

    三数之和等于0的问题: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中 ...

  8. 解决eclipse部署项目各种乱码问题,推荐一下别人的做法

    http://blog.sina.com.cn/s/blog_62aab2760100l1hx.html

  9. 【Java并发核心五】Future 和 Callable

    默认情况下,线程Thread对象不具有返回值的功能,如果在需要取得返回值的情况下会极为不方便.jdk1.5中可以使用Future 和 Callable 来获取线程返回值. Callable 可以 看成 ...

  10. 关于Git的总结

    首先我们先看一张图: 首先我们必须要先理解这几个概念:暂存区,本地仓库,远程仓库 暂存区:这个是我们每一次进行代码修改的地方,例如我们ieda的所编译的代码就是缓存区 本地仓库:是我们每一次pull, ...