Unity Shader for Generating Annotation Image

Game scene:

  • Attach the 2nd (normal view) and 3rd (segmentation view) cameras to the game scene
  • Create Renderer Target x2 to receive images from the cameras
  • Create UI/Raw Image to show the images from the cameras

The segmentation view camera: attach the below script

using UnityEngine;
[ExecuteInEditMode]
public class ReplacementShaderTest : MonoBehaviour
{
    private Camera _camera;
    private Shader _shader;
    void OnEnable()
    {
        _camera = GetComponent<Camera>();
        _shader = Shader.Find("ReplaceObjectColorInCameraView");
        _camera?.SetReplacementShader(_shader, "Annotation");

    }
    private void OnDisable()
    {
        _camera?.ResetReplacementShader();
    }
}

We will have the below shader code in Assets folder. It is called by ReplaceObjectColorInCameraView.cs. It will check the Annotation tag set in another script and change the gameobject material color.

Shader "ReplaceObjectColorInCameraView"
{
	SubShader
	{
		Tags { "Annotation" = "green" }
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			float4 vert(float4 vertex : POSITION) : SV_POSITION
			{
				return UnityObjectToClipPos(vertex);
			}
			fixed4 frag() : SV_Target
			{
				return fixed4(0, 1, 0, 1); //green
			}
			ENDCG
		}
	}
	SubShader
	{
		Tags { "Annotation" = "red" }
		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

			float4 vert(float4 vertex : POSITION) : SV_POSITION
			{
				return UnityObjectToClipPos(vertex);
			}
			fixed4 frag() : SV_Target
			{
				return fixed4(1, 0, 0, 1); //red
			}
			ENDCG
		}
	}
}

At any gameobject, attach the below code to set an annotation tag.
A gameobject may contain many materials or has a material attached in its child object.

using System.Collections.Generic;
using System.Linq;
using UnityEngine;

[ExecuteInEditMode]
public class SetShaderTagsAnnotation : MonoBehaviour
{
    public enum AnnotationType
    {
        green, red
    }
    public AnnotationType annotation_name; 

    void Start()
    {
         List<Material> list_material = obj.GetComponent<Renderer>().materials.ToList();
         foreach (Material mat in list_material)
         {
             mat.SetOverrideTag("Annotation", annotation_name.ToString());
         }
         ApplyAnnotation(gameObject.transform);
    }
    void ApplyAnnotation(Transform obj)
    {
        Renderer myRenderer = obj.GetComponent<Renderer>();
        if (myRenderer != null)
        {
            myRenderer.material.SetOverrideTag("Annotation", annotation_name.ToString());
            //Debug.Log(obj.name + " is set to " + annotation_name.ToString());
        }
        else
        {
            //Debug.Log(obj.name + " has no Renderer component");
            TraverseHierarchy(obj.transform);
        }
    }

    void TraverseHierarchy(Transform parent)
    {
        //Debug.Log("TraverseHierarchy of " + parent.name);
        foreach (Transform child in parent)
        {
            ApplyAnnotation(child);
        }
    }