diff --git a/src/testrender/cuda/optix_raytracer.cu b/src/testrender/cuda/optix_raytracer.cu index c102d25dc..985a7810d 100644 --- a/src/testrender/cuda/optix_raytracer.cu +++ b/src/testrender/cuda/optix_raytracer.cu @@ -245,6 +245,10 @@ __raygen__setglobals() OSL::pvt::test_str_2 = render_params.test_str_2; } + OSL::pvt::num_named_xforms = render_params.num_named_xforms; + OSL::pvt::xform_name_buffer = render_params.xform_name_buffer; + OSL::pvt::xform_buffer = render_params.xform_buffer; + if (render_params.bg_id < 0) return; diff --git a/src/testrender/optixraytracer.cpp b/src/testrender/optixraytracer.cpp index 5f6037a8c..7f2cb8a69 100644 --- a/src/testrender/optixraytracer.cpp +++ b/src/testrender/optixraytracer.cpp @@ -1092,6 +1092,28 @@ OptixRaytracer::render(int xres OSL_MAYBE_UNUSED, int yres OSL_MAYBE_UNUSED) params.test_str_1 = test_str_1; params.test_str_2 = test_str_2; + // Named transforms + int nxforms = m_named_xforms.size(); + params.num_named_xforms = nxforms; + params.xform_name_buffer = DEVICE_ALLOC(sizeof(ustringhash) * nxforms); + params.xform_buffer = DEVICE_ALLOC(sizeof(Transformation) * nxforms); + + std::vector names; + std::vector xforms; + names.reserve(nxforms); + xforms.reserve(nxforms); + + for (auto& pair : m_named_xforms) { + names.push_back(pair.first); + xforms.push_back(*pair.second); + } + + COPY_TO_DEVICE(params.xform_name_buffer, names.data(), + sizeof(ustringhash) * nxforms); + COPY_TO_DEVICE(params.xform_buffer, xforms.data(), + sizeof(Transformation) * nxforms); + CUDA_SYNC_CHECK(); + // Mesh data params.verts = d_vertices; params.triangles = d_vert_indices; diff --git a/src/testrender/raytracer.h b/src/testrender/raytracer.h index eef7f2a3e..425da43b5 100644 --- a/src/testrender/raytracer.h +++ b/src/testrender/raytracer.h @@ -135,8 +135,9 @@ struct Camera { { float k = OIIO::fast_tan(fov * float(M_PI / 360)); Vec3 right = dir.cross(up).normalize(); - cx = right * (xres * k / yres); - cy = (cx.cross(dir)).normalize() * k; + // fov is horizontal + cx = right * k; + cy = (cx.cross(dir)).normalize() * k * yres / xres; } // Get a ray for the given screen coordinates. @@ -147,7 +148,8 @@ struct Camera { // components with magnitudes slightly greater than 1.0, which can cause // downstream computations to blow up and produce NaNs. Normalizing the // vector again avoids this issue. - const Vec3 v = (cx * (x * invw - 0.5f) + cy * (0.5f - y * invh) + dir) + const Vec3 v = (cx * (x * invw - 0.5f) * 2.f + + cy * (0.5f - y * invh) * 2.f + dir) #ifndef __CUDACC__ .normalize(); #else diff --git a/src/testrender/simpleraytracer.cpp b/src/testrender/simpleraytracer.cpp index 0f1258be9..0710750f9 100644 --- a/src/testrender/simpleraytracer.cpp +++ b/src/testrender/simpleraytracer.cpp @@ -332,6 +332,7 @@ SimpleRaytracer::parse_scene_xml(const std::string& scenefile) if (fov_attr) fov = OIIO::Strutil::from_string(fov_attr.value()); + m_fov = fov; camera.lookat(eye, dir, up, fov); } else if (strcmp(node.name(), "Sphere") == 0) { // load sphere @@ -506,6 +507,62 @@ SimpleRaytracer::parse_scene_xml(const std::string& scenefile) if (scene.num_prims() == 0) errhandler().severefmt("No primitives in scene"); camera.finalize(); + prepare_camera_spaces(); +} + + + +void +SimpleRaytracer::prepare_camera_spaces() +{ + Vec3 right = camera.cx.normalized(); + Vec3 up = camera.cy.normalized(); + + Matrix44 camera_to_world = { right.x, right.y, right.z, 0, + up.x, up.y, up.z, 0, + camera.dir.x, camera.dir.y, camera.dir.z, 0, + camera.eye.x, camera.eye.y, camera.eye.z, 1 }; + + name_transform("camera", camera_to_world); + + // Seems never used once moved to named transforms + m_world_to_camera = camera_to_world.inverse(); + Matrix44 M = m_world_to_camera; + float depthrange = (double)m_yon - (double)m_hither; + // clang-format off + if (m_projection == RS::Hashes::perspective) { + float tanhalffov = tanf (0.5f * m_fov * M_PI/180.0); + Matrix44 camera_to_screen ( 1/tanhalffov, 0, 0, 0, + 0, 1/tanhalffov, 0, 0, + 0, 0, m_yon/depthrange, 1, + 0, 0, -m_yon*m_hither/depthrange, 0); + M = M * camera_to_screen; + } else { + Matrix44 camera_to_screen ( 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1/depthrange, 0, + 0, 0, -m_hither/depthrange, 1); + M = M * camera_to_screen; + } + name_transform("screen", M.inverse()); + + float aspect = (float)camera.yres / (float)camera.xres; + float screenleft = -1.0, screenwidth = 2.0; + float screenbottom = -1.0 * aspect, screenheight = 2.0 * aspect; + Matrix44 screen_to_ndc (1/screenwidth, 0, 0, 0, + 0, 1/screenheight, 0, 0, + 0, 0, 1, 0, + -screenleft/screenwidth, -screenbottom/screenheight, 0, 1); + M = M * screen_to_ndc; + name_transform("NDC", M.inverse()); + + Matrix44 ndc_to_raster (camera.xres, 0, 0, 0, + 0, camera.yres, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + M = M * ndc_to_raster; + name_transform("raster", M.inverse()); + // clang-format on } @@ -577,48 +634,6 @@ bool SimpleRaytracer::get_inverse_matrix(ShaderGlobals* /*sg*/, Matrix44& result, ustringhash to, float /*time*/) { - if (to == OSL::Hashes::camera || to == OSL::Hashes::screen - || to == OSL::Hashes::NDC || to == RS::Hashes::raster) { - // clang-format off - Matrix44 M = m_world_to_camera; - if (to == OSL::Hashes::screen || to == OSL::Hashes::NDC || to == RS::Hashes::raster) { - float depthrange = (double)m_yon-(double)m_hither; - if (m_projection == RS::Hashes::perspective) { - float tanhalffov = tanf (0.5f * m_fov * M_PI/180.0); - Matrix44 camera_to_screen (1/tanhalffov, 0, 0, 0, - 0, 1/tanhalffov, 0, 0, - 0, 0, m_yon/depthrange, 1, - 0, 0, -m_yon*m_hither/depthrange, 0); - M = M * camera_to_screen; - } else { - Matrix44 camera_to_screen (1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1/depthrange, 0, - 0, 0, -m_hither/depthrange, 1); - M = M * camera_to_screen; - } - if (to == OSL::Hashes::NDC || to == RS::Hashes::raster) { - float screenleft = -1.0, screenwidth = 2.0; - float screenbottom = -1.0, screenheight = 2.0; - Matrix44 screen_to_ndc (1/screenwidth, 0, 0, 0, - 0, 1/screenheight, 0, 0, - 0, 0, 1, 0, - -screenleft/screenwidth, -screenbottom/screenheight, 0, 1); - M = M * screen_to_ndc; - if (to == RS::Hashes::raster) { - Matrix44 ndc_to_raster (camera.xres, 0, 0, 0, - 0, camera.yres, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - M = M * ndc_to_raster; - } - } - } - // clang-format on - result = M; - return true; - } - TransformMap::const_iterator found = m_named_xforms.find(to); if (found != m_named_xforms.end()) { result = *(found->second); diff --git a/src/testrender/simpleraytracer.h b/src/testrender/simpleraytracer.h index 124266eca..14bc42049 100644 --- a/src/testrender/simpleraytracer.h +++ b/src/testrender/simpleraytracer.h @@ -85,6 +85,7 @@ class SimpleRaytracer : public RendererServices { float yon, int xres, int yres); virtual void parse_scene_xml(const std::string& scenefile); + virtual void prepare_camera_spaces(); virtual void prepare_render(); void prepare_lights(); void prepare_geometry(); @@ -113,7 +114,7 @@ class SimpleRaytracer : public RendererServices { int getBackgroundShaderID() const { return backgroundShaderID; } int getBackgroundResolution() const { return backgroundResolution; } -private: +protected: // Camera parameters Matrix44 m_world_to_camera; ustringhash m_projection; @@ -121,6 +122,11 @@ class SimpleRaytracer : public RendererServices { float m_shutter[2]; float m_screen_window[4]; + // Named transforms + typedef std::map> TransformMap; + TransformMap m_named_xforms; + +private: int backgroundShaderID = -1; int backgroundResolution = 1024; int aa = 1; @@ -140,10 +146,6 @@ class SimpleRaytracer : public RendererServices { std::unique_ptr m_errhandler; bool m_had_error = false; - // Named transforms - typedef std::map> TransformMap; - TransformMap m_named_xforms; - // Attribute and userdata retrieval -- for fast dispatch, use a hash // table to map attribute names to functions that retrieve them. We // imagine this to be fairly quick, but for a performance-critical diff --git a/testsuite/render-background/scene.xml b/testsuite/render-background/scene.xml index 3e7028ef8..92ff05893 100644 --- a/testsuite/render-background/scene.xml +++ b/testsuite/render-background/scene.xml @@ -1,5 +1,5 @@ - + string filename "../common/textures/kitchen_probe.hdr"; diff --git a/testsuite/render-bumptest/bumptest.xml b/testsuite/render-bumptest/bumptest.xml index 6b78db75f..64079da45 100644 --- a/testsuite/render-bumptest/bumptest.xml +++ b/testsuite/render-bumptest/bumptest.xml @@ -1,5 +1,5 @@ - +