Search Unity

[Released] Stylized Water Shader - Desktop/Mobile/VR

Discussion in 'Assets and Asset Store' started by StaggartCreations, Sep 8, 2016.

  1. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,488
    Can we make the shader 2 sided? I turned of zculling in Amplify shader editor but the underside of the water is black.
     
  2. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    1,651
    Do you mean this dropdown? Setting it to Off makes the shader double-sided
    upload_2021-10-5_14-41-29.png

    Though enabling this makes the underside appear identical on my end, so it being black may be attributed to a specific setting or lighting set up. Does this also occur in any of the demo scenes?
     
    protopop likes this.
  3. Braza

    Braza

    Joined:
    Oct 11, 2013
    Posts:
    107
    Hi! Would waves work with time scale = 0? They currently do not seem to. Also I've replaced _Time.x in the shader with _UnscaledTime param that I set from the script as
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         water.SetFloat("_UnscaledTime", Time.unscaledTime);
    4.     }
    but now water is pitch black...
    Also what are the requirements for foam to show up on intersection?
    Thanks.
    upload_2021-10-7_22-40-51.png
     
    Last edited: Oct 7, 2021
  4. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,488
    Thank you:) it's because I turned I off my sun when i am underwater to make things darker. I'm leaving my sun on but now my underwater scene is bright. Maybe I can use amplify to make the shader have a minimum amount of lighting so that it's never quite black, for artistic purposes. I'm glad you made it in amplify because that helps with the edits
     
  5. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    1,651
    Shader animation are also affected by the time scale, so this should work as expected. _Time.x technically unrolls to the same value as UnityEngine.Time.time. Little caveat: when not in play mode the time value is actually something different, don't know what.

    I believe under the hood, if the directional light is disabled, the render pipeline stops passing on any values to shaderland (eg. rotation, color and intensity). So leaving it enabled, but setting the color to black may work better. In terms of performance, it fortunately won't make any difference.
     
    protopop likes this.
  6. Braza

    Braza

    Joined:
    Oct 11, 2013
    Posts:
    107
    It worked though!

    Also, any advice regarding missing foam at intersection with a sphere?
     
    Last edited: Oct 9, 2021
  7. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    1,651
    The intersection foam effect is based on the scene's depth information. So generally for it to work the "Enable Depth Buffer" script needs to be attached to the camera (not needed when using Deferred rendering) and the scene objects need to use a material/shader that writes to the depth texture. This is almost always the case except for unlit and transparent materials.
     
    Braza likes this.
  8. Braza

    Braza

    Joined:
    Oct 11, 2013
    Posts:
    107
    Yay, I use unlit materials indeed. Thanks for pointing this out.
     
  9. Braza

    Braza

    Joined:
    Oct 11, 2013
    Posts:
    107
    Hi again :)
    I'm using the water in a top-down 2d project (unlit, orthographic camera, mobile shader)
    upload_2021-10-20_23-31-59.png
    But from time to time while running on mobile phones I get areas with transparency after ~0.1 - 1 minute. Yellow color is the camera background color therefore I think water is becoming transparent. It happens only on mobile and never in the PC Player.
    upload_2021-10-20_23-30-19.png
    Any thoughts on that?
     
  10. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    1,651
    If time is a factor, it's usually an indication that the shader is running into floating point errors, due to the limited precision of the device's GPU. Though, this varies per device, it could take minutes or even days. Nevertheless, some measures are already taken in the shader to prevent this, otherwise it turns pixellated over time.

    Off the bat, I can't think of any aspect that can cause transparency to be affected. Is the yellow color not from the underlying terrain? Seeing as shadows are being casts onto something.

    If you are willing to send me the material you're using (right-click->Export package) I can try to reproduce it on an old device.
     
  11. Braza

    Braza

    Joined:
    Oct 11, 2013
    Posts:
    107
    Attaching the material.
    Yellow is from the camera background.
    upload_2021-10-22_3-19-54.png
    This effect depends on Waves Height parameter. If it is 0, then water gets totally yellow. If it is > 0 then the water has this polygonal effect. I've changed the value and now it looks like:
    upload_2021-10-22_3-22-17.png
    And I've noticed it happens after the first tap on the water, not over time. Could raycasts interfere with the shader somehow? Like EventSystem.current.RaycastAll?

    Please note that I've modified the code to support unscaled time:
    Code (CSharp):
    1. #region Reflection/Refraction render functions
    2.         public void OnWillRenderObject()
    3.         {
    4.             if (!enabled || !material)
    5.             {
    6.                 return;
    7.             }
    8.  
    9.             Camera cam = Camera.current;
    10.             if (!cam)
    11.             {
    12. #if UNITY_EDITOR
    13.                 currentCam = null;
    14. #endif
    15.                 return;
    16.             }
    17.  
    18. #if UNITY_EDITOR
    19.             currentCam = cam;
    20. #endif
    21.             Shader.SetGlobalFloat("_Unscaled", Time.unscaledTime);
    to pass it to the shader

    Code (CSharp):
    1. uniform float _Unscaled;
    2.  
    3.         void vertexDataFunc( inout appdata_full v, out Input o )
    4.         {
    5.             UNITY_INITIALIZE_OUTPUT( Input, o );
    6.             float3 ase_vertexNormal = v.normal.xyz;
    7.             float4 VertexColors729 = lerp(float4( 0,0,0,0 ),v.color,_ENABLE_VC);
    8.             float3 ase_worldPos = mul( unity_ObjectToWorld, v.vertex );
    9.             float2 Tiling21 = lerp(( -20.0 * v.texcoord.xy ),( (ase_worldPos).xz * float2( 0.1,0.1 ) ),_Worldspacetiling);
    10.             float2 appendResult500 = (float2(_WaveDirection.x , _WaveDirection.z));
    11.             float2 WaveSpeed40 = ( ( _Wavesspeed * _Time.x + _Wavesspeed * _Unscaled ) * appendResult500 );
    12.             float2 HeightmapUV581 = ( ( ( Tiling21 * _WaveSize ) * float2( 0.1,0.1 ) ) + ( WaveSpeed40 * float2( 0.5,0.5 ) ) );
    13.             float4 tex2DNode94 = tex2Dlod( _Shadermap, float4( HeightmapUV581, 0, 1.0) );
    14.             float temp_output_95_0 = ( saturate( ( _WaveHeight - (VertexColors729).b ) ) * tex2DNode94.g );
    15.             float3 Displacement100 = ( ase_vertexNormal * temp_output_95_0 );
    16.             v.vertex.xyz += Displacement100;
    17.             o.vertexToFrag713 = lerp(( -20.0 * v.texcoord.xy ),( (ase_worldPos).xz * float2( 0.1,0.1 ) ),_Worldspacetiling);
    18.             o.vertexToFrag714 = ( ( _Wavesspeed * _Time.x + _Wavesspeed * _Unscaled) * appendResult500 );
    19.             #if defined(LIGHTMAP_ON) && ( UNITY_VERSION < 560 || ( defined(LIGHTMAP_SHADOW_MIXING) && !defined(SHADOWS_SHADOWMASK) && defined(SHADOWS_SCREEN) ) )//aselc
    20.             float4 ase_lightColor = 0;
    21.             #else //aselc
    22.             float4 ase_lightColor = _LightColor0;
    23.             #endif //aselc
    24.             o.vertexToFrag746 = ase_lightColor.rgb;
    25.         }
     
    Last edited: Oct 22, 2021
  12. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    1,651
    Ah right, that makes sense. Both _Time and _Unscaled are values that keep adding up, which amounts to a very large number when combined, beyond the capabilities of the hardware. If I'm not mistaken, you could simply replace _Time.x with _Unscaled instead. If the goal is to have the wave animation ignore the time-scale, that should do the trick.

    Physics should not interfere with any rendering, since there is no communication between the two aspects. Though one thing to check is if the camera's far clipping plane value is as low as possible, which is particularly important on mobile, to increase the accuracy of depth rendering:
    upload_2021-10-22_10-51-36.png

    In your package, you've inadvertently included the water shader file, if you could edit your post and remove it, that'd be appreciated!
     
    Braza likes this.
  13. Braza

    Braza

    Joined:
    Oct 11, 2013
    Posts:
    107
    Thanks for the help! It was camera clipping indeed, but it was far plane somehow, not near plane. Still not sure how is this specific to mobile and input systems but increasing far plane worked!
     
  14. daochihao98

    daochihao98

    Joined:
    Apr 16, 2020
    Posts:
    5
    Is it possible to create a round wave effect at a specific point?
    1.jpg
     
  15. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    1,651
    The short answer would be, no, that's not possible. Possibly in the future through the means of injection normal map stamps/decal into the water surface.
     
  16. daochihao98

    daochihao98

    Joined:
    Apr 16, 2020
    Posts:
    5
    Oke, thanks for your response. I have one more question. I'm writing a post-processing underwater effect, Is there any way I can retrieve the water height at a specific point? I know I can just use the transform.y but it's not precise enough, especially when I'm using y-scale for big waves
     
unityunity