colorize mesh based on dot product

Assuming that we have an object and a 3D mesh. Is it possible to colorize the 3D mesh based on the value of the dot product produced when using the position of the 3D object and the normals of the mesh?

Well, writing a shader for that is quite simple. Here’s an example:

// ColorizeMesh.shader
Shader "Custom/ColorizeMesh" {
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
		_Color2 ("Color2", Color) = (1,1,1,1)
		_ObjectPos ("ObjectPos", vector) = (1,1,1)
		_MainTex ("Albedo (RGB)", 2D) = "white" {}
		_Glossiness ("Smoothness", Range(0,1)) = 0.5
		_Metallic ("Metallic", Range(0,1)) = 0.0
	SubShader {
		Tags { "RenderType"="Opaque" }
		LOD 200
		// Physically based Standard lighting model, and enable shadows on all light types
		#pragma surface surf Standard fullforwardshadows

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

		sampler2D _MainTex;

		struct Input {
			float2 uv_MainTex;
			float3 worldPos;

		half _Glossiness;
		half _Metallic;
		fixed4 _Color;
		fixed4 _Color2;
		float3 _ObjectPos;

		void surf (Input IN, inout SurfaceOutputStandard o) {
			// Albedo comes from a texture tinted by color
			fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
			float3 dir = _ObjectPos - IN.worldPos;
			float t = 0.5 + sign(dot(dir, o.Normal))*0.5;
			o.Albedo = c.rgb * lerp(_Color2.rgb, _Color.rgb, t);
			// Metallic and smoothness come from slider variables
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
			o.Alpha = c.a;
	FallBack "Diffuse"

This shader has an additional color property which is used when the triangle faces away from the given object. It also has an _ObjectPos property which need to be set via script to your desired object.

This can be done with a script like this:

// SetObjectPosition.cs
using UnityEngine;
using System.Collections;

public class SetObjectPosition : MonoBehaviour
    public Transform target;
    private Material mat;
    int id = -1;
    void Start()
        var rend = GetComponent<Renderer>();
        if (rend != null)
            mat = rend.material;
            id = Shader.PropertyToID("_ObjectPos");

	void Update ()
        if (target != null && mat != null)
            mat.SetVector(id, target.position);

The object with the mesh should simply use a Material that uses the shader above. In addition just add the script to the same object. Don’t forget to drag and drop your “other object” in the target variable of the script. In the material you can set the two colors to whatever you like. “Color” is the color that is facing the object, Color2 is the color that is facing away from the object.