Calculates diffuse and specular from a spherical area light
| 110 | |
| 111 | // Calculates diffuse and specular from a spherical area light |
| 112 | static Float3 SampleSphericalAreaLight(const Float3& position, const Float3& normal, RTCScene scene, |
| 113 | const Float3& diffuseAlbedo, const Float3& cameraPos, |
| 114 | bool includeSpecular, Float3 specAlbedo, float roughness, |
| 115 | float u1, float u2, float lightRadius, |
| 116 | const Float3& lightPos, const Float3& lightColor, Float3& irradiance) |
| 117 | { |
| 118 | const float radius2 = lightRadius * lightRadius; |
| 119 | const float invPDF = 2.0f * Pi * radius2; |
| 120 | |
| 121 | Float3 result = 0.0f; |
| 122 | Float3 areaLightIrradiance = 0.0f; |
| 123 | |
| 124 | float r = lightRadius; |
| 125 | float x = u1; |
| 126 | float y = u2; |
| 127 | |
| 128 | Float3 samplePos; |
| 129 | samplePos.x = lightPos.x + 2.0f * r * std::cos(2.0f * Pi * y) * std::sqrt(x * (1.0f - x)); |
| 130 | samplePos.y = lightPos.y + 2.0f * r * std::sin(2.0f * Pi * y) * std::sqrt(x * (1.0f - x)); |
| 131 | samplePos.z = lightPos.z + r * (1.0f - 2.0f * x); |
| 132 | |
| 133 | Float3 sampleDir = samplePos - position; |
| 134 | float sampleDirLen = Float3::Length(sampleDir); |
| 135 | bool visible = false; |
| 136 | if(sampleDirLen > 0.0f) |
| 137 | { |
| 138 | sampleDir /= sampleDirLen; |
| 139 | |
| 140 | visible = Occluded(scene, position, sampleDir, 0.1f, sampleDirLen) == false; |
| 141 | } |
| 142 | |
| 143 | float areaNDotL = std::abs(Float3::Dot(sampleDir, Float3::Normalize(samplePos - lightPos))); |
| 144 | float sDotN = Saturate(Float3::Dot(sampleDir, normal)); |
| 145 | |
| 146 | float invRSqr = 1.0f / (sampleDirLen * sampleDirLen); |
| 147 | |
| 148 | float attenuation = areaNDotL * invRSqr; |
| 149 | if(attenuation && visible) |
| 150 | { |
| 151 | Float3 sampleIrradiance = Saturate(Float3::Dot(normal, sampleDir)) * lightColor * attenuation; |
| 152 | Float3 sample = CalcLighting(normal, sampleIrradiance, sampleDir, diffuseAlbedo, position, |
| 153 | cameraPos, roughness, includeSpecular, specAlbedo); |
| 154 | result = sample * invPDF; |
| 155 | areaLightIrradiance = sampleIrradiance * invPDF; |
| 156 | } |
| 157 | |
| 158 | irradiance += areaLightIrradiance; |
| 159 | |
| 160 | return result; |
| 161 | } |
| 162 | |
| 163 | // Calculates diffuse and specular contribution from the area light, given a 2D random sample point |
| 164 | // representing a location on the surface of the light |