Moving Frostbite to Physically Based Rendering 3.0. Photometric lights
When creating a new light profile, the spherical photometric function is reconstructed and sampled to fill a 2D texture with a spherical parametrization (θ, cos(φ)). We store normalized values scaled by the inverse of the maximum intensity in order to handle both masked and unmasked usage.
// Normalize the profile by its maximum intensity
float getIESProfileAttenuation(float3 L, ShadowLightInfo light)
{
// Sample direction into light space
float3 iesSampleDirection = mul(light. worldToLight, -L);
// Cartesian to spherical
// Texture encoded with cos( phi ), scale from -1 - >1 to 0 - >1
float phiCoord = (iesSampleDirection.z * 0.5f) + 0.5f;
float theta = atan2 (iesSampleDirection.y, iesSampleDirection.x);
float thetaCoord = theta * FB_INV_TWO_PI ;
float3 texCoord = float3(thetaCoord, phiCoord, light. lightIndex);
float iesProfileScale = iesTexture.SampleLevel(sampler, texCoord, 0).r;
return iesProfileScale ;
}
...
att *= getAngleAtt(L, lightForward, lightAngleScale, lightAngleOffset);
att *= getIESProfileAttenuation(L, light);
// lightColor depends on option.
// Non masked : lightColor = color * MaxCandelas
// Masked(for point light with luminous power): lightColor = color * phi / (4 * PI)
float3 luminance = BSDF(...) * saturate(dot(N, L)) * lightColor * att;
Moving Frostbite to Physically Based Rendering 3.0. Photometric lights
When creating a new light profile, the spherical photometric function is reconstructed and sampled to fill a 2D texture with a spherical parametrization (θ, cos(φ)). We store normalized values scaled by the inverse of the maximum intensity in order to handle both masked and unmasked usage.