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