I'm confused because apparently symmetric functions in glsl sometimes include the unity_Scale parameter, and sometimes they don't. For example, from the the glslinc:
// Computes world space view direction
vec3 WorldSpaceViewDir( vec4 v )
{
return _WorldSpaceCameraPos.xyz - (_Object2World * v).xyz;
}
// Computes object space view direction
vec3 ObjSpaceViewDir( vec4 v )
{
vec3 objSpaceCameraPos = (_World2Object * vec4(_WorldSpaceCameraPos.xyz, 1.0)).xyz * unity_Scale.w;
return objSpaceCameraPos - v.xyz;
}
Why do we need unity_Scale in world->object, but not object->world?
_Object2World
is the transformation from object coordinates to world coordinates.
_World2Object * unity_Scale.w
is the transformation from world coordinates to object coordinates.
Unity sometimes (for non-uniform scale factors) scales the vertex coordinates before handing them to the shader. (Supposedly such that _Object2World is an orthogonal matrix.) For uniform scale factors, however, it doesn’t do this vertex scaling but integrates the scaling into _Object2World (making it a scaled orthogonal matrix). However, for some strange reason (and this is probably an inconsistency that just never got fixed and now too much code relies on it) this scaling was never included in _World2Object. Thus, you have to scale _World2Object with unity_Scale.w (if scale is important) but _Object2World is already scaled with the reciprocal factor.