in SHMath/DirectXSH.cpp [4796:4907]
bool XM_CALLCONV DirectX::XMSHEvalHemisphereLight(
size_t order,
FXMVECTOR dir,
FXMVECTOR topColor,
FXMVECTOR bottomColor,
float *resultR,
float *resultG,
float *resultB) noexcept
{
if (!resultR)
return false;
if (order < XM_SH_MINORDER || order > XM_SH_MAXORDER)
return false;
// seperate "R/G/B colors...
float fTmpDir[XM_SH_MAXORDER * XM_SH_MAXORDER]; // rotation "vector"
float fTmpL0[XM_SH_MAXORDER];
const float fNewNorm = 3.0f / 2.0f; // normalizes things for 1 sky color, 0 ground color...
XMFLOAT3A vd;
XMStoreFloat3(&vd, dir);
const float fX = vd.x;
const float fY = vd.y;
const float fZ = vd.z;
sh_eval_basis_1(fX, fY, fZ, fTmpDir);
XMFLOAT3A clrTop;
XMStoreFloat3A(&clrTop, topColor);
XMFLOAT3A clrBottom;
XMStoreFloat3A(&clrBottom, bottomColor);
float fA = clrTop.x;
float fAvrg = (clrTop.x + clrBottom.x)*0.5f;
fTmpL0[0] = fAvrg*2.0f*SHEvalHemisphereLight_fSqrtPi;
fTmpL0[1] = (fA - fAvrg)*2.0f*SHEvalHemisphereLight_fSqrtPi3;
size_t i = 0;
for (; i < 2; ++i)
{
_Analysis_assume_(i < order);
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
const float fValUse = fTmpL0[i] * fNewNorm*fExtraNormFac[i];
for (size_t j = 0; j < cNumCoefs; ++j) resultR[cStart + j] = fTmpDir[cStart + j] * fValUse;
}
for (; i < order; ++i)
{
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
for (size_t j = 0; j < cNumCoefs; ++j) resultR[cStart + j] = 0.0f;
}
if (resultG)
{
fA = clrTop.y;
fAvrg = (clrTop.y + clrBottom.y)*0.5f;
fTmpL0[0] = fAvrg*2.0f*SHEvalHemisphereLight_fSqrtPi;
fTmpL0[1] = (fA - fAvrg)*2.0f*SHEvalHemisphereLight_fSqrtPi3;
for (i = 0; i < 2; ++i)
{
_Analysis_assume_(i < order);
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
const float fValUse = fTmpL0[i] * fNewNorm*fExtraNormFac[i];
for (size_t j = 0; j < cNumCoefs; ++j) resultG[cStart + j] = fTmpDir[cStart + j] * fValUse;
}
for (; i < order; ++i)
{
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
for (size_t j = 0; j < cNumCoefs; ++j) resultG[cStart + j] = 0.0f;
}
}
if (resultB)
{
fA = clrTop.z;
fAvrg = (clrTop.z + clrBottom.z)*0.5f;
fTmpL0[0] = fAvrg*2.0f*SHEvalHemisphereLight_fSqrtPi;
fTmpL0[1] = (fA - fAvrg)*2.0f*SHEvalHemisphereLight_fSqrtPi3;
for (i = 0; i < 2; ++i)
{
_Analysis_assume_(i < order);
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
const float fValUse = fTmpL0[i] * fNewNorm*fExtraNormFac[i];
for (size_t j = 0; j < cNumCoefs; ++j) resultB[cStart + j] = fTmpDir[cStart + j] * fValUse;
}
for (; i < order; ++i)
{
const size_t cNumCoefs = 2 * i + 1;
const size_t cStart = i*i;
for (size_t j = 0; j < cNumCoefs; ++j) resultB[cStart + j] = 0.0f;
}
}
return true;
}