Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Simple Water Shader keeps "Jumping"

Discussion in 'Editor & General Support' started by scootaboy, Dec 4, 2011.

  1. scootaboy

    scootaboy

    Joined:
    Dec 4, 2011
    Posts:
    8
    Title pretty much says it. I've tried applying the shader to different planes and objects including the original nurbs circle. Scaling the object to different scales and playing with all the wave speed variables but sooner or later the animation of the shader always "jumps" as though it's getting to the end of its cycle.

    What am I doing wrong? Is there a sweetspot setting in the wave variables that I am missing?

    Hope someone else has found a solve for this issue....
     
  2. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    What? :confused: Unity does not render NURBS.
     
  3. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    The original water mesh in Unity was made from a NURBS circle in Maya and I think the name of the converted mesh was "nurbstopoly" or similar. That's probably what he's referring to. As far as the "jump", how long does it take for this to occur?
     
  4. scootaboy

    scootaboy

    Joined:
    Dec 4, 2011
    Posts:
    8
    ... that's right, Nurbs is the name, not the method. As far as how long it takes to occur, it depends on the wave speed settings. The faster the motion the quicker it loops/jumps....
     
  5. scootaboy

    scootaboy

    Joined:
    Dec 4, 2011
    Posts:
    8
    Tried different settings but still seeing the jumping. The problem is that the game I am building includes the water in an overhead view in the camera view for several minutes at a time. Generally the shader jumps after about 45-60 seconds.

    Anyone?
     
  6. janpec

    janpec

    Joined:
    Jul 16, 2010
    Posts:
    3,520
    I solved problem with reimporting water3 or water4. Try if it helps for you.
     
  7. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    That sounds like lack of precision. I don't know what shader you're talking about, but the solution is probably to feed it an offset between 0 and 1.

    Or, if you're talking about something that repeats every minute, then the code doesn't wrap the UV cycle properly.
     
    Last edited: Dec 8, 2011
  8. luisanton

    luisanton

    Joined:
    Aug 25, 2009
    Posts:
    325
    Sorry to revive this post, but I've the same problem. It seems related to the Repeat thing. If, instead of these lines:

    Code (csharp):
    1.  
    2.         Vector4 offset4 = waveSpeed * (t * waveScale);
    3.         Vector4 offsetClamped = new Vector4(Mathf.Repeat(offset4.x,1.0f), Mathf.Repeat(offset4.y,1.0f), Mathf.Repeat(offset4.z,1.0f), Mathf.Repeat(offset4.w,1.0f));
    4.         mat.SetVector( "_WaveOffset", offsetClamped );
    5.  
    we use offset4 as is, it won't jump. But of course, offset4 will increase forever... I've not found a solution, yet.

    Code (csharp):
    1.  
    2.         mat.SetVector( "_WaveOffset", offset4 );
    3.  
     
  9. Baschti-aus-s

    Baschti-aus-s

    Joined:
    Jan 6, 2020
    Posts:
    9
    Sorry for exhuming again, but i found a solution which maybe is helpful for other people come across.
    My example refers to the Water (Basic) prefab, which uses the WaterBasic.cs script as a component of the game object and the FXWaterBasic shader.

    The WaterBasic.cs script contains the code which @luisanton already mentioned, to prepare the movement of the water. The part
    Code (CSharp):
    1. Mathf.Repeat(offset4.x,1.0f)
    should ensure, that the water moves to a certain point and then restart at 0. In that special example above, the value of offset4.x starts at 0f, goes up to 1.0f and than starts at 0f again.
    This will be done for all of the 4 float values which are contained in the Vector4 called offsetClamped.
    This vector will be passed towards the shader by the line
    Code (CSharp):
    1. mat.SetVector("_WaveOffset", offsetClamped);
    The shader uses the _WaveOffset vector to move the water:
    Code (CSharp):
    1. // scroll bump waves
    2.     float4 temp;
    3.     float4 wpos = mul (unity_ObjectToWorld, v.vertex);
    4.     temp.xyzw = wpos.xzxz * _WaveScale + _WaveOffset;
    5.     o.bumpuv[0] = temp.xy * float2(.4, .45);
    6.     o.bumpuv[1] = temp.wz;

    It uses twice the normal map which is set in the shader settings and move it around with the given wave speed. One keeps the original orientation and one is rotated by 90° to get a distorting look of the water surface. To distort the look even more, one of the normal map position gets an additional modifier of
    Code (CSharp):
    1. * float2(.4, .45)
    And this is, which causes the problems.
    The one without the modifier
    Code (CSharp):
    1. o.bumpuv[1] = temp.wz;
    works fine with the loop from 0f to 1f out of the WaterBasic.cs script.
    The one with the modifier look like it is zoomed in and so the loop from 0f to 1f isn't working well for this one.

    Now there are two options to solve the issue:

    Number 1: Remove the modifier in the shader, so the new code should look like this:
    Code (CSharp):
    1.     // scroll bump waves
    2.     float4 temp;
    3.     float4 wpos = mul (unity_ObjectToWorld, v.vertex);
    4.     temp.xyzw = wpos.xzxz * _WaveScale + _WaveOffset;
    5.     o.bumpuv[0] = temp.xy;
    6.     o.bumpuv[1] = temp.wz;
    Number 2: Redefine the loop in the WaterBasic.cs script. There is a inversely proportional between the modifier in the shader and the end of the loop.
    Modifier = 1, End of the loop at 1f
    Modifier = 0.4, End of the loop at 2.5f
    Modifier = 0.45, End of the loop at 2.2222f
    So by keeping the modifier as is, the new line of code in the WaterBasic.cs script has to look like this:
    Code (CSharp):
    1. Vector4 offset4 = waveSpeed * (t * waveScale);
    2.             Vector4 offsetClamped = new Vector4(Mathf.Repeat(offset4.x, 2.5f), Mathf.Repeat(offset4.y, 2.2222f), Mathf.Repeat(offset4.z, 1.0f), Mathf.Repeat(offset4.w, 1.0f));
    3.  
    4.             mat.SetVector("_WaveOffset", offsetClamped);
    Cheers!