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 Jun 26 '15 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 Jun 26 '15 at 17:59
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\$

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.