I can’t really give you our engine code verbatim (it wouldn’t be a drop-in replacement anyway) but I think you want something like this:
float3 velocityVS = mul(worldViewMatrix, velocity);
velocityVS -= cameraVelocity;
float speedVS = dot(velocityVS);
speedVS = select(rsqrte(speedVS), 0.0f, speedVS <= 1e-30f);
float3 startProjWS = positionWS;
float3 positionVS = mul(invTransformMatrix, positionWS);
float3 endProjWS;
if (pivotOffset)
{
positionVS += mul(velocityVS, speedVS * pivotPercentage.y * size.y);
}
float3 endVS = positionVS - mul(velocityVS, (velocityScale + speedVS * (lengthScale * size.y)));
float2 deltaVS;
deltaVS.x = positionVS.z * endVS.y - positionVS.y * endVS.z;
deltaVS.y = positionVS.x * endVS.z - positionVS.z * endVS.x;
float2 deltaVSN = normalizeSafe(deltaVS);
deltaVS = mul(deltaVSN, hsize.x);
float3 delta3VS(deltaVS.x, deltaVS.y, 0.0f);
if (pivotOffset)
{
float3 delta3ScaledVS = mul(delta3VS, pivotPercentage.x);
positionVS += delta3ScaledVS;
endVS += delta3ScaledVS;
startProjWS = mul(transformMatrix, positionVS);
}
endProjWS = mul(transformMatrix, endVS);
n0 = mul(rotationN, delta3VS);
vert[0] = startProjWS + n0;
vert[1] = endProjWS + n0;
vert[2] = endProjWS - n0;
vert[3] = startProjWS - n0;
I probably can’t easily troubleshoot this with you in case it doesn’t work, but, hopefully it gets you closer to what you need.
Be aware that there are features not included in my example, eg freeform stretching mode.
Plus a bunch of inputs that you’ll need to provide yourself, such as the transform matrices and various scaling factors.
normalizeSafe
is like normalize, but it returns a zero vector if the length of the input is zero, instead of exploding.
hsize
is the same as size
, except it is clamped based on the min/max particle size parameters, if particle screen space size is too big or small. I’d ignore that for now, if i were you, and just set it to the same as size.
rsqrte
is a fast inverse sqrt. you can replace with 1.0f / sqrt(val)
if we don’t have rsqrt in the shading language. (i forget :-))
select
may not be in the shading language either. you can implement as result = c ? b : a;
Note that our code sets the 4 vertices, rather than calculating a rotation/scale. Converting that will need figuring out.
I’m not sure how helpful this will be, but, this is only modifed slightly from what is actually in the engine, to make it more like shader code for you, so good luck!