【舊博客轉移 - 2016年1月13日 13:18 】
前面的話:
本來我是想寫一個水的原理的,但是發現涉及的知識太多,還有好多不懂的,所以就先一步一步來
最近呢,我在網上撿到了一本《熱扭曲秘籍》,修煉數日,甚覺精妙
這次分享一個很簡單的熱扭曲原理
先看效果:
1.這是原圖

2.加了特效之后~顯得很亮,很柔..

3.這個神秘的圖,才是效果的關鍵


擾動圖:
擾動圖其實是把offset信息寫入到R,G通道中的圖片
下面我們拿一個“照妖鏡”隨便找一個像素看一下它的真面目

可以看到像素值為#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)*2;
改變原圖
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) = 0 //背景偏移 _BackgroundScrollY ("Y Offset", float) = 0 _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) = 0 _DistortionScrollY ("Y Offset", float) = 0 _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 } } }