in SHMath/DirectXSH.cpp [4675:4779]
bool XM_CALLCONV DirectX::XMSHEvalConeLight(
size_t order,
FXMVECTOR dir,
float radius,
FXMVECTOR color,
float *resultR,
float *resultG,
float *resultB) noexcept
{
if (!resultR)
return false;
if (radius < 0.f || radius >(XM_PI*1.00001f))
return false;
if (radius < 0.0001f)
{
// turn it into a pure directional light...
return XMSHEvalDirectionalLight(order, dir, color, resultR, resultG, resultB);
}
else
{
float fTmpL0[XM_SH_MAXORDER];
float fTmpDir[XM_SH_MAXORDER * XM_SH_MAXORDER];
const float fConeAngle = radius;
const float fAngCheck = (fConeAngle > XM_PIDIV2) ? (XM_PIDIV2) : fConeAngle;
const float fNewNorm = 1.0f / (sinf(fAngCheck)*sinf(fAngCheck));
ComputeCapInt(order, fConeAngle, fTmpL0);
XMFLOAT3A vd;
XMStoreFloat3(&vd, dir);
const float fX = vd.x;
const float fY = vd.y;
const float fZ = vd.z;
switch (order)
{
case 2:
sh_eval_basis_1(fX, fY, fZ, fTmpDir);
break;
case 3:
sh_eval_basis_2(fX, fY, fZ, fTmpDir);
break;
case 4:
sh_eval_basis_3(fX, fY, fZ, fTmpDir);
break;
case 5:
sh_eval_basis_4(fX, fY, fZ, fTmpDir);
break;
case 6:
sh_eval_basis_5(fX, fY, fZ, fTmpDir);
break;
default:
assert(order < XM_SH_MINORDER || order > XM_SH_MAXORDER);
return false;
}
XMFLOAT3A clr;
XMStoreFloat3A(&clr, color);
for (size_t i = 0; i < order; ++i)
{
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
const float fValUse = fTmpL0[i] * clr.x*fNewNorm*fExtraNormFac[i];
for (size_t j = 0; j < cNumCoefs; ++j)
resultR[cStart + j] = fTmpDir[cStart + j] * fValUse;
}
if (resultG)
{
for (size_t i = 0; i < order; ++i)
{
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
const float fValUse = fTmpL0[i] * clr.y*fNewNorm*fExtraNormFac[i];
for (size_t j = 0; j < cNumCoefs; ++j)
resultG[cStart + j] = fTmpDir[cStart + j] * fValUse;
}
}
if (resultB)
{
for (size_t i = 0; i < order; ++i)
{
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
const float fValUse = fTmpL0[i] * clr.z*fNewNorm*fExtraNormFac[i];
for (size_t j = 0; j < cNumCoefs; ++j)
resultB[cStart + j] = fTmpDir[cStart + j] * fValUse;
}
}
}
return true;
}