38 #ifndef RixIESInline_h 39 #define RixIESInline_h 56 emission->r = emission->g = emission->b = 1.f;
66 if (!m_hasNegativeDeterminant)
71 calcLatLongParam(1, (
float*)&localDir, m_iesProfile.
isExr, &u, &v);
73 if ((u != u) || (v != v))
77 emission->r = emission->g = emission->b = 1.f;
81 if (u < 0.0f || u > 1.0f || v < 0.0f || v > 1.0f)
85 emission->r = emission->g = emission->b = 1.f;
90 float coneSize = 1.0f;
91 float profileScale = 1.0f;
92 if (m_coneAngle > 0.0f)
94 coneSize = m_coneAngle / (float)
F_PI;
95 profileScale = coneSize;
107 v = v / profileScale;
112 v = std::max(std::min(v * vScale, 1.0f), 0.0f);
116 float uf = u *
static_cast<float>(m_iesProfile.
nu);
117 if (uf >= m_iesProfile.
nu)
118 uf -=
static_cast<float>(m_iesProfile.
nu);
120 int u0 =
static_cast<int>(floorf(uf));
122 if (u1 >= m_iesProfile.
nu)
125 float fu = uf -
static_cast<float>(u0);
127 if (u0 < 0 || u0 >= m_iesProfile.
nu || u1 < 0 || u1 >= m_iesProfile.
nu)
131 emission->r = emission->g = emission->b = 1.f;
135 float vf = v * (
static_cast<float>(m_iesProfile.
nv) - 1.0f);
136 if (vf >= m_iesProfile.
nv)
137 vf =
static_cast<float>(m_iesProfile.
nv) - 1.0f;
139 int v0 =
static_cast<int>(floorf(vf));
141 if (v1 >= m_iesProfile.
nv)
142 v1 = m_iesProfile.
nv - 1;
144 float fv = vf -
static_cast<float>(v0);
146 if (v0 < 0 || v0 >= m_iesProfile.
nv || v1 < 0 || v1 >= m_iesProfile.
nv)
150 emission->r = emission->g = emission->b = 1.f;
154 int v00 = u0 + v0 * m_iesProfile.
nu;
155 int v10 = u1 + v0 * m_iesProfile.
nu;
156 int v01 = u0 + v1 * m_iesProfile.
nu;
157 int v11 = u1 + v1 * m_iesProfile.
nu;
159 float rfu = 1.0f - fu;
166 (1.0f - fv) * ( rfu * m_iesProfile.
profile[3 * v00 + 0]
167 + fu * m_iesProfile.
profile[3 * v10 + 0])
168 + fv * ( rfu * m_iesProfile.
profile[3 * v01 + 0]
169 + fu * m_iesProfile.
profile[3 * v11 + 0]);
170 emission->r = std::max(0.0f, emission->r);
173 (1.0f - fv) * ( rfu * m_iesProfile.
profile[3 * v00 + 1]
174 + fu * m_iesProfile.
profile[3 * v10 + 1])
175 + fv * ( rfu * m_iesProfile.
profile[3 * v01 + 1]
176 + fu * m_iesProfile.
profile[3 * v11 + 1]);
177 emission->g = std::max(0.0f, emission->g);
180 (1.0f - fv) * ( rfu * m_iesProfile.
profile[3 * v00 + 2]
181 + fu * m_iesProfile.
profile[3 * v10 + 2])
182 + fv * ( rfu * m_iesProfile.
profile[3 * v01 + 2]
183 + fu * m_iesProfile.
profile[3 * v11 + 2]);
184 emission->b = std::max(0.0f, emission->b);
189 (1.0f - fv) * ( rfu * m_iesProfile.
profile[v00]
190 + fu * m_iesProfile.
profile[v10])
191 + fv * ( rfu * m_iesProfile.
profile[v01]
192 + fu * m_iesProfile.
profile[v11]);
194 emission->r = std::max(0.0f, emission->r);
195 emission->g = emission->b = emission->r;
204 m_iesProfile.
clear();
207 if (!iesProfile.Empty())
209 static std::string rtxPrefix(
"rtxplugin:RtxIES?filename=");
216 std::string mapName = rtxPrefix + std::string(iesProfile.CStr());
227 "RixIES emission profile: could not open %s",
235 "Building RixIES emission profile(\"%s\")\n",
238 m_iesProfile.
nu = txProps.
width;
240 m_iesProfile.
isExr =
false;
244 m_iesProfile.
profile =
new float[
255 int nu = m_iesProfile.
nu;
256 int nv = m_iesProfile.
nv;
261 for (
int j = 0; j <= nv / 2; ++j)
273 float lowerAngle = (j == 0) ? 0 :
F_PI * (2 * j - 1) / nv;
275 (j == nv / 2) ?
F_PI :
F_PI * (2 * j + 1) / nv;
277 0.5f * (cosf(lowerAngle) - cosf(upperAngle));
278 for (
int i = 0; i < nu; ++i)
280 for (
int k = 0; k < nchans; ++k)
282 total += scalefactor *
283 m_iesProfile.
profile[((j * nu) + i) * nchans + k];
287 m_normalizationFactor = nu * nchans / total;
298 if (m_coneAngle > 0.0f)
302 if (m_hasNegativeDeterminant)
305 if (localDir.z > 0.0f)
307 localDir.Normalize();
308 if (localDir.z >= m_cosConeAngle)
320 float& minT,
float& maxT)
const 324 float ts = lightN.Dot(offsetP + minT * segmentDir - lightP);
325 float te = lightN.Dot(offsetP + maxT * segmentDir - lightP);
326 if (ts < 0.0f && te < 0.0f)
return 0.0f;
329 float planeT = lightN.Dot(lightP - offsetP) / segmentDir.Dot(lightN);
339 if (m_cosConeAngle < 1e-5f)
return 1.0f;
341 float vDn = segmentDir.Dot(lightN);
343 float c2 = vDn * vDn - segmentDir.Dot(segmentDir) * m_cosConeAngle * m_cosConeAngle;
344 if (c2 == 0.0f)
return 0.0f;
345 float lpDn = lToP.Dot(lightN);
346 float c1 = vDn * lpDn - lToP.Dot(segmentDir) * m_cosConeAngle * m_cosConeAngle;
347 float c0 = lpDn * lpDn - lToP.Dot(lToP) * m_cosConeAngle * m_cosConeAngle;
349 float delta = c1*c1 - c0*c2;
353 float rootDelta = sqrtf(delta);
358 t0 = (-c1 - rootDelta) / c2;
359 t1 = (-c1 + rootDelta) / c2;
363 t1 = (-c1 - rootDelta) / c2;
364 t0 = (-c1 + rootDelta) / c2;
368 minT = std::max(minT, t0);
369 maxT = std::min(maxT, t1);
385 RixIES::calcLongitude(
float x,
float y,
bool isExr)
const 391 float s = atan2f(y, x);
415 float x, y, z, len, zlen;
416 for (
int i = 0; i < n; i++, s++, t++, dir += 3)
424 len = x * x + y * y + z * z;
426 len = 1.f / sqrtf(len);
438 *t = 0.5f - asinf(zlen) * 1.0f /
F_PI;
439 *s = calcLongitude(x, y, openEXR);
virtual int AcquireTexture(RtUString const fileName, TxAtlasStyle const atlasStyle, TxProperties &txProperties)=0
pxrcore::ColorRGB RtColorRGB
Id for New Texture-2D interface.
PRMAN_INLINE bool ReadIESProfile(RixContext const &rixCtx, RtUString const iesProfile)
PRMAN_INLINE void EvaluateIESProfile(RtFloat3 const &P, RtColorRGB *emission) const
pxrcore::UString RtUString
Id for RixMessages interface.
virtual int TextureData(TxProperties const &txProperties, TxParams const &txParams, int mipLevel, int cubeFace, void *result)=0
virtual int ReleaseTexture(TxProperties const &txProperties)=0
PRMAN_INLINE float EvaluateConeAngle(RtFloat3 const &P) const
virtual RixInterface * GetRixInterface(RixInterfaceId id) const =0