Flowmap的实质:
一张记录了2D向量信息的纹理,
Flow map上的颜色(通常为RG通道)记录该处向量场的方向,让模型上某一点表现出定量流动的特征。
通过在shader中偏移uv再对纹理进行采样,来模拟流动效果。
- 不同软件中有不同的uv坐标,比如UE4中他和unity相比是反转了绿通道(左上角为原点,unity用的opengl的,UE4则是使用的DirectX的)
- 所以我们使用的Flowmap也要发生变化,我们需要根据我们的引擎去进行调整
为什么要使用Flowmap
类型uv动画,而非顶点动画,所以无需对模型顶点进行操作,易实现,运算开销小
除去水面的渲染,凡是涉及到流动的地方都可以使用flowmap,
水体渲染,flowmap可以算是其中一种解决方案,还有其他很多方案:
- FFT(快速傅里叶变换)
- Gerstner波
- 法线水
- .采样Flow map获取向量场信息
- 用向量场信息,使采样贴图时的UV随时间变化
- 对同一贴图以半个周期的相位差采集两次,并线性插值,使贴图流动连续
实现代码
Shader "Custom/Flowmap" { Properties { _Color ("Color", Color) = (1,1,1,1) _MainTex ("Albedo (RGB)", 2D) = "white" {} _FlowMap("FlowMap" ,2D) = "white"{} _FlowSpeed("FlowSpeed",Range(0,0.5)) = 0.1 _TimeSpeed("TimeSpeed" ,Range(0,1)) = 1 [Toggle]_reverse_flow("Reverse_flow",int) = 0 } SubShader { Tags { "Queue" = "Opaque" "IgnorProjector"="True" "RenderType"="Opaque" } Cull Off Lighting Off ZWrite On Pass{ CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma shader_feature _REVERSE_FLOW #include "UnityCG.cginc" struct a2f{ float4 vertex :POSITION; float2 uv:TEXCOORD0; }; struct v2f{ float4 vertex:SV_POSITION; float2 uv :TEXCOORD0; }; fixed4 _Color; sampler2D _MainTex; float4 _MainTex_ST; sampler2D _FlowMap; float4 _FlowMap_ST; float _FlowSpeed; float _TimeSpeed; v2f vert(a2f i){ v2f o; o.vertex = UnityObjectToClipPos(i.vertex); o.uv = i.uv; return o; } fixed4 frag (v2f i) : SV_Target{ float3 flowDir = tex2D(_FlowMap, i.uv) * 2 - 1; flowDir *= _FlowSpeed; #ifdef _REVERSE_FLOW flowDir = -1 #endif //控制时间周期 float phase0 = frac(_Time.y * 0.1 * _TimeSpeed); float phase1 = frac(_Time.y * 0.1 * _TimeSpeed + 0.5); float2 tlling_uv = TRANSFORM_TEX(i.uv,_MainTex); half4 tex0 = tex2D(_MainTex, tlling_uv - flowDir.xy * phase0); half4 tex1 = tex2D(_MainTex, tlling_uv - flowDir.xy * phase1); float flowlerp = abs((0.5 - phase0) / 0.5); half4 MainColor = lerp(tex0, tex1, flowlerp) * _Color; return MainColor; } ENDCG } } FallBack "Diffuse" }View Code
用Flow map修改法线贴图采样
//在法线从切线空间转换到世界空间前修改法线 //half4 worldNormal; //worldNormal.x = dot(i.tsapce0,tnormal); //worldNormal.y = dot(i.tsapce1,tnormal); //worldNormal.z = dot(i.tsapce2,tnormal);View Code
标签:flowDir,uv,MainTex,float,FlowMap,Flowmap From: https://www.cnblogs.com/kayiko/p/17255814.html