2
\$\begingroup\$

I'm currently attempting to create a cartoon-ish water shader with a shoreline. After looking around trying to find out how other games do it i figured out it has something to do with getting the distance from the depth map (which doesn't include the water when it's render queue is set to transparent) and the and the world position of the current pixel.

From certain angles i'm actually getting very close to the desired result as show here: enter image description here

The topmost island almost has the desired result, but as you can tell, the closer it gets to the camera, the more out of place the effect becomes.

here's a zoomed out top down view illustrating the problem enter image description here

as per request, here's what the terrain looks like beneath the water surface (animated gif) enter image description here and of course, here is my shader code:

Shader "Custom/CartoonWater" {
 Properties {
     _Color ("Color", Color) = (1,1,1,1)
     _Glossiness("Smoothness", Range(0,1)) = 0.5
     _ShoreFade("Shoreline Distance", Float) = 1
 }
 SubShader {
         Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
     LOD 200

     CGPROGRAM
     // Physically based Standard lighting model, and enable shadows on all light types
     #pragma surface surf StandardSpecular     

     // Use shader model 3.0 target, to get nicer looking lighting
     #pragma target 3.0

     sampler2D _CameraDepthTexture;

     struct Input {
         float3 worldPos;
         float4 screenPos;
     };

     half _Glossiness;
     fixed4 _Color;
     float _ShoreFade;

     void surf (Input IN, inout SurfaceOutputStandardSpecular o) {

         o.Albedo = _Color.rgb;
         o.Smoothness = _Glossiness;

         fixed4 depth = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));

         o.Albedo = _Color;
         if (distance(LinearEyeDepth(depth), distance(_WorldSpaceCameraPos, IN.worldPos)) < _ShoreFade) {
             o.Albedo = fixed4(1, 1, 1, 1);
         }

     }
     ENDCG
 }
 FallBack "Diffuse"
 }

any help is greatly appreciated :) thanks in advance.

\$\endgroup\$
  • \$\begingroup\$ Can you post screenshots of what is under the water? (The heightmap might give us a more thorough understanding of the problem) \$\endgroup\$ – John Hamilton Mar 17 '17 at 9:00
  • \$\begingroup\$ If you are trying to find the depth of shore, why are you using position of camera and screen? \$\endgroup\$ – AaA Mar 17 '17 at 9:44
  • \$\begingroup\$ @JohnHamilton I added the image you requested \$\endgroup\$ – Daniel Holst Mar 17 '17 at 10:31
  • \$\begingroup\$ I have a few ideas to test out but nothing solid. Let's discuss it here: chat.stackexchange.com/rooms/55522/… \$\endgroup\$ – John Hamilton Mar 17 '17 at 10:59
3
\$\begingroup\$

After much trial and error and Google-fu, I've come across a texture blend shader that gave a similar effect to what you wanted. After a bit of tinkering I've achieved a satisfactory result.

What this shader does, is that it blends the mesh right below itself and it'd normally add some sort of transparency effect to the material. I've modified the values of the result and instead of making it more transparent as it got closer to the object, I've increased its colors. You could just set the colors to white instead too.

Here's the shader I've used:

Shader "Custom/SurfaceDepthTextureColorized" {
    Properties{
        _Color("Color", Color) = (1,1,1,1)
        _BlendColor("Blend Color", Color) = (1,1,1,1)
        _MainTex("Albedo (RGB)", 2D) = "white" {}
    _Glossiness("Smoothness", Range(0,1)) = 0.5
        _Metallic("Metallic", Range(0,1)) = 0.0
        _InvFade("Soft Factor", Range(0.01,3.0)) = 1.0
        _FadeLimit("Fade Limit", Range(0.00,1.0)) = 0.3
    }
        SubShader{
        Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard vertex:vert alpha:fade nolightmap

        // Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0

        sampler2D _MainTex;

    struct Input {
        float2 uv_MainTex;
        float4 screenPos;
        float eyeDepth;
    };

    half _Glossiness;
    half _Metallic;
    fixed4 _Color;
    fixed4 _BlendColor;
    sampler2D_float _CameraDepthTexture;
    float4 _CameraDepthTexture_TexelSize;

    float _FadeLimit;
    float _InvFade;

    void vert(inout appdata_full v, out Input o)
    {
        UNITY_INITIALIZE_OUTPUT(Input, o);
        COMPUTE_EYEDEPTH(o.eyeDepth);
    }

    void surf(Input IN, inout SurfaceOutputStandard o) {
        // Albedo comes from a texture tinted by color
        fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
        o.Albedo = c.rgb;
        // Metallic and smoothness come from slider variables
        o.Metallic = _Metallic;
        o.Smoothness = _Glossiness;

        float rawZ = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));
        float sceneZ = LinearEyeDepth(rawZ);
        float partZ = IN.eyeDepth;

        float fade = 1.0;
        if (rawZ > 0.0) // Make sure the depth texture exists
            fade = saturate(_InvFade * (sceneZ - partZ));
        //o.Alpha = c.a * fade; //(original line)
        //the rest are lines I've input
        o.Alpha = 1;
        if(fade<_FadeLimit)
        o.Albedo = c.rgb * fade + _BlendColor * (1 - fade);
    }
    ENDCG
    }
}

Here are the results; soft factor 0.15, fade limit 1:

enter image description here

soft factor 0.05, fade limit 0.05:

enter image description here

Finally, thanks to @DanielHolst for chatting with me on the matter, I would've just gotten bored at some point if he didn't work with me on this.

\$\endgroup\$
  • 1
    \$\begingroup\$ Yay teamwork !! \$\endgroup\$ – Daniel Holst Mar 17 '17 at 15:58
  • \$\begingroup\$ Nice this is what I was looking for. However it renders completely black when I try to use this shader. Any idea why ? Thanks. \$\endgroup\$ – Virus721 Mar 9 '18 at 12:01
  • \$\begingroup\$ @Virus721 Seems like you need to construct an actual question and post it on the site. I can't really help you at all since I would need a ton of details and I might not even have time to go through it all. \$\endgroup\$ – John Hamilton Mar 9 '18 at 12:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.