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

Water Volume Shader

Discussion in 'Shaders' started by asdfghjkloi87654, Jun 12, 2021.

  1. asdfghjkloi87654

    asdfghjkloi87654

    Joined:
    Feb 16, 2013
    Posts:
    43
    Hello everyone,

    I want to render water volumes, like cubes of water with a depth gradient effect. I started with a shader from catlike coding, that reads the _CameraDepthTexture, provided by Unity and applies some fog, according to the depth of the previously rendered scene. Additionaly the shader uses a GrabPass to add refraction effects.

    catlike1.jpg

    This works well so far. You'll find the source here: https://catlikecoding.com/unity/tutorials/flow/looking-through-water/

    Adding this excact shader to a water cube creates problems however. The Background is very far away and this makes the depth fog very strong. The cube is opaque although it is not a very thick water volume.

    cube_basic.jpg

    This shader runs in the transparent quene, including the GrabPass. I wrote a second shader on a second material, rendering on the geometry quene. This shader culls the front (outside) and renders only the inside cube.

    I am currently using a ShadowCaster pass to write the depth texture before the depth fog reads it. I works well, however it interferes with the shadows in a weired way. this is why I don't want to use the ShadowCaster pass.

    cube_depth.jpg

    Below my backside shader. It should only write to depth. I don't want shadows at all.

    Code (CSharp):
    1. Shader "Custom/ack"
    2. {
    3.     Properties
    4.     {
    5.         _Color("Color", Color) = (1,1,1,1)
    6.         _MainTex("Albedo (RGB)", 2D) = "white" {}
    7.         _Glossiness("Smoothness", Range(0,1)) = 0.5
    8.         _Metallic("Metallic", Range(0,1)) = 0.0
    9.     }
    10.         SubShader
    11.         {
    12.             //back side pass
    13.                     Tags { "RenderType" = "Opaque" "Queue" = "Geometry"}
    14.                     LOD 200
    15.  
    16.             Cull Front
    17.             ZWrite On
    18.             Blend SrcAlpha OneMinusSrcAlpha
    19.  
    20.             Pass
    21.         {
    22.             Tags {"LightMode" = "ShadowCaster"}
    23.  
    24.             CGPROGRAM
    25.             #pragma vertex vert
    26.             #pragma fragment frag
    27.             #pragma multi_compile_shadowcaster
    28.             #include "UnityCG.cginc"
    29.  
    30.             struct v2f {
    31.                 V2F_SHADOW_CASTER;
    32.             };
    33.  
    34.             v2f vert(appdata_base v)
    35.             {
    36.                 v2f o;
    37.                 TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
    38.                 return o;
    39.             }
    40.  
    41.             float4 frag(v2f i) : SV_Target
    42.             {
    43.                     SHADOW_CASTER_FRAGMENT(i)
    44.             }
    45.             ENDCG
    46.         }
    47. }
    48. }
     
  2. Arycama

    Arycama

    Joined:
    May 25, 2014
    Posts:
    182
    Seeing as you're rendering a box, you can do a ray-box intersection to find the endpoint of the ray, and use that as your water distance, if it is closer than the background (Depth), its easier than messing around with depth for this particular case.
     
  3. asdfghjkloi87654

    asdfghjkloi87654

    Joined:
    Feb 16, 2013
    Posts:
    43
    I don't quite understand how I can get this running in a shader. Additionally, the box is just a test. Eventually the shape will be arbitrary.