I am having some trouble converting my unlit (emissive) billboard shader to the HD Scriptable Render Pipeline.
The problem is with the new Camera Relative Rendering the HD SRP uses. See code below.
//Legacy pipeline version:
//output.pos = mul(UNITY_MATRIX_P, float4(UnityObjectToViewPos(input.center), 1.0f) + offset); //Place the vertex by moving it away from the center, rotate the billboard towards the camera.
//HD SRP version, but it causes major rendering artifacts.
output.pos.xyz = TransformObjectToWorld(input.center.xyz);
output.pos = mul(UNITY_MATRIX_P, float4(output.pos.xyz, 1.0f) + offset); //Rotate billboard towards camera. Not sure how to convert this to SRP.
output.pos.xyz = GetCameraRelativePositionWS(output.pos.xyz);
output.pos = TransformWorldToHClip(output.pos.xyz);
In Unity 2018.2.0f2 the Camera Relative Rendering seems to be broken. Commenting out line 2 in the code will at least render the lights, but they will not face the camera…
Here is how camera relative is implemented, this can help you.
We remove the translation part of the View Matrix on C# side
and we add it the the object transform on hlsl side.
The hlsl code that update the object transform is via the Macro UNITY_MATRIX_M
float4x4 ApplyCameraTranslationToMatrix(float4x4 modelMatrix)
{
// To handle camera relative rendering we substract the camera position in the model matrix #if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
modelMatrix._m03_m13_m23 -= _WorldSpaceCameraPos; #endif
return modelMatrix;
}
See VertMesh.hlsl for correct use or camera relative rendering.
We transform like this:
// This return the camera relative position (if enable)
float3 positionRWS = TransformObjectToWorld(input.positionOS);
output.positionCS = TransformWorldToHClip(positionRWS);
So indeed the equivalent of the above code if you split View and Projection matrice is: