5
\$\begingroup\$

In 3d space, objects can be occluded by another objects.
By depth testing, the occluded faces are skipped rendering. Only the nearest(smallest) depth value pixels are drawn. But, sometime we need to render the occluded object or pixels for game play.

To differentiate the occluded object's pixels from foreground pixels, some game use gray color to render the pixels.


This is the sample images for the case.


enter image description here

enter image description here

I guess this can be achieved by some sort of shader.
How can I make this effects in Unity 3D Engine? Any hints or idea plz.



\$\endgroup\$
2
  • \$\begingroup\$ Something like if the z-test fails draw a gray pixel in front. I suspect some z-Buffer trick. \$\endgroup\$
    – aggsol
    Commented Jun 26, 2015 at 13:37
  • 1
    \$\begingroup\$ You can make this effect with a custom shader that has two passes, one for ZTest greater(rendered with color or a silhouette), one for ZTest less or equal where you render that part normally. \$\endgroup\$
    – nexx
    Commented Jun 26, 2015 at 17:59

2 Answers 2

1
\$\begingroup\$

I followed @nexx's comment.
and made a 2 pass surface shader which give colors to hidden pixels.

You can use built-in light function or Unlit version(commented).
Hope this help for others finding this kinds of effects.

Shader "Test/HiddenPixelColoring" {
   Properties {
      _MainTex ("Texture", 2D) = "white" { }
   }

   SubShader {
      ////////////////////////////////////////////////////////////
      // Pass #1 

      Tags {"Queue" = "Geometry" "RenderType" = "Opaque" }

      CGPROGRAM

      #pragma target 3.0
      #pragma surface surf BlinnPhong

      struct Input {
         float2 uv_MainTex;
      };

      sampler2D _MainTex;

      void surf (Input IN, inout SurfaceOutput o) {
         o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
      }

      ENDCG

      ////////////////////////////////////////////////////////////
      // Pass #2 
      ZTest Greater

      CGPROGRAM

      #pragma target 3.0
      #pragma surface surf Lambert //lambertian reflectance lighting version
      //#pragma surface surf NoLighting //no lighting version

      struct Input {
        float4 color : COLOR;
      };

     /*
     //Lambertian reflectance lighting version
     fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, fixed atten)
     {
         fixed4 c;
         c.rgb = s.Albedo; 
         c.a = s.Alpha;
         return c;
     }
     */

      void surf (Input IN, inout SurfaceOutput o) {
         o.Albedo = float3(1.0, 0.0, 0.5);
      }

      ENDCG
   }

    Fallback "Diffuse"
}

hidden pixel coloring shader #1 hidden pixel coloring shader #2
hidden pixel coloring shader #3 hidden pixel coloring shader #4

\$\endgroup\$
0
\$\begingroup\$

What you are describing is not occlusion. Your objects in the image are rendered but are overwritten by the other object because of a higher Z depth.

What you are trying to achieve could be done using a shader that nexx mentioned earlier. For example this one could help you: http://forum.unity3d.com/threads/trying-to-make-a-silhouette-outline-shader.96005

you might need to modify it so that it won't display anything when the objects are visible. (There is an offset in the shader about the extrude value)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .