ray-cast / ies

Convert the IES file into a IES texture for IES lightning
Other
51 stars 11 forks source link

Unable to properly sample IES light on the CPU #3

Open Zeta48 opened 2 years ago

Zeta48 commented 2 years ago

Hello,

I am trying to add IES lighting to my CPU renderer. To do so i used your IES parser. Unfortunetly i am getting wrong results when i sample the lights(IESLoadHelper::interpolatePoint or IESLoadHelper::interpolateBilinear).

For example: The ground truth: https://imgur.com/CrxT7bv The result I get: https://imgur.com/pJ7VU5e

My renderer use a right handed Y up coordinate system: https://i.stack.imgur.com/vg1P7.png

Here is my sampling code:

`

Math::Vec2 dirToSphericalUV(const Math::Vec3& dir)
{
    return Math::Vec2(
        0.5f + 0.5f * atan2(dir.x, dir.z) / 3.1415926f,
        1.f - acos(dir.y) / 3.1415926f);
}

struct SampleToLight
{
    Math::Vec3 L;
    float length;
    float intensityMultiplier = 1.0f;
};

SampleToLight IesLight::generateSampleToLight(const Math::Vec3& P) const
{
    const Math::Vec3 lightWsPosition = this->readPosition();

    SampleToLight sample;
    sample.L = lightWsPosition - P;
    sample.length = glm::length(sample.L);
    sample.L /= sample.length;

    //NOT WORKING
    const Math::Vec2 profileUV = dirToSphericalUV(-1.f * sample.L);
    const float profileCoordH = profileUV.x * (float)m_iesFileInfo->anglesNumH;
    const float profileCoordV = profileUV.y * (float)m_iesFileInfo->anglesNumV;
    sample.intensityMultiplier = m_iesLoadHelper.interpolateBilinear(*m_iesFileInfo, profileCoordH, profileCoordV);

    return sample;
}

`

Thanks in advance for helping.

Zeta48 commented 2 years ago

I found out my mistake. I should use angles instead of directly using interpolateBilinear. `

void dirToSphericalAngles(const Math::Vec3& dir, nbFloat32& angleH, nbFloat32& angleV)
{
    angleH = (0.5f + 0.5f * atan2(dir.x, dir.z) / Math::Pi.getValue()) * 360.0f;
    angleV = (1.f - acos(dir.y) / Math::Pi.getValue()) * 180.0f;
}

struct SampleToLight
{
    Math::Vec3 L;
    float length;
    float intensityMultiplier = 1.0f;
};

SampleToLight IesLight::generateSampleToLight(const Math::Vec3& P) const
{
    const Math::Vec3 lightWsPosition = this->readPosition();

    SampleToLight sample;
    sample.L = lightWsPosition - P;
    sample.length = glm::length(sample.L);
    sample.L /= sample.length;

    nbFloat32 angleH, angleV;
    dirToSphericalAngles(-sample.L, angleH, angleV);
    sample.intensityMultiplier = m_iesLoadHelper.interpolate2D(*m_iesFileInfo, angleV, angleH);

    return sample;
}

`