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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

calculate water depth under pixel?

Discussion in 'Shaders' started by battou, Mar 12, 2015.

  1. battou

    battou

    Joined:
    Jan 25, 2011
    Posts:
    197
    Im wrighting water shader and need to calculate depth of water under pixel. I can calculate water view depth by comparing pixel screen depth with camera depth texture, but it is depending on view angle. Is there any way to calculate distance from pixel to bottom along some normal vector? Shader raycast?)
     
  2. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    It is indeed depending on the view angle. Just normalize the view vector and multiply the distance between the water and ground with the y component of the normalized view vector.

    (You get the view vector by taking the difference between the pixel position and the camera position.)

    In pseudo code:
    Code (csharp):
    1.  
    2. float3 view = normalize(camera - position);
    3. float water_distance = depth_buffer - depth_current;
    4. float water_depth = water_distance * view.y;
    5.  
     
  3. battou

    battou

    Joined:
    Jan 25, 2011
    Posts:
    197
    Hm.. But it will still vary depending on view distance, even if less, right? For example if depth buffer inthis screen pos is infinity or seafloor is slope up?
     
  4. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    It will give you the distance straight up from the ground you're looking at to the water surface.

    If there is a hole in your model, it will of course not work. Just fix the hole in that case ;-)
     
  5. battou

    battou

    Joined:
    Jan 25, 2011
    Posts:
    197
    But ground point on depth texture wont be right under the water. For example if Camera look from the water towards the beach Ill get point on the ground almost near the edge of water, but point on water in this screen point will be closer to the camera thus farther from the edge of water, but view y will be less then 1 so depth will be even lover then distance from water point to ground point, but real depth under water would be greater.
     
  6. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Well, this is the amount of water straight up from the ground. Obtaining the amount of water straight down from the water surface is a lot trickier.
     
  7. battou

    battou

    Joined:
    Jan 25, 2011
    Posts:
    197
    But I need ammount of water straight down under water point. Any, even complex way to get it without another camera?
     
  8. varfare

    varfare

    Joined:
    Feb 12, 2013
    Posts:
    227
    Good depth sampling example is included in soft particles code. Take a look at "projPos". Vertex program outputs depth information into it.

    Code (CSharp):
    1. Shader "Particles/Alpha Blended" {
    2. Properties {
    3.     _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
    4.     _MainTex ("Particle Texture", 2D) = "white" {}
    5.     _InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
    6. }
    7.  
    8. Category {
    9.     Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    10.     Blend SrcAlpha OneMinusSrcAlpha
    11.     AlphaTest Greater .01
    12.     ColorMask RGB
    13.     Cull Off Lighting Off ZWrite Off
    14.  
    15.     SubShader {
    16.         Pass {
    17.        
    18.             CGPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             #pragma multi_compile_particles
    22.            
    23.             #include "UnityCG.cginc"
    24.  
    25.             sampler2D _MainTex;
    26.             fixed4 _TintColor;
    27.            
    28.             struct appdata_t {
    29.                 float4 vertex : POSITION;
    30.                 fixed4 color : COLOR;
    31.                 float2 texcoord : TEXCOORD0;
    32.             };
    33.  
    34.             struct v2f {
    35.                 float4 vertex : SV_POSITION;
    36.                 fixed4 color : COLOR;
    37.                 float2 texcoord : TEXCOORD0;
    38.                 #ifdef SOFTPARTICLES_ON
    39.                 float4 projPos : TEXCOORD1;
    40.                 #endif
    41.             };
    42.            
    43.             float4 _MainTex_ST;
    44.  
    45.             v2f vert (appdata_t v)
    46.             {
    47.                 v2f o;
    48.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    49.                 #ifdef SOFTPARTICLES_ON
    50.                 o.projPos = ComputeScreenPos (o.vertex);
    51.                 COMPUTE_EYEDEPTH(o.projPos.z);
    52.                 #endif
    53.                 o.color = v.color;
    54.                 o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
    55.                 return o;
    56.             }
    57.  
    58.             sampler2D_float _CameraDepthTexture;
    59.             float _InvFade;
    60.            
    61.             fixed4 frag (v2f i) : SV_Target
    62.             {
    63.                 #ifdef SOFTPARTICLES_ON
    64.                 float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
    65.                 float partZ = i.projPos.z;
    66.                 float fade = saturate (_InvFade * (sceneZ-partZ));
    67.                 i.color.a *= fade;
    68.                 #endif
    69.                
    70.                 return 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord);
    71.             }
    72.             ENDCG
    73.         }
    74.     }  
    75. }
    76. }
    77.  
     
  9. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    Not in a reliable way. The solution would need another camera to render the depth so it can be looked up.
     
  10. battou

    battou

    Joined:
    Jan 25, 2011
    Posts:
    197
    I thought so. Thanks to you all.)
     
  11. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    old thread but any one facing this problem, you could just use a height map and get the depth from there then apply it to the view distance.
     
  12. Henry_Sun

    Henry_Sun

    Joined:
    Jun 1, 2019
    Posts:
    23
    Don't mean to necropost this.
    I believe " straight up from the ground" depth B is more realistic than " straight down from the water" depth A, if you have a thought about how the light travels. Especially in a clear transparent water, the look of the seabed is mostly affected by the light from Point Q above him, and reflect them into our eyes. Not the Point P.
    Snipaste_2021-08-19_11-03-20.png
    And the distance is also a factor that links to absorption. If the view is almost parallel with the water surface ,the distance will be really large and result an dark absorbed color. That will make sense.
     
  13. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    It depends on what you're doing really. I agree that for most visual aspects you'd want depth B, but the original author was looking for depth A. One thing that comes to my mind that is related to depth A is the height of the waves at the water surface. So it's not completely uncommon to use depth A (besides depth B.)