_World2Object confusion

Hello everybody,

I am trying to do a special type of lighting where all scene objects are lighted up only at certain distance from light source. I am not using a real light, but a GameObject which position is passed to shader. The problem, is that I can’t transform “light” position from World space to Object space. In my case GameObject is at (0,0,0) and I can see that scene acts like light source is at (0,0,0) of every object.

Shader "blind" {
   Properties {
	  _Le ("_Le", Vector) = (10.0,12.0,0,0)
	}
	SubShader {
    Pass {

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

struct v2f {
    V2F_POS_FOG;
	float3 p;
	float distance;
};

float4 _Le;

v2f vert (appdata_base v)
{
    v2f o;
    o.pos = mul( glstate.matrix.mvp, v.vertex ); 
    o.p  = v.vertex.xyz;
    return o;
}

half4 frag (v2f i) : COLOR
{

	float4 soundPosWorld = float4(0.0,0.0,0.0,0.0); // This is coordinates of "light" source
	float4 soundPos = mul( _World2Object, float4(soundPosWorld, 1.0) );

	float distance = sqrt((i.p.x - soundPos.x) * (i.p.x - soundPos.x) + (i.p.y - soundPosWorld.y) * (i.p.y - soundPos.y) + (i.p.z - soundPos.z) * (i.p.z - soundPos.z));

	float3 color = float3(1.0, 1.0, 1.0);

	if (distance > _Le.x) { 
		if (distance < _Le.y) {
			color.r = 0.5;
			color.g = 0.745;
			color.b = 0.88;
		} 
	}
	
	if (distance < _Le.x) { 
		if (distance > (_Le.x - 0.1)) {
			color.r = 0.0;
			color.g = 0.5;
			color.b = 0.0;
		}
	}
	
	if (distance > _Le.y) { 
		if (distance < (_Le.y+0.1)) { 
			color.r = 0.5;
			color.g = 0.0;
			color.b = 0.0;
		}
	}

    return half4( color, 1 );
}
ENDCG

 Lighting Off

    }
}

}

Btw, can distance be calculated in a more elegant way?

With a great help of ToreTank this issue is solved.