1 // Copyright 2017-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3
4 #include "test_volumetric.h"
5 #include "ArcballCamera.h"
6 #include "ospray_testing.h"
7 #include "rkcommon/utility/multidim_index_sequence.h"
8
9 namespace OSPRayTestScenes {
10
11 // Helper functions /////////////////////////////////////////////////////////
12
13 // creates a torus
14 // volumetric data: stores data of torus
15 // returns created ospvolume of torus
CreateTorus(const int size)16 static cpp::Volume CreateTorus(const int size)
17 {
18 std::vector<float> volumetricData(size * size * size);
19
20 const float r = 30;
21 const float R = 80;
22 const int size_2 = size / 2;
23 const vec3i dims = vec3i(size);
24 rkcommon::index_sequence_3D idx(dims);
25 for (vec3i i : idx) {
26 const float X = i.x - size_2;
27 const float Y = i.y - size_2;
28 const float Z = i.z - size_2;
29
30 const float d = (R - std::sqrt(Z * Z + Y * Y));
31 volumetricData[idx.flatten(i)] = r * r - d * d - X * X;
32 }
33
34 cpp::Volume torus("structuredRegular");
35 torus.setParam("data", cpp::CopiedData(volumetricData.data(), vec3ul(size)));
36 torus.setParam("gridOrigin", vec3f(-0.5f));
37 torus.setParam("gridSpacing", vec3f(1.f / size));
38 torus.commit();
39 return torus;
40 }
41
42 /////////////////////////////////////////////////////////////////////////////
43
TextureVolumeTransform_deprecated()44 TextureVolumeTransform_deprecated::TextureVolumeTransform_deprecated()
45 {
46 rendererType = GetParam();
47 }
48
SetUp()49 void TextureVolumeTransform_deprecated::SetUp()
50 {
51 Base::SetUp();
52
53 camera.setParam("position", vec3f(.66f, .66f, -2.5f));
54 camera.setParam("direction", vec3f(0.f, 0.f, 1.f));
55 camera.setParam("up", vec3f(0.f, 1.f, 0.f));
56
57 // Create transfer function
58 cpp::TransferFunction transferFun("piecewiseLinear");
59 {
60 std::vector<vec3f> colors = {vec3f(1.f, 0.f, 0.f),
61 vec3f(0.f, 1.f, 0.f),
62 vec3f(0.f, 1.f, 1.f),
63 vec3f(1.f, 1.f, 0.f),
64 vec3f(1.f, 1.f, 1.f),
65 vec3f(1.f, 0.f, 1.f)};
66 std::vector<float> opacities = {1.f, 1.f};
67
68 transferFun.setParam("valueRange", vec2f(-10000.f, 100.f));
69 transferFun.setParam("color", cpp::CopiedData(colors));
70 transferFun.setParam("opacity", cpp::CopiedData(opacities));
71 transferFun.commit();
72 }
73
74 // Create volumetric model
75 cpp::VolumetricModel volumetricModel(CreateTorus(256));
76 volumetricModel.setParam("transferFunction", transferFun);
77 volumetricModel.commit();
78
79 // Create volume texture
80 cpp::Texture tex("volume");
81 tex.setParam("volume", volumetricModel);
82 tex.commit();
83
84 // Create a single sphere geometry
85 cpp::Geometry sphere("sphere");
86 {
87 sphere.setParam("sphere.position", cpp::CopiedData(vec3f(0.f)));
88 sphere.setParam("radius", 0.51f);
89 sphere.commit();
90 }
91
92 // Prepare material array
93 constexpr uint32_t cols = 2;
94 constexpr uint32_t rows = 2;
95 std::array<cpp::Material, cols * rows> materials;
96 {
97 // Create materials
98 for (uint32_t i = 0; i < cols * rows; i++) {
99 cpp::Material mat(rendererType, "obj");
100 mat.setParam("map_kd", tex);
101 mat.commit();
102 materials[i] = mat;
103 }
104
105 // Set scale
106 materials[1].setParam("map_kd.transform", affine3f::scale(vec3f(1.2f)));
107 materials[1].commit();
108
109 // Set rotation
110 materials[2].setParam(
111 "map_kd.transform", affine3f::rotate(vec3f(0.5, 0.2, 1), 1.f));
112 materials[2].commit();
113 }
114
115 // Prepare instances
116 rkcommon::index_sequence_2D idx(vec2i(cols, rows));
117 for (auto i : idx) {
118 // Create geometric model
119 cpp::GeometricModel model(sphere);
120 model.setParam("material", materials[idx.flatten(i)]);
121 model.commit();
122
123 // Create group
124 cpp::Group group;
125 group.setParam("geometry", cpp::CopiedData(model));
126 group.commit();
127
128 // Create instance
129 cpp::Instance instance(group);
130 instance.setParam(
131 "transform", affine3f::translate(1.25f * vec3f(i.x, i.y, 0.f)));
132 instance.commit();
133 AddInstance(instance);
134 }
135
136 cpp::Light ambient("ambient");
137 ambient.setParam("intensity", 0.5f);
138 AddLight(ambient);
139 }
140
TextureVolumeTransform()141 TextureVolumeTransform::TextureVolumeTransform()
142 {
143 rendererType = GetParam();
144 }
145
SetUp()146 void TextureVolumeTransform::SetUp()
147 {
148 Base::SetUp();
149
150 camera.setParam("position", vec3f(.66f, .66f, -2.5f));
151 camera.setParam("direction", vec3f(0.f, 0.f, 1.f));
152 camera.setParam("up", vec3f(0.f, 1.f, 0.f));
153
154 // Create transfer function
155 cpp::TransferFunction transferFun("piecewiseLinear");
156 {
157 std::vector<vec3f> colors = {vec3f(1.f, 0.f, 0.f),
158 vec3f(0.f, 1.f, 0.f),
159 vec3f(0.f, 1.f, 1.f),
160 vec3f(1.f, 1.f, 0.f),
161 vec3f(1.f, 1.f, 1.f),
162 vec3f(1.f, 0.f, 1.f)};
163 std::vector<float> opacities = {1.f, 1.f};
164
165 transferFun.setParam("valueRange", vec2f(-10000.f, 100.f));
166 transferFun.setParam("color", cpp::CopiedData(colors));
167 transferFun.setParam("opacity", cpp::CopiedData(opacities));
168 transferFun.commit();
169 }
170
171 // Create volumetric model
172 cpp::Volume volume = CreateTorus(256);
173 volume.commit();
174
175 // Create volume texture
176 cpp::Texture tex("volume");
177 tex.setParam("volume", volume);
178 tex.setParam("transferFunction", transferFun);
179 tex.commit();
180
181 // Create a single sphere geometry
182 cpp::Geometry sphere("sphere");
183 {
184 sphere.setParam("sphere.position", cpp::CopiedData(vec3f(0.f)));
185 sphere.setParam("radius", 0.51f);
186 sphere.commit();
187 }
188
189 // Prepare material array
190 constexpr uint32_t cols = 2;
191 constexpr uint32_t rows = 2;
192 std::array<cpp::Material, cols * rows> materials;
193 {
194 // Create materials
195 for (uint32_t i = 0; i < cols * rows; i++) {
196 cpp::Material mat(rendererType, "obj");
197 mat.setParam("map_kd", tex);
198 mat.commit();
199 materials[i] = mat;
200 }
201
202 // Set scale
203 materials[1].setParam("map_kd.transform", affine3f::scale(vec3f(1.2f)));
204 materials[1].commit();
205
206 // Set rotation
207 materials[2].setParam(
208 "map_kd.transform", affine3f::rotate(vec3f(0.5, 0.2, 1), 1.f));
209 materials[2].commit();
210 }
211
212 // Prepare instances
213 rkcommon::index_sequence_2D idx(vec2i(cols, rows));
214 for (auto i : idx) {
215 // Create geometric model
216 cpp::GeometricModel model(sphere);
217 model.setParam("material", materials[idx.flatten(i)]);
218 model.commit();
219
220 // Create group
221 cpp::Group group;
222 group.setParam("geometry", cpp::CopiedData(model));
223 group.commit();
224
225 // Create instance
226 cpp::Instance instance(group);
227 instance.setParam(
228 "transform", affine3f::translate(1.25f * vec3f(i.x, i.y, 0.f)));
229 instance.commit();
230 AddInstance(instance);
231 }
232
233 cpp::Light ambient("ambient");
234 ambient.setParam("intensity", 0.5f);
235 AddLight(ambient);
236 }
237
DepthCompositeVolume()238 DepthCompositeVolume::DepthCompositeVolume()
239 {
240 auto params = GetParam();
241 rendererType = std::get<0>(params);
242 bgColor = std::get<1>(params);
243 }
244
SetUp()245 void DepthCompositeVolume::SetUp()
246 {
247 Base::SetUp();
248
249 camera.setParam("position", vec3f(0.f, 0.f, 1.f));
250 camera.setParam("direction", vec3f(0.f, 0.f, -1.f));
251 camera.setParam("up", vec3f(0.f, 1.f, 0.f));
252
253 cpp::Volume torus = CreateTorus(256);
254 cpp::VolumetricModel volumetricModel(torus);
255
256 cpp::TransferFunction transferFun("piecewiseLinear");
257 transferFun.setParam("valueRange", vec2f(-10000.f, 10000.f));
258
259 std::vector<vec3f> colors = {
260 vec3f(1.0f, 0.0f, 0.0f), vec3f(0.0f, 1.0f, 0.0f)};
261
262 std::vector<float> opacities = {0.05f, 1.0f};
263
264 transferFun.setParam("color", cpp::CopiedData(colors));
265 transferFun.setParam("opacity", cpp::CopiedData(opacities));
266 transferFun.commit();
267
268 volumetricModel.setParam("transferFunction", transferFun);
269 volumetricModel.commit();
270
271 AddModel(volumetricModel);
272
273 cpp::Texture depthTex("texture2d");
274
275 std::vector<float> texData(imgSize.product());
276 for (int y = 0; y < imgSize.y; y++) {
277 for (int x = 0; x < imgSize.x; x++) {
278 const size_t index = imgSize.x * y + x;
279 if (x < imgSize.x / 3) {
280 texData[index] = 999.f;
281 } else if (x < (imgSize.x * 2) / 3) {
282 texData[index] = 0.75f;
283 } else {
284 texData[index] = 0.00001f;
285 }
286 }
287 }
288
289 depthTex.setParam("format", OSP_TEXTURE_R32F);
290 depthTex.setParam("filter", OSP_TEXTURE_FILTER_NEAREST);
291 depthTex.setParam("data", cpp::CopiedData(texData.data(), imgSize));
292 depthTex.commit();
293
294 renderer.setParam("map_maxDepth", depthTex);
295 renderer.setParam("backgroundColor", bgColor);
296
297 cpp::Light ambient("ambient");
298 ambient.setParam("intensity", 0.5f);
299 AddLight(ambient);
300 }
301
UnstructuredVolume()302 UnstructuredVolume::UnstructuredVolume()
303 {
304 auto params = GetParam();
305 rendererType = std::get<0>(params);
306 showCells = std::get<1>(params);
307 }
308
SetUp()309 void UnstructuredVolume::SetUp()
310 {
311 Base::SetUp();
312
313 instances.clear();
314
315 auto builder = ospray::testing::newBuilder("unstructured_volume");
316 ospray::testing::setParam(builder, "rendererType", rendererType);
317 ospray::testing::setParam(builder, "showCells", showCells);
318 ospray::testing::commit(builder);
319
320 world = ospray::testing::buildWorld(builder);
321 ospray::testing::release(builder);
322
323 world.commit();
324
325 auto worldBounds = world.getBounds<box3f>();
326
327 ArcballCamera arcballCamera(worldBounds, imgSize);
328
329 camera.setParam("position", arcballCamera.eyePos());
330 camera.setParam("direction", arcballCamera.lookDir());
331 camera.setParam("up", arcballCamera.upDir());
332
333 renderer.setParam("maxPathLength", 1);
334 }
335
336 // Test Instantiations //////////////////////////////////////////////////////
337
338 INSTANTIATE_TEST_SUITE_P(TestScenesVolumes,
339 FromOsprayTesting,
340 ::testing::Combine(::testing::Values("gravity_spheres_volume",
341 "perlin_noise_volumes",
342 "unstructured_volume_simple",
343 "particle_volume",
344 "vdb_volume",
345 "gravity_spheres_amr"),
346 ::testing::Values("scivis", "pathtracer", "ao"),
347 ::testing::Values(16)));
348
349 INSTANTIATE_TEST_SUITE_P(TestScenesVolumesStrictParams,
350 FromOsprayTesting,
351 ::testing::Values(std::make_tuple("perlin_noise_many_volumes", "scivis", 4),
352 std::make_tuple("perlin_noise_many_volumes", "pathtracer", 32),
353 std::make_tuple("perlin_noise_many_volumes", "ao", 4)));
354
TEST_P(UnstructuredVolume,simple)355 TEST_P(UnstructuredVolume, simple)
356 {
357 PerformRenderTest();
358 }
359
360 INSTANTIATE_TEST_SUITE_P(TestScenesVolumes,
361 UnstructuredVolume,
362 ::testing::Combine(::testing::Values("scivis", "pathtracer", "ao"),
363 ::testing::Values(false, true)));
364
TEST_P(TextureVolumeTransform_deprecated,simple)365 TEST_P(TextureVolumeTransform_deprecated, simple)
366 {
367 PerformRenderTest();
368 }
369
370 INSTANTIATE_TEST_SUITE_P(
371 Renderers, TextureVolumeTransform_deprecated, ::testing::Values("scivis"));
372
TEST_P(TextureVolumeTransform,simple)373 TEST_P(TextureVolumeTransform, simple)
374 {
375 PerformRenderTest();
376 }
377
378 INSTANTIATE_TEST_SUITE_P(
379 Renderers, TextureVolumeTransform, ::testing::Values("scivis"));
380
TEST_P(DepthCompositeVolume,simple)381 TEST_P(DepthCompositeVolume, simple)
382 {
383 PerformRenderTest();
384 }
385
386 INSTANTIATE_TEST_SUITE_P(Renderers,
387 DepthCompositeVolume,
388 ::testing::Combine(::testing::Values("scivis"),
389 ::testing::Values(vec4f(0.f),
390 vec4f(1.f),
391 vec4f(0.f, 0.f, 0.f, 1.f),
392 vec4f(1.f, 0.f, 0.f, 0.5f))));
393
394 } // namespace OSPRayTestScenes
395