Skip to content

Commit d4e959a

Browse files
testrender: Fix uv derivatives for testrender [AcademySoftwareFoundation#1978] (AcademySoftwareFoundation#2037)
Fix dudx, dudy, dvdx, dvdy, as well as dpdx, dpdy in testrender. Now, bump mapping from both UV-based mapping and 3D-based patterns works well. Mip-Map selection also works fine now. Images in Issue: AcademySoftwareFoundation#1978 This PR is intended to validate math and discuss tests. Fixes AcademySoftwareFoundation#1978 This fix could potentially affect many other tests since dpdx, dpdy are changed. I'm going to add tests representing bump and mipmapping in this PR. --------- Signed-off-by: Alexey Smolenchuk <[email protected]> Signed-off-by: Larry Gritz <[email protected]> Co-authored-by: Larry Gritz <[email protected]>
1 parent 693ed85 commit d4e959a

File tree

4 files changed

+51
-16
lines changed

4 files changed

+51
-16
lines changed

src/testrender/raytracer.h

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,22 @@ struct Scene {
279279
return ((1 - u - v) * na + u * nb + v * nc).normalize();
280280
}
281281

282+
// Project differentials onto surface defined by N
283+
OSL_HOSTDEVICE
284+
void project(Dual2<Vec3>& p, const Vec3& N, const Vec3& I) const
285+
{
286+
Vec3 nI = I.normalized();
287+
float cosI = dot(-nI, N);
288+
289+
if (fabsf(cosI) > 1e-3f) {
290+
float deltaX = dot(p.dx(), N) / cosI;
291+
float deltaY = dot(p.dy(), N) / cosI;
292+
293+
p.dx() += nI * deltaX;
294+
p.dy() += nI * deltaY;
295+
}
296+
}
297+
282298
OSL_HOSTDEVICE
283299
Dual2<Vec2> uv(const Dual2<Vec3>& p, const Vec3& n, Vec3& dPdu, Vec3& dPdv,
284300
int primID, float u, float v) const
@@ -304,7 +320,25 @@ struct Scene {
304320
dPdv = (-dt12.x * dp02 + dt02.x * dp12) * invdet;
305321
// TODO: smooth out dPdu and dPdv by storing per vertex tangents
306322
}
307-
return Dual2<Vec2>((1 - u - v) * ta + u * tb + v * tc);
323+
324+
// L represent planes constructed from opposite points perpendicular
325+
// to N and scaled to return 1.0 for scalar product with itself
326+
Vec3 La = n.cross(vc - vb);
327+
La /= dot(va - vb, La);
328+
329+
Vec3 Lb = n.cross(va - vc);
330+
Lb /= dot(vb - vc, Lb);
331+
332+
Vec3 Lc = n.cross(vb - va);
333+
Lc /= dot(vc - va, Lc);
334+
335+
Vec2 dTdx = dot(La, p.dx()) * ta + dot(Lb, p.dx()) * tb
336+
+ dot(Lc, p.dx()) * tc;
337+
338+
Vec2 dTdy = dot(La, p.dy()) * ta + dot(Lb, p.dy()) * tb
339+
+ dot(Lc, p.dy()) * tc;
340+
341+
return Dual2<Vec2>((1 - u - v) * ta + u * tb + v * tc, dTdx, dTdy);
308342
}
309343

310344
OSL_HOSTDEVICE int shaderid(int primID) const { return shaderids[primID]; }

src/testrender/simpleraytracer.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -903,25 +903,26 @@ SimpleRaytracer::globals_from_hit(ShaderGlobalsType& sg, const Ray& r,
903903
const int meshid = m_meshids[id];
904904
#endif
905905

906-
Dual2<Vec3> P = r.point(t);
907-
// We are missing the projection onto the surface here
908-
sg.P = P.val();
909-
sg.dPdx = P.dx();
910-
sg.dPdy = P.dy();
911-
sg.N = scene.normal(P, sg.Ng, id, u, v);
912-
Dual2<Vec2> uv = scene.uv(P, sg.N, sg.dPdu, sg.dPdv, id, u, v);
913-
sg.u = uv.val().x;
914-
sg.dudx = uv.dx().x;
915-
sg.dudy = uv.dy().x;
916-
sg.v = uv.val().y;
917-
sg.dvdx = uv.dx().y;
918-
sg.dvdy = uv.dy().y;
919-
sg.surfacearea = m_mesh_surfacearea[meshid];
920906
Dual2<Vec3> direction = r.dual_direction();
921907
sg.I = direction.val();
922908
sg.dIdx = direction.dx();
923909
sg.dIdy = direction.dy();
924-
sg.backfacing = sg.Ng.dot(sg.I) > 0;
910+
Dual2<Vec3> P = r.point(t);
911+
sg.P = P.val();
912+
sg.N = scene.normal(P, sg.Ng, id, u, v);
913+
// Projecting onto the surface here
914+
scene.project(P, sg.N, sg.I);
915+
sg.dPdx = P.dx();
916+
sg.dPdy = P.dy();
917+
Dual2<Vec2> uv = scene.uv(P, sg.N, sg.dPdu, sg.dPdv, id, u, v);
918+
sg.u = uv.val().x;
919+
sg.dudx = uv.dx().x;
920+
sg.dudy = uv.dy().x;
921+
sg.v = uv.val().y;
922+
sg.dvdx = uv.dx().y;
923+
sg.dvdy = uv.dy().y;
924+
sg.surfacearea = m_mesh_surfacearea[meshid];
925+
sg.backfacing = sg.Ng.dot(sg.I) > 0;
925926
if (sg.backfacing) {
926927
sg.N = -sg.N;
927928
sg.Ng = -sg.Ng;
2.99 KB
Binary file not shown.

testsuite/render-uv/ref/out.exr

-246 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)