1 // Copyright 2017-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #include "ospray_testing.h"
5 #include "test_fixture.h"
6 
7 namespace OSPRayTestScenes {
8 
9 class MotionBlurBoxes
10     : public Base,
11       public ::testing::TestWithParam<std::tuple<const char * /*renderer*/,
12           OSPStereoMode,
13           OSPShutterType,
14           float /*rollingShutterDuration*/>>
15 {
16  public:
17   MotionBlurBoxes();
18   void SetUp() override;
19 
20  protected:
21   OSPStereoMode stereoMode{OSP_STEREO_NONE};
22   OSPShutterType shutterType{OSP_SHUTTER_GLOBAL};
23   float rollingShutterDuration{0.f};
24 };
25 
MotionBlurBoxes()26 MotionBlurBoxes::MotionBlurBoxes()
27 {
28   auto params = GetParam();
29   rendererType = std::get<0>(params);
30   stereoMode = std::get<1>(params);
31   shutterType = std::get<2>(params);
32   rollingShutterDuration = std::get<3>(params);
33   samplesPerPixel = rendererType == "pathtracer" ? 64 : 16;
34 }
35 
SetUp()36 void MotionBlurBoxes::SetUp()
37 {
38   Base::SetUp();
39   renderer.setParam("backgroundColor", vec4f(0.2, 0.2, 0.2, 1.0f));
40   camera.setParam("position", vec3f(0, 0, -9));
41   camera.setParam("stereoMode", stereoMode);
42   camera.setParam("shutter", range1f(0.0f, 1.0f));
43   camera.setParam("shutterType", shutterType);
44   camera.setParam("rollingShutterDuration", rollingShutterDuration);
45 
46   cpp::Geometry boxGeometry("box");
47   boxGeometry.setParam(
48       "box", cpp::CopiedData(box3f(vec3f(-0.5f), vec3f(0.5f))));
49   boxGeometry.commit();
50   cpp::GeometricModel model(boxGeometry);
51 
52   cpp::Material material(rendererType, "obj");
53   material.setParam("kd", vec3f(0.8f, 0.1, 0.4));
54   material.setParam("ks", vec3f(0.2f));
55   material.setParam("ns", 99.f);
56   material.commit();
57   model.setParam("material", material);
58   model.commit();
59 
60   cpp::Volume volume("structuredRegular");
61   std::vector<float> volData(8);
62   std::generate(
63       volData.begin(), volData.end(), [n = 0]() mutable { return n++; });
64   volume.setParam("data", cpp::CopiedData(volData.data(), vec3ul(2)));
65   volume.setParam("gridOrigin", vec3f(-0.5, 0.5, -0.5));
66   volume.setParam("filter", (int)OSP_VOLUME_FILTER_NEAREST);
67   volume.commit();
68 
69   cpp::TransferFunction transferFun("piecewiseLinear");
70   transferFun.setParam("valueRange", vec2f(0.f, 7.f));
71   std::vector<vec3f> colors = {vec3f(1.0f, 0.5f, 0.5f),
72       vec3f(0.5f, 1.0f, 0.5f),
73       vec3f(0.5f, 1.0f, 1.0f),
74       vec3f(0.5f, 0.5f, 1.0f)};
75   std::vector<float> opacities = {0.1f, 1.0f};
76   transferFun.setParam("color", cpp::CopiedData(colors));
77   transferFun.setParam("opacity", cpp::CopiedData(opacities));
78   transferFun.commit();
79 
80   cpp::VolumetricModel volModel(volume);
81   volModel.setParam("transferFunction", transferFun);
82   volModel.setParam("densityScale", 99.0f);
83   volModel.commit();
84 
85   cpp::Geometry sphereGeometry("sphere");
86   sphereGeometry.setParam(
87       "sphere.position", cpp::CopiedData(vec3f(0.3f, 0.6f, -0.2f)));
88   sphereGeometry.setParam("radius", 0.6f);
89   sphereGeometry.commit();
90   cpp::GeometricModel clipModel(sphereGeometry);
91   clipModel.commit();
92 
93   cpp::Group group;
94   group.setParam("geometry", cpp::CopiedData(model));
95   group.setParam("volume", cpp::CopiedData(volModel));
96   group.setParam("clippingGeometry", cpp::CopiedData(clipModel));
97   group.commit();
98 
99   { // static original
100     cpp::Instance instance(group);
101     instance.setParam("transform", affine3f::rotate(vec3f(1, 1, 0.1), -0.4));
102     AddInstance(instance);
103   }
104 
105   { // linear
106     cpp::Instance instance(group);
107     std::vector<affine3f> xfms;
108     xfms.push_back(affine3f::translate(vec3f(3, -3, 0)));
109     xfms.push_back(affine3f::translate(vec3f(2.5, -3, 0)));
110     xfms.push_back(affine3f::translate(vec3f(2.2, -1, 0)));
111     instance.setParam("motion.transform", cpp::CopiedData(xfms));
112     AddInstance(instance);
113   }
114 
115   { // linear, time
116     cpp::Instance instance(group);
117     std::vector<affine3f> xfms;
118     xfms.push_back(affine3f::translate(vec3f(5, -3, 0)));
119     xfms.push_back(affine3f::translate(vec3f(4.5, -3, 0)));
120     xfms.push_back(affine3f::translate(vec3f(4.2, -1, 0)));
121     instance.setParam("motion.transform", cpp::CopiedData(xfms));
122     instance.setParam("time", range1f(-2, 0.8));
123     AddInstance(instance);
124   }
125 
126   { // scale
127     cpp::Instance instance(group);
128     std::vector<affine3f> xfms;
129     xfms.push_back(affine3f::translate(vec3f(1, 2, 0)));
130     xfms.push_back(affine3f::translate(vec3f(1, 2, 0))
131         * affine3f::scale(vec3f(1.8, 0.9, 1)));
132     instance.setParam("motion.transform", cpp::CopiedData(xfms));
133     AddInstance(instance);
134   }
135 
136   { // rot
137     cpp::Instance instance(group);
138     std::vector<affine3f> xfms;
139     xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 0.8));
140     xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 1.2));
141     xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 1.6));
142     instance.setParam("motion.transform", cpp::CopiedData(xfms));
143     AddInstance(instance);
144   }
145 
146   { // quaternion
147     cpp::Instance instance(group);
148     std::vector<vec3f> ss;
149     ss.push_back(vec3f(0, -4, 0));
150     ss.push_back(vec3f(0, -4, 0));
151     ss.push_back(vec3f(0, -4, 0));
152     instance.setParam("motion.pivot", cpp::CopiedData(ss));
153     std::vector<quatf> qs;
154     qs.push_back(quatf::rotate(vec3f(0, 0, 1), -0.8));
155     qs.push_back(quatf::rotate(vec3f(0, 0, 1), -1.2));
156     qs.push_back(quatf::rotate(vec3f(0, 0, 1), -1.6));
157     instance.setParam("motion.rotation", cpp::CopiedData(qs));
158     std::vector<vec3f> ts;
159     ts.push_back(vec3f(0, 4, 0));
160     ts.push_back(vec3f(0, 4, 0));
161     ts.push_back(vec3f(0, 4, 0));
162     instance.setParam("motion.translation", cpp::CopiedData(ts));
163     AddInstance(instance);
164   }
165 
166   cpp::Light distant("distant");
167   distant.setParam("intensity", 3.0f);
168   distant.setParam("direction", vec3f(0.3f, -4.0f, 2.8f));
169   distant.setParam("color", vec3f(1.0f, 0.5f, 0.5f));
170   distant.setParam("angularDiameter", 1.0f);
171   AddLight(distant);
172 
173   cpp::Light ambient("ambient");
174   ambient.setParam("visible", false);
175   ambient.setParam("intensity", 0.1f);
176   AddLight(ambient);
177 }
178 
179 // Test camera MB (also in combination with stereo) ////////////////////////////
180 class MotionCamera
181     : public Base,
182       public ::testing::TestWithParam<
183           std::tuple<const char * /*camera*/, OSPStereoMode, OSPShutterType>>
184 {
185  public:
186   MotionCamera();
187   void SetUp() override;
188 
189  protected:
190   std::string cameraType;
191   vec3f pos{0.0f, 0.0f, -0.5f};
192   OSPStereoMode stereoMode{OSP_STEREO_NONE};
193   OSPShutterType shutterType{OSP_SHUTTER_GLOBAL};
194 };
195 
MotionCamera()196 MotionCamera::MotionCamera()
197 {
198   rendererType = "pathtracer";
199   samplesPerPixel = 64;
200 
201   auto params = GetParam();
202   cameraType = std::get<0>(params);
203   stereoMode = std::get<1>(params);
204   shutterType = std::get<2>(params);
205 }
206 
SetUp()207 void MotionCamera::SetUp()
208 {
209   Base::SetUp();
210 
211   instances.clear();
212 
213   auto builder = ospray::testing::newBuilder("cornell_box");
214   ospray::testing::setParam(builder, "rendererType", rendererType);
215   ospray::testing::commit(builder);
216 
217   world = ospray::testing::buildWorld(builder);
218   ospray::testing::release(builder);
219 
220   camera = cpp::Camera(cameraType);
221   if (cameraType != "panoramic") {
222     pos.z = -2.f;
223     camera.setParam("aspect", imgSize.x / (float)imgSize.y);
224   }
225   camera.setParam("position", pos);
226   if (cameraType == "orthographic")
227     camera.setParam("height", 2.0f);
228   else
229     camera.setParam("stereoMode", stereoMode);
230 
231   std::vector<affine3f> xfms;
232   xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 0.1));
233   xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 0.12));
234   camera.setParam("motion.transform", cpp::CopiedData(xfms));
235   camera.setParam("shutter", range1f(0.0f, 1.0f));
236   camera.setParam("shutterType", shutterType);
237 }
238 
239 // Test Instantiations //////////////////////////////////////////////////////
240 
TEST_P(MotionBlurBoxes,instance_mb)241 TEST_P(MotionBlurBoxes, instance_mb)
242 {
243   PerformRenderTest();
244 }
245 
246 INSTANTIATE_TEST_SUITE_P(TestMotionBlur,
247     MotionBlurBoxes,
248     ::testing::Combine(::testing::Values("scivis", "pathtracer"),
249         ::testing::Values(OSP_STEREO_NONE),
250         ::testing::Values(OSP_SHUTTER_GLOBAL),
251         ::testing::Values(0.f)));
252 
253 INSTANTIATE_TEST_SUITE_P(CameraRollingShutter,
254     MotionBlurBoxes,
255     ::testing::Combine(::testing::Values("pathtracer"),
256         ::testing::Values(OSP_STEREO_NONE),
257         ::testing::Values(OSP_SHUTTER_ROLLING_RIGHT,
258             OSP_SHUTTER_ROLLING_LEFT,
259             OSP_SHUTTER_ROLLING_DOWN,
260             OSP_SHUTTER_ROLLING_UP),
261         ::testing::Values(0.f, 0.1f)));
262 
263 INSTANTIATE_TEST_SUITE_P(CameraStereoRollingShutter,
264     MotionBlurBoxes,
265     ::testing::Combine(::testing::Values("pathtracer"),
266         ::testing::Values(OSP_STEREO_TOP_BOTTOM),
267         ::testing::Values(OSP_SHUTTER_ROLLING_DOWN),
268         ::testing::Values(0.f)));
269 
TEST_P(MotionCamera,camera_mb)270 TEST_P(MotionCamera, camera_mb)
271 {
272   PerformRenderTest();
273 }
274 
275 INSTANTIATE_TEST_SUITE_P(Camera,
276     MotionCamera,
277     ::testing::Combine(::testing::Values("perspective", "panoramic"),
278         ::testing::Values(OSP_STEREO_NONE,
279             OSP_STEREO_RIGHT,
280             OSP_STEREO_LEFT,
281             OSP_STEREO_SIDE_BY_SIDE,
282             OSP_STEREO_TOP_BOTTOM),
283         ::testing::Values(OSP_SHUTTER_GLOBAL)));
284 
285 INSTANTIATE_TEST_SUITE_P(CameraOrtho,
286     MotionCamera,
287     ::testing::Values(
288         std::make_tuple("orthographic", OSP_STEREO_NONE, OSP_SHUTTER_GLOBAL)));
289 
290 INSTANTIATE_TEST_SUITE_P(CameraStereoRollingShutter,
291     MotionCamera,
292     ::testing::Combine(::testing::Values("perspective"),
293         ::testing::Values(OSP_STEREO_TOP_BOTTOM),
294         ::testing::Values(OSP_SHUTTER_ROLLING_DOWN)));
295 
296 } // namespace OSPRayTestScenes
297