@@ -278,6 +278,24 @@ struct Scene {
278278 return ((1 - u - v) * na + u * nb + v * nc).normalize ();
279279 }
280280
281+ // Project differentials onto surface defined by N
282+ OSL_HOSTDEVICE
283+ void project (Dual2<Vec3>& p, const Vec3& N, const Vec3& I) const
284+ {
285+ float cosx = dot (p.dx ().normalized (), N);
286+ float cosy = dot (p.dy ().normalized (), N);
287+ float cosI = dot (I.normalized (), N);
288+
289+ if (abs (cosI)>1e-3 )
290+ {
291+ float deltaX = p.dx ().length () * cosx / cosI;
292+ float deltaY = p.dy ().length () * cosy / cosI;
293+
294+ p.dx () -= I.normalized () * deltaX;
295+ p.dy () -= I.normalized () * deltaY;
296+ }
297+ }
298+
281299 OSL_HOSTDEVICE
282300 Dual2<Vec2> uv (const Dual2<Vec3>& p, const Vec3& n, Vec3& dPdu, Vec3& dPdv,
283301 int primID, float u, float v) const
@@ -303,7 +321,27 @@ struct Scene {
303321 dPdv = (-dt12.x * dp02 + dt02.x * dp12) * invdet;
304322 // TODO: smooth out dPdu and dPdv by storing per vertex tangents
305323 }
306- return Dual2<Vec2>((1 - u - v) * ta + u * tb + v * tc);
324+
325+ // L represent planes constructed from opposite points
326+ // scaled to return 1.0 for scalar product with itself
327+ Vec3 La = vb.cross (vc);
328+ La /= dot (va, La);
329+
330+ Vec3 Lb = va.cross (vc);
331+ Lb /= dot (vb, Lb);
332+
333+ Vec3 Lc = va.cross (vb);
334+ Lc /= dot (vc, Lc);
335+
336+ Vec2 dTdx = dot (La, p.dx ()) * ta +
337+ dot (Lb, p.dx ()) * tb +
338+ dot (Lc, p.dx ()) * tc;
339+
340+ Vec2 dTdy = dot (La, p.dy ()) * ta +
341+ dot (Lb, p.dy ()) * tb +
342+ dot (Lc, p.dy ()) * tc;
343+
344+ return Dual2<Vec2>((1 - u - v) * ta + u * tb + v * tc, dTdx, dTdy);
307345 }
308346
309347 OSL_HOSTDEVICE int shaderid (int primID) const { return shaderids[primID]; }
0 commit comments