Hey all, I’ve followed this thread Problem Solving: 2D Billboard Sprites clipping into 3D environment - #68 by claudio04 religiously for the past year or so while developing my game. It helped me fix the issues reported on the thread but now I’ve got another issue when rotating the camera and didn’t want to revive that old thread.
If the camera is “centered”/facing north, the sprites render normally
However as soon as I start rotating the camera I can see some displacement

Here’s a 360 video:
And this is how I have my shader
float rayPlaneIntersection(float3 rayDir, float3 rayPos, float3 planeNormal, float3 planePos)
{
float denom = dot(planeNormal, rayDir);
denom = max(denom, 0.000001);
float3 diff = planePos - rayPos;
return dot(diff, planeNormal) / denom;
}
float4 billboardMeshTowardsCamera(float3 vertex, float4 offset, float4 uv)
{
// billboard mesh towards camera
float3 vpos = mul((float3x3)unity_ObjectToWorld, vertex.xyz);
float4 worldCoord = float4(unity_ObjectToWorld._m03_m13_m23, 1);
float4 viewPivot = mul(UNITY_MATRIX_V, worldCoord);
// construct rotation matrix
float3 forward = -normalize(viewPivot);
float3 up = mul(UNITY_MATRIX_V, float3(0,1,0)).xyz;
float3 right = normalize(cross(up,forward));
up = cross(forward,right);
float3x3 facingRotation = float3x3(right, up, forward);
float4 viewPos = float4(viewPivot + mul(vpos, facingRotation), 1.0);
float4 pos = mul(UNITY_MATRIX_P, viewPos + offset);
// calculate distance to vertical billboard plane seen at this vertex's screen position
const float3 planeNormal = normalize((_WorldSpaceCameraPos.xyz - unity_ObjectToWorld._m03_m13_m23) * float3(1,0,1));
const float3 planePoint = UNITY_MATRIX_M._m03_m13_m23;
const float3 rayStart = _WorldSpaceCameraPos.xyz;
const float3 rayDir = -normalize(mul(UNITY_MATRIX_I_V, float4(viewPos.xyz, 1.0)).xyz - rayStart);
float dist = rayPlaneIntersection(rayDir, rayStart, planeNormal, planePoint);
// calculate the clip space z for vertical plane
float4 planeOutPos = mul(UNITY_MATRIX_VP, float4(rayStart + rayDir * dist, 1.0));
float newPosZ = planeOutPos.z / planeOutPos.w * pos.w;
// use the closest clip space z
#if defined(UNITY_REVERSED_Z)
pos.z = max(pos.z, newPosZ) + uv.z;
#else
pos.z = min(pos.z, newPosZ) + uv.z;
#endif
return pos;
}
PackedVaryings CustomVertex(Attributes input)
{
Varyings output = (Varyings)0;
output = BuildVaryings(input);
output.positionCS = billboardMeshTowardsCamera(input.positionOS, _Offset, input.uv0);
PackedVaryings packedOutput = (PackedVaryings)0;
packedOutput = PackVaryings(output);
return packedOutput;
}
Other than that it works perfectly fine. How would I fix that? I tried compensating with float4(0.5,0.0,0.5,0.0) at several different places but no dice

