An example i thought up consists like this;
one script attached to the player which will check for all fadeable objects at start, by checking if they have a tag “Fadeable”
on each update for all objects within range it will create a float based on minimum and maximum clip distances
this float will be assigned to all detected objects using renderer.material.SetFloat, to the shader’s _Fader value I added.
It’s probably not the cleanest example, but it seems quite lightweight and can be added to most shaders without a lot of hassle.
Shader Code:
ANY shader that uses a _Fader value can be used.
Shader "Custom/ProximityFade" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_Fader ("Fader Slider", Float) = 0
_MinOpacity ("Minimum Opacity", Range(0,1)) = 0.1
}
SubShader {
Tags { "Queue"="Transparent" "RenderType"="Transparent" }
LOD 200
ZWrite Off
ZTest Less
Cull Back
CGPROGRAM
#pragma surface surf Lambert alpha
sampler2D _MainTex;
float _Fader;
float _MinOpacity;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
_Fader = max(_MinOpacity,_Fader);
o.Alpha = c.a*_Fader;
}
ENDCG
}
FallBack "Diffuse"
}
Script Code: [Scriptname: Fader.cs]
This is best attached to the camera or a scene manager of some sort.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Fader : MonoBehaviour {
public bool UseFadeableTags;
public Transform playerobject;
public Shader fadeshader;
public float MinClip = 0.5f;
public float MaxClip = 2f;
private List<Transform> FadeableObjects;
private Vector2 sqrdist;
bool inRange(Transform firstTransform, Transform otherTransform, float distance)
{
return (firstTransform.position - otherTransform.position).sqrMagnitude < distance * distance;
}
bool inPlayerRange(Transform target, float distance)
{
return (playerobject.position - target.position).sqrMagnitude < distance*distance;
}
// Use this for initialization
void Start () {
if (GameObject.Find("Player"))
playerobject = GameObject.Find("Player").transform;
FadeableObjects = new List<Transform>();
GameObject[]go;
if (UseFadeableTags == true)
{
go = GameObject.FindGameObjectsWithTag("Fadeable"); //looked up by tag
}
else
{
go = UnityEngine.GameObject.FindObjectsOfType(typeof(GameObject)) as GameObject[]; // iterating through ALL objects
}
if (fadeshader != null) // if fadeshader is selected
{
foreach(GameObject FadeableObject in go)
{
if (FadeableObject.renderer){
if (FadeableObject.renderer.material.shader == fadeshader)
FadeableObjects.Add(FadeableObject.transform);
}
}}
else // if no fadeshader is selected:
{
foreach(GameObject FadeableObject in go)
{
FadeableObjects.Add(FadeableObject.transform);
Debug.Log("Added "+FadeableObject.name);
}
}
sqrdist = new Vector2(MinClip*MinClip, MaxClip*MaxClip);
}
// Update is called once per frame
void Update () {
foreach(Transform FadeableObject in FadeableObjects)
{
if (inPlayerRange(FadeableObject,sqrdist.y))
{
float FadeValue = Mathf.InverseLerp(sqrdist.x,sqrdist.y,(FadeableObject.position - playerobject.position).sqrMagnitude);
FadeableObject.renderer.material.SetFloat("_Fader", FadeValue);
}
}
}
}
Hope it’ll help you out a bit 
This method is mostly based on an object’s transform position, but i’d guess it’s a quite effective method for objects which aren’t too big of a size.The script could always be modified further for additional checks
I also put a webdemo online;
www.annihlator.nl/Unity/Shared/Faderweb/FaderWeb.html
EDIT:
I know you preferred a way without scripts, but I believe this is a lightweight method because;
- When you use Tags, it will only make an array of the objects which can be faded at all.
- It only uses a (relatively) cheap comparison of positions between the objects which could possibly be faded (so no distances calculated of other surfaces, also due to the shader selector)
- it does not rely on any triggers or colliders
possible downside as i said above can be accuracy.