Skip to content

Commit a2b7543

Browse files
fix fov, add named camera spaces
Signed-off-by: Alexey Smolenchuk <alexey.smolenchuk@gmail.com>
1 parent 0848570 commit a2b7543

6 files changed

Lines changed: 97 additions & 51 deletions

File tree

src/testrender/cuda/optix_raytracer.cu

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ __raygen__setglobals()
245245
OSL::pvt::test_str_2 = render_params.test_str_2;
246246
}
247247

248+
OSL::pvt::num_named_xforms = render_params.num_named_xforms;
249+
OSL::pvt::xform_name_buffer = render_params.xform_name_buffer;
250+
OSL::pvt::xform_buffer = render_params.xform_buffer;
251+
248252
if (render_params.bg_id < 0)
249253
return;
250254

src/testrender/optixraytracer.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ OptixRaytracer::OptixRaytracer()
114114

115115
CUDA_CHECK(cudaSetDevice(0));
116116
CUDA_CHECK(cudaStreamCreate(&m_cuda_stream));
117+
118+
cache = OIIO::ImageCache::create ();
117119
}
118120

119121

@@ -930,7 +932,7 @@ OptixRaytracer::get_texture_handle(ustring filename,
930932
auto itr = m_samplers.find(filename);
931933
if (itr == m_samplers.end()) {
932934
// Open image to check the number of mip levels
933-
OIIO::ImageBuf image;
935+
OIIO::ImageBuf image(filename, 0, 0, cache);
934936
if (!image.init_spec(filename, 0, 0)) {
935937
errhandler().errorfmt("Could not load: {} (hash {})", filename,
936938
filename);
@@ -1092,6 +1094,27 @@ OptixRaytracer::render(int xres OSL_MAYBE_UNUSED, int yres OSL_MAYBE_UNUSED)
10921094
params.test_str_1 = test_str_1;
10931095
params.test_str_2 = test_str_2;
10941096

1097+
// Named transforms
1098+
int nxforms = m_named_xforms.size();
1099+
params.num_named_xforms = nxforms;
1100+
params.xform_name_buffer = DEVICE_ALLOC(sizeof(ustringhash)*nxforms);
1101+
params.xform_buffer = DEVICE_ALLOC(sizeof(Transformation)*nxforms);
1102+
1103+
std::vector<ustringhash> names;
1104+
std::vector<Transformation> xforms;
1105+
names.reserve(nxforms);
1106+
xforms.reserve(nxforms);
1107+
1108+
for (auto &pair : m_named_xforms)
1109+
{
1110+
names.push_back(pair.first);
1111+
xforms.push_back(*pair.second);
1112+
}
1113+
1114+
COPY_TO_DEVICE(params.xform_name_buffer, names.data(), sizeof(ustringhash)*nxforms);
1115+
COPY_TO_DEVICE(params.xform_buffer, xforms.data(), sizeof(Transformation)*nxforms);
1116+
CUDA_SYNC_CHECK();
1117+
10951118
// Mesh data
10961119
params.verts = d_vertices;
10971120
params.triangles = d_vert_indices;

src/testrender/optixraytracer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include <OpenImageIO/ustring.h>
8+
#include <OpenImageIO/imagecache.h>
89

910
#include <OSL/oslexec.h>
1011

@@ -144,6 +145,8 @@ class OptixRaytracer final : public SimpleRaytracer {
144145
// CUdeviceptrs that need to be freed after we are done
145146
std::vector<CUdeviceptr> m_ptrs_to_free;
146147
std::vector<cudaArray_t> m_arrays_to_free;
148+
149+
std::shared_ptr<OIIO::ImageCache> cache;
147150
};
148151

149152

src/testrender/raytracer.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,9 @@ struct Camera {
135135
{
136136
float k = OIIO::fast_tan(fov * float(M_PI / 360));
137137
Vec3 right = dir.cross(up).normalize();
138-
cx = right * (xres * k / yres);
139-
cy = (cx.cross(dir)).normalize() * k;
138+
// fov is horizontal
139+
cx = right * k;
140+
cy = (cx.cross(dir)).normalize() * k * yres / xres;
140141
}
141142

142143
// Get a ray for the given screen coordinates.
@@ -147,7 +148,7 @@ struct Camera {
147148
// components with magnitudes slightly greater than 1.0, which can cause
148149
// downstream computations to blow up and produce NaNs. Normalizing the
149150
// vector again avoids this issue.
150-
const Vec3 v = (cx * (x * invw - 0.5f) + cy * (0.5f - y * invh) + dir)
151+
const Vec3 v = (cx * (x * invw - 0.5f) * 2.f + cy * (0.5f - y * invh) * 2.f + dir)
151152
#ifndef __CUDACC__
152153
.normalize();
153154
#else

src/testrender/simpleraytracer.cpp

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ SimpleRaytracer::parse_scene_xml(const std::string& scenefile)
332332
if (fov_attr)
333333
fov = OIIO::Strutil::from_string<float>(fov_attr.value());
334334

335+
m_fov = fov;
335336
camera.lookat(eye, dir, up, fov);
336337
} else if (strcmp(node.name(), "Sphere") == 0) {
337338
// load sphere
@@ -506,6 +507,60 @@ SimpleRaytracer::parse_scene_xml(const std::string& scenefile)
506507
if (scene.num_prims() == 0)
507508
errhandler().severefmt("No primitives in scene");
508509
camera.finalize();
510+
prepare_camera_spaces();
511+
}
512+
513+
514+
515+
void
516+
SimpleRaytracer::prepare_camera_spaces()
517+
{
518+
Vec3 right = camera.cx.normalized();
519+
Vec3 up = camera.cy.normalized();
520+
521+
Matrix44 camera_to_world = {right.x, right.y, right.z, 0,
522+
up.x, up.y, up.z, 0,
523+
camera.dir.x, camera.dir.y, camera.dir.z, 0,
524+
camera.eye.x, camera.eye.y, camera.eye.z, 1};
525+
526+
name_transform("camera", camera_to_world );
527+
528+
// Seems never used once moved to named transforms
529+
m_world_to_camera = camera_to_world.inverse();
530+
Matrix44 M = m_world_to_camera;
531+
float depthrange = (double)m_yon-(double)m_hither;
532+
if (m_projection == RS::Hashes::perspective) {
533+
float tanhalffov = tanf (0.5f * m_fov * M_PI/180.0);
534+
Matrix44 camera_to_screen (1/tanhalffov, 0, 0, 0,
535+
0, 1/tanhalffov, 0, 0,
536+
0, 0, m_yon/depthrange, 1,
537+
0, 0, -m_yon*m_hither/depthrange, 0);
538+
M = M * camera_to_screen;
539+
} else {
540+
Matrix44 camera_to_screen (1, 0, 0, 0,
541+
0, 1, 0, 0,
542+
0, 0, 1/depthrange, 0,
543+
0, 0, -m_hither/depthrange, 1);
544+
M = M * camera_to_screen;
545+
}
546+
name_transform("screen", M.inverse() );
547+
548+
float aspect = (float)camera.yres / (float)camera.xres;
549+
float screenleft = -1.0, screenwidth = 2.0;
550+
float screenbottom = -1.0*aspect, screenheight = 2.0*aspect;
551+
Matrix44 screen_to_ndc (1/screenwidth, 0, 0, 0,
552+
0, 1/screenheight, 0, 0,
553+
0, 0, 1, 0,
554+
-screenleft/screenwidth, -screenbottom/screenheight, 0, 1);
555+
M = M * screen_to_ndc;
556+
name_transform("NDC", M.inverse() );
557+
558+
Matrix44 ndc_to_raster (camera.xres, 0, 0, 0,
559+
0, camera.yres, 0, 0,
560+
0, 0, 1, 0,
561+
0, 0, 0, 1);
562+
M = M * ndc_to_raster;
563+
name_transform("raster", M.inverse() );
509564
}
510565

511566

@@ -577,48 +632,6 @@ bool
577632
SimpleRaytracer::get_inverse_matrix(ShaderGlobals* /*sg*/, Matrix44& result,
578633
ustringhash to, float /*time*/)
579634
{
580-
if (to == OSL::Hashes::camera || to == OSL::Hashes::screen
581-
|| to == OSL::Hashes::NDC || to == RS::Hashes::raster) {
582-
// clang-format off
583-
Matrix44 M = m_world_to_camera;
584-
if (to == OSL::Hashes::screen || to == OSL::Hashes::NDC || to == RS::Hashes::raster) {
585-
float depthrange = (double)m_yon-(double)m_hither;
586-
if (m_projection == RS::Hashes::perspective) {
587-
float tanhalffov = tanf (0.5f * m_fov * M_PI/180.0);
588-
Matrix44 camera_to_screen (1/tanhalffov, 0, 0, 0,
589-
0, 1/tanhalffov, 0, 0,
590-
0, 0, m_yon/depthrange, 1,
591-
0, 0, -m_yon*m_hither/depthrange, 0);
592-
M = M * camera_to_screen;
593-
} else {
594-
Matrix44 camera_to_screen (1, 0, 0, 0,
595-
0, 1, 0, 0,
596-
0, 0, 1/depthrange, 0,
597-
0, 0, -m_hither/depthrange, 1);
598-
M = M * camera_to_screen;
599-
}
600-
if (to == OSL::Hashes::NDC || to == RS::Hashes::raster) {
601-
float screenleft = -1.0, screenwidth = 2.0;
602-
float screenbottom = -1.0, screenheight = 2.0;
603-
Matrix44 screen_to_ndc (1/screenwidth, 0, 0, 0,
604-
0, 1/screenheight, 0, 0,
605-
0, 0, 1, 0,
606-
-screenleft/screenwidth, -screenbottom/screenheight, 0, 1);
607-
M = M * screen_to_ndc;
608-
if (to == RS::Hashes::raster) {
609-
Matrix44 ndc_to_raster (camera.xres, 0, 0, 0,
610-
0, camera.yres, 0, 0,
611-
0, 0, 1, 0,
612-
0, 0, 0, 1);
613-
M = M * ndc_to_raster;
614-
}
615-
}
616-
}
617-
// clang-format on
618-
result = M;
619-
return true;
620-
}
621-
622635
TransformMap::const_iterator found = m_named_xforms.find(to);
623636
if (found != m_named_xforms.end()) {
624637
result = *(found->second);

src/testrender/simpleraytracer.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class SimpleRaytracer : public RendererServices {
8585
float yon, int xres, int yres);
8686

8787
virtual void parse_scene_xml(const std::string& scenefile);
88+
virtual void prepare_camera_spaces();
8889
virtual void prepare_render();
8990
void prepare_lights();
9091
void prepare_geometry();
@@ -113,14 +114,19 @@ class SimpleRaytracer : public RendererServices {
113114
int getBackgroundShaderID() const { return backgroundShaderID; }
114115
int getBackgroundResolution() const { return backgroundResolution; }
115116

116-
private:
117+
protected:
117118
// Camera parameters
118119
Matrix44 m_world_to_camera;
119120
ustringhash m_projection;
120121
float m_fov, m_pixelaspect, m_hither, m_yon;
121122
float m_shutter[2];
122123
float m_screen_window[4];
123124

125+
// Named transforms
126+
typedef std::map<ustringhash, std::shared_ptr<Transformation>> TransformMap;
127+
TransformMap m_named_xforms;
128+
129+
private:
124130
int backgroundShaderID = -1;
125131
int backgroundResolution = 1024;
126132
int aa = 1;
@@ -140,10 +146,6 @@ class SimpleRaytracer : public RendererServices {
140146
std::unique_ptr<OIIO::ErrorHandler> m_errhandler;
141147
bool m_had_error = false;
142148

143-
// Named transforms
144-
typedef std::map<ustringhash, std::shared_ptr<Transformation>> TransformMap;
145-
TransformMap m_named_xforms;
146-
147149
// Attribute and userdata retrieval -- for fast dispatch, use a hash
148150
// table to map attribute names to functions that retrieve them. We
149151
// imagine this to be fairly quick, but for a performance-critical

0 commit comments

Comments
 (0)