Answer:
struct SG
{
float3 Amplitude;
float3 Axis;
float Sharpness;
};
float3 EvaluateSG(in SG sg, in float3 dir)
{
float cosAngle = dot(dir, sg.Axis);
return sg.Amplitude * exp(sg.Sharpness * (cosAngle - 1.0f));
}
SG SGProduct(in SG x, in SG y)
{
float3 um = (x.Sharpness * x.Axis + y.Sharpness * y.Axis) /
(x.Sharpness + y.Sharpness);
float umLength = length(um);
float lm = x.Sharpness + y.Sharpness;
SG res;
res.Axis = um * (1.0f / umLength);
res.Sharpness = lm * umLength;
res.Amplitude = x.Amplitude * y.Amplitude *
exp(lm * (umLength - 1.0f));
return res;
}