Flow Shader and map generation

Discussion in 'Shaders' started by aubergine, Nov 9, 2012.

  1. aubergine

    aubergine

    Member

    Joined:
    Sep 12, 2009
    Messages:
    2,047
    So, here is a basic test shader and script for using flow maps on water surfaces. No water here, just the flow of the normals.

    NoiseTex is an average noise texture you can make one with render clouds option in photoshop.
    NormTex0 and 1 are just average wave normal textures, you can use the one supplied with unity water.

    Shader:
    Code (csharp):
    1. Shader "Aubergine/ObjSpace/Flow" {
    2.     Properties {
    3.         _FlowTex ("_FlowTex", 2D) = "white" {}
    4.         _NoiseTex ("_NoiseTex", 2D) = "white" {}
    5.         _NormTex0 ("_NormTex0", 2D) = "" {}
    6.         _NormTex1 ("_NormTex1", 2D) = "" {}
    7.     }
    8.     SubShader {
    9.         Pass {
    10.             Tags { "RenderType"="Opaque" }
    11.             Lighting Off Fog { Mode Off }
    12.             LOD 200
    13.            
    14.             CGPROGRAM
    15.                 #pragma vertex vert
    16.                 #pragma fragment frag
    17.                 #pragma fragmentoption ARB_precision_hint_fastest
    18.                 #include "UnityCG.cginc"
    19.  
    20.                 sampler2D _FlowTex, _NoiseTex, _NormTex0, _NormTex1;
    21.                 uniform float _FlowOffset0, _FlowOffset1, _HalfCycle;
    22.                
    23.                 struct a2f {
    24.                     float4 vertex : POSITION;
    25.                     float4 texcoord : TEXCOORD0;
    26.                 };
    27.  
    28.                 struct v2f {
    29.                     float4 Pos : SV_POSITION;
    30.                     float2 Uv : TEXCOORD0;
    31.                 };
    32.  
    33.                 v2f vert (a2f v) {
    34.                     v2f o;
    35.                     o.Pos = mul(UNITY_MATRIX_MVP, v.vertex);
    36.                     o.Uv = v.texcoord.xy;
    37.                     return o;
    38.                 }
    39.  
    40.                 half4 frag( v2f i ) : COLOR {
    41.                     half2 flowTex = tex2D(_FlowTex, i.Uv).rg * 2.0f - 1.0f;
    42.                     float cycleOffs = tex2D(_NoiseTex, i.Uv).r;
    43.                    
    44.                     //float phase0 = 0.5f + _FlowOffset0;
    45.                     //float phase1 = 0.5f + _FlowOffset1;
    46.                     float phase0 = cycleOffs * 0.5f + _FlowOffset0;
    47.                     float phase1 = cycleOffs * 0.5f + _FlowOffset1;
    48.                    
    49.                     float3 norm0 = tex2D(_NormTex0, (i.Uv * 4) + flowTex * phase0);
    50.                     float3 norm1 = tex2D(_NormTex1, (i.Uv * 2) + flowTex * phase1);
    51.                    
    52.                     float f = (abs(_HalfCycle - _FlowOffset0) / _HalfCycle);
    53.                    
    54.                     float3 normT = lerp(norm0, norm1, f);
    55.                     return float4(normT, 1.0f);
    56.                 }
    57.             ENDCG
    58.         }
    59.     }
    60.     FallBack Off
    61. }
    The script
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Flow : MonoBehaviour {
    5.  
    6.     public float Cycle = .15f;
    7.     public float FlowSpeed = .05f;
    8.     private float HalfCycle = 0f;
    9.     private float FlowMapOffset0, FlowMapOffset1;
    10.  
    11.     // Use this for initialization
    12.     void Start () {
    13.         HalfCycle = Cycle * .5f;
    14.         FlowMapOffset0 = 0.0f;
    15.         FlowMapOffset1 = HalfCycle;
    16.         renderer.sharedMaterial.SetFloat("_HalfCycle", HalfCycle);
    17.         renderer.sharedMaterial.SetFloat("_FlowOffset0", FlowMapOffset0);
    18.         renderer.sharedMaterial.SetFloat("_FlowOffset1", FlowMapOffset1);
    19.     }
    20.    
    21.     // Update is called once per frame
    22.     void Update () {
    23.         FlowMapOffset0 += FlowSpeed * Time.deltaTime;
    24.         FlowMapOffset1 += FlowSpeed * Time.deltaTime;
    25.         if (FlowMapOffset0 >= Cycle)
    26.             FlowMapOffset0 = 0.0f;
    27.  
    28.         if (FlowMapOffset1 >= Cycle)
    29.             FlowMapOffset1 = 0.0f;
    30.        
    31.         renderer.sharedMaterial.SetFloat("_FlowOffset0", FlowMapOffset0);
    32.         renderer.sharedMaterial.SetFloat("_FlowOffset1", FlowMapOffset1);
    33.     }
    34. }
    My question is, the flowmap is a picture of 2d vectors. And i want to make a custom flow map generator for my personal usage but i am having hard times understanding what color represents what direction.

    I found out these yet:
    rgb(128, 128, 128) = Vector(0, 0)
    rgb(0, 0, 0) = Vector(-1, -1)
    rgb(255, 0, 0) = Vector(1, 0) or (1, 1) i dont understand.

    Anyways, is there any resource that explains how flowmap colors actually work?
     
  2. Farfarer

    Farfarer

    Member

    Joined:
    Aug 17, 2010
    Messages:
    2,172
    They're essentially a 2D normal map except the values represent the magnitude of change to the UV value rather than the normal value. So two axes (R and G) represent the value of the UV offset you apply.

    One of my friends authored a tool in Unity that lets you paint them out to a texture;
    http://teckartist.com/?page_id=107
     
    Last edited: Nov 9, 2012
  3. lazygunn

    lazygunn

    Member

    Joined:
    Jul 24, 2011
    Messages:
    2,172
    I'm not sure if you've seen it (you probably have) but if you take a look at this http://algoholic.eu/flow-shader-fix-flow-editor/, you might be able to figure it out from how the editor works, good luck, it's something i intend to tackle soon
     
  4. lazygunn

    lazygunn

    Member

    Joined:
    Jul 24, 2011
    Messages:
    2,172
    ahh i hadnt seen that, cheers!
     
  5. aubergine

    aubergine

    Member

    Joined:
    Sep 12, 2009
    Messages:
    2,047
    Yes the UV offset or lets say the movement direction, i will check out the tool your friend authored. Thanks :)
     
  6. Arkhivrag

    Arkhivrag

    Member

    Joined:
    Apr 25, 2012
    Messages:
    296