Unity3D-Shader-热扭曲效果

时间:2021-04-14 14:44:50

【旧博客转移 - 2016年1月13日 13:18 】

前面的话:

本来我是想写一个水的原理的,但是发现涉及的知识太多,还有好多不懂的,所以就先一步一步来
最近呢,我在网上捡到了一本《热扭曲秘籍》,修炼数日,甚觉精妙
这次分享一个很简单的热扭曲原理
 

先看效果:

1.这是原图
Unity3D-Shader-热扭曲效果
 
2.加了特效之后~显得很亮,很柔..
Unity3D-Shader-热扭曲效果
3.这个神秘的图,才是效果的关键Unity3D-Shader-热扭曲效果
Unity3D-Shader-热扭曲效果
 

扰动图:

扰动图其实是把offset信息写入到R,G通道中的图片
下面我们拿一个“照妖镜”随便找一个像素看一下它的真面目
Unity3D-Shader-热扭曲效果
 
可以看到像素值为#946A00, R通道94,G通道6A,而B通道没有值,是00,因为这里暂时用不到B
float4 disTex = tex2D(_DistortionMap, i.uv);
float2 offsetUV = float2(disTex.r, disTex.g);
通过tex2D采样,就可以取出扰动偏移量了
 
但是呢,颜色值是【0到1】,而扰动向量的值是【-1到1】
所以还需要转换一下
offsetUV = (offsetUV-0.5)*;

改变原图

float4 bgTex = tex2D(_Background, i.uv + offsetUV);
直接加上uv偏移量就行了
 

总结

看到这里,你已经掌握了扭曲图片的基本原理,没错就是这么简单~
偏移uv坐标,把偏移信息生成到一张图片中,就叫扰动图
 
热扭曲秘籍:链接:http://pan.baidu.com/s/1jH1nMqq 密码:zxfb

本文源码

Shader "lijia/Refractor1" {

    Properties {
_Background ("Background", 2D) = "" {} //背景纹理
_BackgroundScrollX ("X Offset", float) = //背景偏移
_BackgroundScrollY ("Y Offset", float) =
_BackgroundScaleX ("X Scale", float) = 1.0 //背景缩放
_BackgroundScaleY ("Y Scale", float) = 1.0
_Refraction ("Refraction", float) = 1.0 //折射值
_DistortionMap ("Distortion Map", 2D) = "" {} //扭曲
_DistortionScrollX ("X Offset", float) =
_DistortionScrollY ("Y Offset", float) =
_DistortionScaleX ("X Scale", float) = 1.0
_DistortionScaleY ("Y Scale", float) = 1.0
_DistortionPower ("Distortion Power", float) = 0.08
} SubShader {
Tags {"Queue" = "Geometry" "RenderType" = "Opaque"} Pass { Cull Off
ZTest LEqual
ZWrite On
AlphaTest Off
Lighting Off
ColorMask RGBA
Blend Off CGPROGRAM
#pragma target 2.0
#pragma fragment frag
#pragma vertex vert
#include "UnityCG.cginc" uniform sampler2D _Background;
uniform sampler2D _DistortionMap;
uniform float _BackgroundScrollX;
uniform float _BackgroundScrollY;
uniform float _DistortionScrollX;
uniform float _DistortionScrollY;
uniform float _DistortionPower;
uniform float _BackgroundScaleX;
uniform float _BackgroundScaleY;
uniform float _DistortionScaleX;
uniform float _DistortionScaleY;
uniform float _Refraction; struct AppData {
float4 vertex : POSITION;
half2 texcoord : TEXCOORD0;
}; struct VertexToFragment {
float4 pos : POSITION;
half2 uv : TEXCOORD0;
}; VertexToFragment vert(AppData v) {
VertexToFragment o;
o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
o.uv = v.texcoord.xy;
return o;
} fixed4 frag(VertexToFragment i) : COLOR {
float2 bgOffset = float2(_BackgroundScrollX,_BackgroundScrollY);
float2 disOffset = float2(_DistortionScrollX,_DistortionScrollY);
float2 disScale = float2(_DistortionScaleX,_DistortionScaleY);
float2 bgScale = float2(_BackgroundScaleX,_BackgroundScaleY); float4 disTex = tex2D(_DistortionMap, disScale * i.uv+disOffset); float2 offsetUV = (-_Refraction*(disTex * _DistortionPower - (_DistortionPower*0.5))); return tex2D(_Background, bgScale * i.uv + bgOffset + offsetUV);
} ENDCG
}
}
}