diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d8b0652d1..76f4c157c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ Version History --------------- +### Changes in v1.2.1: + +- Various bugfixes related to MPI distributed rendering, ISPC issues + on Windows, and other build related issues. + ### Changes in v1.2.0: - Added support for volumes with voxelType `short` (16-bit signed diff --git a/README.md b/README.md index 2382fe106d..a0644eeccb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ OSPRay ====== -This is release v1.2.0 of OSPRay. For changes and new features see the +This is release v1.2.1 of OSPRay. For changes and new features see the [changelog](CHANGELOG.md). Also visit http://www.ospray.org for more information. @@ -56,9 +56,8 @@ branch should always point to the latest tested bugfix release. Prerequisites ------------- -OSPRay currently supports both Linux and Mac OS X (and experimentally -Windows). In addition, before you can build OSPRay you need the -following prerequisites: +OSPRay currently supports Linux, Mac OS X, and Windows. In addition, +before you can build OSPRay you need the following prerequisites: - You can clone the latest OSPRay sources via: @@ -157,9 +156,9 @@ Documentation ============= The following [API -documentation](http://www.sdvis.org/ospray/download/OSPRay_readme_devel.pdf "OSPRay Documentation") +documentation](http://www.sdvis.org/ospray/download/OSPRay_readme.pdf "OSPRay Documentation") of OSPRay can also be found as a [pdf -document](http://www.sdvis.org/ospray/download/OSPRay_readme_devel.pdf "OSPRay Documentation") +document](http://www.sdvis.org/ospray/download/OSPRay_readme.pdf "OSPRay Documentation") (2.6MB). For a deeper explanation of the concepts, design, features and @@ -183,12 +182,15 @@ To access the OSPRay API you first need to include the OSPRay header where the API is compatible with C99 and C++. -In order to use the API, OSPRay must initialized with a "device". A +Initialization +-------------- + +In order to use the API, OSPRay must be initialized with a "device". A device is the object which implements the API. Creating and initializing a device can be done in either of two ways: command line arguments or manually instantiating a device. -### Initialization via command line arguments +### Command Line Arguments The first is to do so by giving OSPRay the command line from `main()` by calling @@ -252,7 +254,7 @@ convention with "`--osp:`") are understood: : Command line parameters accepted by OSPRay's `ospInit`. -### Initialization via manual device instantiation +### Manual Device Instantiation The second method of initialization is to explicitly create the device yourself, and possibly set parameters. This method looks almost @@ -318,23 +320,23 @@ to OSPRay API calls, where users can set/change parameters and recommit the device. If changes are made to the device that is already set as the current device, it does not need to be set as current again. -### Useful environment variables +### Environment Variables Finally, OSPRay's generic device parameters can be overridden via environment variables for easy changes to OSPRay's behavior without needing to change the application (variables are prefixed by convention with "`OSPRAY_`"): -| Variable | Description | -|:--------------------|:--------------------------------------------------------------| -| OSPRAY\_THREADS | equivalent to `--osp:numthreads` | -| OSPRAY\_LOG\_LEVEL | equivalent to `--osp:loglevel` | -| OSPRAY\_LOG\_OUTPUT | equivalent to `--osp:logoutput` | -| OSPRAY\_DEBUG | equivalent to both OSPRAY\_LOG\_LEVEL=2 and OSPRAY\_THREADS=1 | +| Variable | Description | +|:--------------------|:---------------------------------| +| OSPRAY\_THREADS | equivalent to `--osp:numthreads` | +| OSPRAY\_LOG\_LEVEL | equivalent to `--osp:loglevel` | +| OSPRAY\_LOG\_OUTPUT | equivalent to `--osp:logoutput` | +| OSPRAY\_DEBUG | equivalent to `--osp:debug` | : Environment variables interpreted by OSPRay. -### Handling error and status messages from OSPRay +### Handling Error and Status Messages from OSPRay Applications may be interested in messages which OSPRay emits, whether for debugging or logging events. Applications can call @@ -349,7 +351,7 @@ desired by an application will require that a callback be provided. Note that callbacks for C++ std::cout and std::cerr can be alternatively set through ospInit() or OSPRAY\_LOG\_OUTPUT environment variable. -### Loading OSPRay extensions at runtime +### Loading OSPRay Extensions at Runtime OSPRay's functionality can be extended via plugins, which are implemented in shared libraries. To load plugin `name` from @@ -579,27 +581,28 @@ summarized in the table below. If `voxelRange` is not provided for a volume OSPRay will compute it based on the voxel data, which may result in slower data updates. -| Type | Name | Description | -|:-------|:------------------------|:-------------------------------------------------------------------------| -| vec3i | dimensions | number of voxels in each dimension $(x, y, z)$ | -| string | voxelType | data type of each voxel, currently supported are: | -|   |   | "uchar" (8 bit unsigned integer) | -|   |   | "ushort" (16 bit unsigned integer) | -|   |   | "float" (32 bit single precision floating point) | -|   |   | "double" (64 bit double precision floating point) | -| vec2f | voxelRange | minimum and maximum of the scalar values | -| vec3f | gridOrigin | origin of the grid in world-space, default $(0, 0, 0)$ | -| vec3f | gridSpacing | size of the grid cells in world-space, default $(1, 1, 1)$ | -| bool | gradientShadingEnabled | volume is rendered with surface shading according to normalized gradient | -| bool | preIntegration | enable using pre-integration for transferFunction lookups | -| bool | singleShade | shade only at the point of maximum intensity | -| bool | adaptiveSampling | adapt ray step size based on opacity | -| float | adaptiveScalar | modifier for adaptive step size | -| float | adaptiveMaxSamplingRate | maximum sampling rate for adaptive sampling | -| float | samplingRate | sampling rate of the volume. This is the minumum step size for adaptive. | -| vec3f | specular | specular component for shading | -| vec3f | volumeClippingBoxLower | clip the volume values in object coordinates | -| vec3f | volumeClippingBoxUpper | clip the volume values in object coordinates | +| Type | Name | Default| Description | +|:-------|:------------------------|------------:|:----------------------------------------------------------------------------------| +| vec3i | dimensions | | number of voxels in each dimension $(x, y, z)$ | +| string | voxelType | | data type of each voxel, currently supported are: | +| | | | "uchar" (8 bit unsigned integer) | +| | | | "short" (16 bit signed integer) | +| | | | "ushort" (16 bit unsigned integer) | +| | | | "float" (32 bit single precision floating point) | +| | | | "double" (64 bit double precision floating point) | +| vec2f | voxelRange | | minimum and maximum of the scalar values | +| vec3f | gridOrigin | $(0, 0, 0)$| origin of the grid in world-space | +| vec3f | gridSpacing | $(1, 1, 1)$| size of the grid cells in world-space | +| bool | gradientShadingEnabled | false| volume is rendered with surface shading wrt. to normalized gradient | +| bool | preIntegration | false| use pre-integration for [transfer function](#transfer-function) lookups | +| bool | singleShade | true| shade only at the point of maximum intensity | +| bool | adaptiveSampling | true| adapt ray step size based on opacity | +| float | adaptiveScalar | 15| modifier for adaptive step size | +| float | adaptiveMaxSamplingRate | 2| maximum sampling rate for adaptive sampling | +| float | samplingRate | 0.125| sampling rate of the volume (this is the minimum step size for adaptive sampling) | +| vec3f | specular | gray 0.3| specular color for shading | +| vec3f | volumeClippingBoxLower | disabled| lower coordinate (in object-space) to clip the volume values | +| vec3f | volumeClippingBoxUpper | disabled| upper coordinate (in object-space) to clip the volume values | : Parameters to configure a structured volume. @@ -991,7 +994,7 @@ were rendered with OpenGL. The screen-sized [texture](#texture) distance of primary rays, thus objects of other renderers can hide objects rendered by OSPRay. -### Path tracer +### Path Tracer The path tracer supports soft shadows, indirect illumination and realistic materials. In addition to the [general parameters](#renderer) @@ -1078,11 +1081,11 @@ The call returns `NULL` if that type of camera is not known by the renderer, or else an `OSPLight` handle to the created light source. All light sources[^2] accept the following parameters: -| Type | Name | Default | Description | -|:---------|:----------|:--------|:---------------------------------------| -| vec3f(a) | color | white | color of the light | -| float | intensity | 1 | intensity of the light (a factor) | -| bool | isVisible | true | whether the light can be directly seen | +| Type | Name | Default| Description | +|:---------|:----------|--------:|:---------------------------------------| +| vec3f(a) | color | white| color of the light | +| float | intensity | 1| intensity of the light (a factor) | +| bool | isVisible | true| whether the light can be directly seen | : Parameters accepted by the all lights. diff --git a/apps/common/commandline/RendererParser.cpp b/apps/common/commandline/RendererParser.cpp index b5fed8775a..8d2a0e85a8 100644 --- a/apps/common/commandline/RendererParser.cpp +++ b/apps/common/commandline/RendererParser.cpp @@ -56,6 +56,7 @@ void DefaultRendererParser::finalize() { parsedRenderer.set("aoSamples", aoSamples); parsedRenderer.set("shadowsEnabled", shadows); + parsedRenderer.set("aoTransparencyEnabled", 1); } parsedRenderer.set("spp", spp); diff --git a/apps/common/sg/common/Integrator.cpp b/apps/common/sg/common/Integrator.cpp index ff30f05ca6..6dfefcb66e 100644 --- a/apps/common/sg/common/Integrator.cpp +++ b/apps/common/sg/common/Integrator.cpp @@ -38,6 +38,7 @@ namespace ospray { { ospSet1i(ospRenderer, "aoSamples", 1); ospSet1i(ospRenderer, "shadowsEnabled", 1); + ospSet1i(ospRenderer, "aoTransparencyEnabled", 1); } if (!ospRenderer) diff --git a/apps/common/widgets/OSPGlutViewer.cpp b/apps/common/widgets/OSPGlutViewer.cpp index d66aa36f24..cea0921894 100644 --- a/apps/common/widgets/OSPGlutViewer.cpp +++ b/apps/common/widgets/OSPGlutViewer.cpp @@ -294,7 +294,7 @@ void OSPGlutViewer::display() renderer.renderFrame(frameBuffer, OSP_FB_COLOR | OSP_FB_ACCUM); - // set the glut3d widget's frame buffer to the opsray frame buffer, + // set the glut3d widget's frame buffer to the OSPRay frame buffer, // then display ucharFB = (uint32_t *)frameBuffer.map(OSP_FB_COLOR); frameBufferMode = Glut3DWidget::FRAMEBUFFER_UCHAR; diff --git a/apps/common/widgets/glut3D.h b/apps/common/widgets/glut3D.h index b80b8bf2b7..f9f5ab12ff 100644 --- a/apps/common/widgets/glut3D.h +++ b/apps/common/widgets/glut3D.h @@ -40,7 +40,7 @@ namespace ospray { /*! initialize everything GLUT-related */ OSPRAY_GLUT3D_INTERFACE void initGLUT(int32_t *ac, const char **av); - /*! switch over to GLUT for control flow. This functoin will not return */ + /*! switch over to GLUT for control flow. This function will not return */ OSPRAY_GLUT3D_INTERFACE void runGLUT(); using ospcommon::AffineSpace3fa; diff --git a/apps/ospTutorial.c b/apps/ospTutorial.c index f1e90724c6..6dfecfb1c6 100644 --- a/apps/ospTutorial.c +++ b/apps/ospTutorial.c @@ -45,7 +45,7 @@ void writePPM(const char *fileName, for (int x = 0; x < size->x; x++) { out[3*x + 0] = in[4*x + 0]; out[3*x + 1] = in[4*x + 1]; - out[3*x + 2] = in[4*x +2 ]; + out[3*x + 2] = in[4*x + 2]; } fwrite(out, 3*size->x, sizeof(char), file); } diff --git a/apps/ospTutorial.cpp b/apps/ospTutorial.cpp index 9e26e09224..682fc0c36d 100644 --- a/apps/ospTutorial.cpp +++ b/apps/ospTutorial.cpp @@ -45,7 +45,7 @@ void writePPM(const char *fileName, for (int x = 0; x < size.x; x++) { out[3*x + 0] = in[4*x + 0]; out[3*x + 1] = in[4*x + 1]; - out[3*x + 2] = in[4*x +2 ]; + out[3*x + 2] = in[4*x + 2]; } fwrite(out, 3*size.x, sizeof(char), file); } diff --git a/apps/volumeViewer/VolumeViewer.cpp b/apps/volumeViewer/VolumeViewer.cpp index 6debb45553..e08044ea79 100644 --- a/apps/volumeViewer/VolumeViewer.cpp +++ b/apps/volumeViewer/VolumeViewer.cpp @@ -467,7 +467,6 @@ void VolumeViewer::setPlane(bool st) } } -//! Set gradient shading flag on all volumes. void VolumeViewer::setAOWeight(double value) { ospSet1f(renderer, "aoWeight", value); @@ -476,7 +475,6 @@ void VolumeViewer::setAOWeight(double value) render(); } -//! Set gradient shading flag on all volumes. void VolumeViewer::setAOSamples(int value) { if (aoSamples != value) @@ -777,6 +775,7 @@ void VolumeViewer::initObjects(const std::string &renderer_type) { ospSet1i(renderer, "aoSamples", 1); ospSet1i(renderer, "shadowsEnabled", 1); + ospSet1i(renderer, "aoTransparencyEnabled", 1); } // Create OSPRay ambient and directional lights. GUI elements will modify their parameters. diff --git a/cmake/configure_embree.cmake b/cmake/configure_embree.cmake index a4a5b9da62..e8e8b1910b 100644 --- a/cmake/configure_embree.cmake +++ b/cmake/configure_embree.cmake @@ -52,7 +52,7 @@ ELSE() ENDIF() ENDIF() -IF (${EMBREE_MAX_ISA} STREQUAL "NONE") +IF (EMBREE_MAX_ISA STREQUAL "NONE") SET(EMBREE_ISA_SUPPORTS_SSE4 ${EMBREE_ISA_SSE42}) SET(EMBREE_ISA_SUPPORTS_AVX ${EMBREE_ISA_AVX}) SET(EMBREE_ISA_SUPPORTS_AVX2 ${EMBREE_ISA_AVX2}) @@ -62,17 +62,18 @@ ELSE() SET(EMBREE_ISA_SUPPORTS_AVX FALSE) SET(EMBREE_ISA_SUPPORTS_AVX2 FALSE) SET(EMBREE_ISA_SUPPORTS_AVX512 FALSE) - - IF (${EMBREE_MAX_ISA} STREQUAL "SSE4.1") + + + IF (EMBREE_MAX_ISA MATCHES "SSE4\\.[12]$") SET(EMBREE_ISA_SUPPORTS_SSE4 TRUE) - ELSEIF (${EMBREE_MAX_ISA} STREQUAL "AVX") + ELSEIF (EMBREE_MAX_ISA STREQUAL "AVX") SET(EMBREE_ISA_SUPPORTS_SSE4 TRUE) SET(EMBREE_ISA_SUPPORTS_AVX TRUE) - ELSEIF (${EMBREE_MAX_ISA} STREQUAL "AVX2") + ELSEIF (EMBREE_MAX_ISA STREQUAL "AVX2") SET(EMBREE_ISA_SUPPORTS_SSE4 TRUE) SET(EMBREE_ISA_SUPPORTS_AVX TRUE) SET(EMBREE_ISA_SUPPORTS_AVX2 TRUE) - ELSEIF (${EMBREE_MAX_ISA} STREQUAL "AVX512KNL") + ELSEIF (EMBREE_MAX_ISA STREQUAL "AVX512KNL") SET(EMBREE_ISA_SUPPORTS_SSE4 TRUE) SET(EMBREE_ISA_SUPPORTS_AVX TRUE) SET(EMBREE_ISA_SUPPORTS_AVX2 TRUE) diff --git a/cmake/ospray_options.cmake b/cmake/ospray_options.cmake index 51cf8ead6c..af8be4f42c 100644 --- a/cmake/ospray_options.cmake +++ b/cmake/ospray_options.cmake @@ -20,7 +20,7 @@ SET(OSPRAY_VERSION_MAJOR 1) SET(OSPRAY_VERSION_MINOR 2) -SET(OSPRAY_VERSION_PATCH 0) +SET(OSPRAY_VERSION_PATCH 1) SET(OSPRAY_VERSION_GITHASH 0) IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) FIND_PACKAGE(Git) diff --git a/cmake/package.cmake b/cmake/package.cmake index d33ccb07ab..7b2c7fb8d7 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -191,6 +191,7 @@ ELSE() # Linux specific settings #SET(CPACK_RPM_CHANGELOG_FILE "") # ChangeLog of the RPM; also CHANGELOG.md is not in the required format SET(CPACK_RPM_PACKAGE_ARCHITECTURE x86_64) SET(CPACK_RPM_PACKAGE_URL http://www.ospray.org/) + SET(CPACK_RPM_DEFAULT_DIR_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) # post install and uninstall scripts SET(CPACK_RPM_lib_POST_INSTALL_SCRIPT_FILE ${PROJECT_SOURCE_DIR}/scripts/rpm_ldconfig.sh) diff --git a/components/ospcommon/CMakeLists.txt b/components/ospcommon/CMakeLists.txt index 470b5f9be3..5c95f0bb18 100644 --- a/components/ospcommon/CMakeLists.txt +++ b/components/ospcommon/CMakeLists.txt @@ -40,8 +40,9 @@ ELSE() tasking/parallel_for.inl tasking/parallel_for.h - tasking/async.inl tasking/async.h + tasking/schedule.inl + tasking/schedule.h tasking/tasking_system_handle.cpp tasking/TaskingTypeTraits.h tasking/TaskSys.cpp diff --git a/components/ospcommon/tasking/TaskingTypeTraits.h b/components/ospcommon/tasking/TaskingTypeTraits.h index 3259268888..a82151e0e9 100644 --- a/components/ospcommon/tasking/TaskingTypeTraits.h +++ b/components/ospcommon/tasking/TaskingTypeTraits.h @@ -45,25 +45,25 @@ namespace ospcommon { template struct has_operator_method_with_integral_param { - using T_SHORT_PARAM = void(T::*)(short) const; - using T_INT_PARAM = void(T::*)(int) const; - using T_UNSIGNED_PARAM = void(T::*)(unsigned int) const; - using T_SIZET_PARAM = void(T::*)(size_t) const; + template + using t_param = void(T::*)(P) const; + using byte_t = unsigned char; + using operator_t = decltype(&T::operator()); - using PARAM_IS_SHORT = std::is_same; - using PARAM_IS_INT = std::is_same; - using PARAM_IS_UNSIGNED = std::is_same; - using PARAM_IS_SIZET = std::is_same; + using param_is_byte = std::is_same , operator_t>; + using param_is_short = std::is_same , operator_t>; + using param_is_int = std::is_same , operator_t>; + using param_is_unsigned = std::is_same, operator_t>; + using param_is_long = std::is_same , operator_t>; + using param_is_size_t = std::is_same , operator_t>; static const bool value = has_operator_method::value && - (PARAM_IS_SHORT::value - || PARAM_IS_INT::value - || PARAM_IS_UNSIGNED::value - || PARAM_IS_SIZET::value); + (param_is_byte::value || + param_is_short::value || + param_is_int::value || + param_is_unsigned::value || + param_is_long::value || + param_is_size_t::value); }; } // ::ospcommon diff --git a/components/ospcommon/tasking/async.h b/components/ospcommon/tasking/async.h index eef7b1cd32..a9fed32d2f 100644 --- a/components/ospcommon/tasking/async.h +++ b/components/ospcommon/tasking/async.h @@ -16,26 +16,35 @@ #pragma once -#include "TaskingTypeTraits.h" -#include "async.inl" +#include +#include + +#include "schedule.h" namespace ospcommon { + template + using operator_return_t = typename std::result_of::type; + // NOTE(jda) - This abstraction takes a lambda which should take captured // variables by *value* to ensure no captured references race // with the task itself. - - // NOTE(jda) - No priority is associated with this call, but could be added - // later with a hint enum, using a default value for the priority - // to not require specifying it. template - inline void async(TASK_T&& fcn) + inline auto async(TASK_T&& fcn) -> std::future> { static_assert(has_operator_method::value, - "ospray::async() requires the implementation of method " - "'void TASK_T::operator()'."); + "ospcommon::schedule() requires the implementation of method " + "'RETURN_T TASK_T::operator()', where RETURN_T is the " + "return value of the passed in task."); + + using package_t = std::packaged_task()>; + + auto task = new package_t(std::forward(fcn)); + auto future = task->get_future(); + + schedule([=](){ (*task)(); delete task; }); - async_impl(std::forward(fcn)); + return future; } } // ::ospcommon diff --git a/components/ospcommon/tasking/parallel_for.h b/components/ospcommon/tasking/parallel_for.h index 59c137a05d..2e14ef0bae 100644 --- a/components/ospcommon/tasking/parallel_for.h +++ b/components/ospcommon/tasking/parallel_for.h @@ -29,7 +29,7 @@ namespace ospcommon { static_assert(has_operator_method_with_integral_param::value, "ospcommon::parallel_for() requires the implementation of " "method 'void TASK_T::operator(P taskIndex), where P is of " - "type short, int, uint, or size_t."); + "type unsigned char, short, int, uint, long, or size_t."); parallel_for_impl(nTasks, std::forward(fcn)); } @@ -42,7 +42,7 @@ namespace ospcommon { static_assert(has_operator_method_with_integral_param::value, "ospcommon::serial_for() requires the implementation of " "method 'void TASK_T::operator(P taskIndex), where P is of " - "type short, int, uint, or size_t."); + "type unsigned char, short, int, uint, long, or size_t."); for (int taskIndex = 0; taskIndex < nTasks; ++taskIndex) { fcn(taskIndex); diff --git a/components/ospcommon/tasking/parallel_for.inl b/components/ospcommon/tasking/parallel_for.inl index 824031b810..6c62436b81 100644 --- a/components/ospcommon/tasking/parallel_for.inl +++ b/components/ospcommon/tasking/parallel_for.inl @@ -16,6 +16,8 @@ #pragma once +#include + #ifdef OSPRAY_TASKING_TBB # include #elif defined(OSPRAY_TASKING_CILK) diff --git a/components/ospcommon/tasking/schedule.h b/components/ospcommon/tasking/schedule.h new file mode 100644 index 0000000000..730d1ea49b --- /dev/null +++ b/components/ospcommon/tasking/schedule.h @@ -0,0 +1,41 @@ +// ======================================================================== // +// Copyright 2009-2017 Intel Corporation // +// // +// Licensed under the Apache License, Version 2.0 (the "License"); // +// you may not use this file except in compliance with the License. // +// You may obtain a copy of the License at // +// // +// http://www.apache.org/licenses/LICENSE-2.0 // +// // +// Unless required by applicable law or agreed to in writing, software // +// distributed under the License is distributed on an "AS IS" BASIS, // +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // +// See the License for the specific language governing permissions and // +// limitations under the License. // +// ======================================================================== // + +#pragma once + +#include "TaskingTypeTraits.h" +#include "schedule.inl" + +namespace ospcommon { + + // NOTE(jda) - This abstraction takes a lambda which should take captured + // variables by *value* to ensure no captured references race + // with the task itself. + + // NOTE(jda) - No priority is associated with this call, but could be added + // later with a hint enum, using a default value for the priority + // to not require specifying it. + template + inline void schedule(TASK_T&& fcn) + { + static_assert(has_operator_method::value, + "ospcommon::schedule() requires the implementation of method " + "'void TASK_T::operator()'."); + + schedule_impl(std::forward(fcn)); + } + +} // ::ospcommon diff --git a/components/ospcommon/tasking/async.inl b/components/ospcommon/tasking/schedule.inl similarity index 98% rename from components/ospcommon/tasking/async.inl rename to components/ospcommon/tasking/schedule.inl index 3e8d1215b7..0ca694758a 100644 --- a/components/ospcommon/tasking/async.inl +++ b/components/ospcommon/tasking/schedule.inl @@ -27,7 +27,7 @@ namespace ospcommon { template - inline void async_impl(TASK_T&& fcn) + inline void schedule_impl(TASK_T&& fcn) { #ifdef OSPRAY_TASKING_TBB struct LocalTBBTask : public tbb::task diff --git a/modules/mpi/CMakeLists.txt b/modules/mpi/CMakeLists.txt index ed4e4b8e68..49bb673b57 100644 --- a/modules/mpi/CMakeLists.txt +++ b/modules/mpi/CMakeLists.txt @@ -22,7 +22,6 @@ IF (OSPRAY_MODULE_MPI) OSPRAY_BUILD_COMPONENT(mpiCommon) - OPTION(OSPRAY_EXP_DATA_PARALLEL "Experimental data-parallel compositing mode" ON) OPTION(OSPRAY_PIN_ASYNC "Pin async mpi comm threads?" OFF) MARK_AS_ADVANCED(OSPRAY_PIN_ASYNC) diff --git a/modules/mpi/OSPMPIConfig.h.in b/modules/mpi/OSPMPIConfig.h.in index f791c49969..22ebd7b8da 100644 --- a/modules/mpi/OSPMPIConfig.h.in +++ b/modules/mpi/OSPMPIConfig.h.in @@ -18,7 +18,3 @@ #cmakedefine OSPRAY_PIN_ASYNC -#cmakedefine OSPRAY_EXP_DATA_PARALLEL -#ifdef OSPRAY_EXP_DATA_PARALLEL -# define EXP_DATA_PARALLEL 1 -#endif diff --git a/modules/mpi/fb/DistributedFrameBuffer.cpp b/modules/mpi/fb/DistributedFrameBuffer.cpp index a0875753cb..d5b90c9c73 100644 --- a/modules/mpi/fb/DistributedFrameBuffer.cpp +++ b/modules/mpi/fb/DistributedFrameBuffer.cpp @@ -18,8 +18,8 @@ #include "DistributedFrameBuffer_TileTypes.h" #include "DistributedFrameBuffer_ispc.h" -#include "ospcommon/tasking/async.h" #include "ospcommon/tasking/parallel_for.h" +#include "ospcommon/tasking/schedule.h" #ifdef _WIN32 # include // for Sleep @@ -406,7 +406,7 @@ namespace ospray { } } - async([=]() { + schedule([=]() { switch (_msg->command) { case MASTER_WRITE_TILE_NONE: this->processMessage((MasterTileMessage_NONE*)_msg); diff --git a/modules/mpi/render/volume/RaycastVolumeRenderer.cpp b/modules/mpi/render/volume/RaycastVolumeRenderer.cpp index b57091d90b..df2c01594b 100644 --- a/modules/mpi/render/volume/RaycastVolumeRenderer.cpp +++ b/modules/mpi/render/volume/RaycastVolumeRenderer.cpp @@ -25,12 +25,11 @@ // ours // ispc exports #include "RaycastVolumeRenderer_ispc.h" -#if EXP_DATA_PARALLEL -# include "mpiCommon/MPICommon.h" -# include "../../fb/DistributedFrameBuffer.h" -# include "../../volume/DataDistributedBlockedVolume.h" -# include "render/LoadBalancer.h" -#endif + +#include "mpiCommon/MPICommon.h" +#include "../../fb/DistributedFrameBuffer.h" +#include "../../volume/DataDistributedBlockedVolume.h" +#include "render/LoadBalancer.h" #define TILE_CACHE_SAFE_MUTEX 0 @@ -42,8 +41,6 @@ namespace ospray { return new RaycastVolumeMaterial; } -#if EXP_DATA_PARALLEL - struct CacheForBlockTiles { CacheForBlockTiles(size_t numBlocks) @@ -251,7 +248,7 @@ namespace ospray { // check if we're even in mpi parallel mode (can't do // data-parallel otherwise) - if (!ospray::core::isMpiParallel()) { + if (!ospray::mpi::isMpiParallel()) { throw std::runtime_error("#dvr: need data-parallel rendering, " "but not running in mpi mode!?"); } @@ -291,14 +288,13 @@ namespace ospray { renderTask.dpv = ddVolumeVec[0]; size_t NTASKS = renderTask.numTiles_x * renderTask.numTiles_y; - parallel_for(NTASKS, renderTask); + parallel_for(NTASKS, std::move(renderTask)); dfb->waitUntilFinished(); Renderer::endFrame(nullptr, channelFlags); return fb->endFrame(0.f); } -#endif void RaycastVolumeRenderer::commit() { diff --git a/modules/mpi/render/volume/RaycastVolumeRenderer.h b/modules/mpi/render/volume/RaycastVolumeRenderer.h index cbc51e1703..260ce5f34e 100644 --- a/modules/mpi/render/volume/RaycastVolumeRenderer.h +++ b/modules/mpi/render/volume/RaycastVolumeRenderer.h @@ -16,6 +16,7 @@ #pragma once +#include "OSPMPIConfig.h" #include "render/Renderer.h" namespace ospray { @@ -40,10 +41,8 @@ namespace ospray { //! A string description of this class. std::string toString() const override; -#if EXP_DATA_PARALLEL /*! per-frame data to describe the data-parallel components */ float renderFrame(FrameBuffer *fb, const uint32 channelFlags) override; -#endif private: diff --git a/modules/mpi/render/volume/RaycastVolumeRenderer.ih b/modules/mpi/render/volume/RaycastVolumeRenderer.ih index 91ade9189b..b4cfcd3677 100644 --- a/modules/mpi/render/volume/RaycastVolumeRenderer.ih +++ b/modules/mpi/render/volume/RaycastVolumeRenderer.ih @@ -16,6 +16,7 @@ #pragma once +#include "OSPMPIConfig.h" #include "common/Ray.ih" #include "lights/Light.ih" #include "math/box.ih" diff --git a/modules/mpi/render/volume/RaycastVolumeRenderer.ispc b/modules/mpi/render/volume/RaycastVolumeRenderer.ispc index 4fa15074fd..8db1cc7ef9 100644 --- a/modules/mpi/render/volume/RaycastVolumeRenderer.ispc +++ b/modules/mpi/render/volume/RaycastVolumeRenderer.ispc @@ -186,7 +186,6 @@ RaycastVolumeRenderer_intersectVolumes(uniform RaycastVolumeRenderer *uniform se Ray volumeRay = ray; volumeRay.t0 = infinity; -#if EXP_DATA_PARALLEL if (passInfo.block != NULL) { // Intersect volume bounding box. float t0, t1; @@ -219,12 +218,10 @@ RaycastVolumeRenderer_intersectVolumes(uniform RaycastVolumeRenderer *uniform se // Return the first intersected volume. return volume; } -#endif // Test each volume and find the first intersection. for (uniform int32 i=0; isuper.model->volumeCount; i++) { Volume *uniform volume_i = self->super.model->volumes[i]; -#if EXP_DATA_PARALLEL // hack for now .... if this does not have a 'getvoxel' function // it must be a data parallel volume... if (volume_i->computeSample == NULL) { @@ -232,16 +229,13 @@ RaycastVolumeRenderer_intersectVolumes(uniform RaycastVolumeRenderer *uniform se // do NOT render data-parallel volumes in regular sampling mode... continue; } -#endif // Intersect volume bounding box. float t0, t1; intersectBox(ray, volume_i->boundingBox, t0, t1); -#if EXP_DATA_PARALLEL t0 = max(t0,passInfo.region.lower); t1 = min(t1,passInfo.region.upper); -#endif // Clip against volume clipping box (if specified). if(ne(volume_i->volumeClippingBox.lower, @@ -469,7 +463,6 @@ export void RaycastVolumeRenderer_setLights(void *uniform _self, self->numLights = numLights; } -#if EXP_DATA_PARALLEL extern "C" Tile * uniform CacheForBlockTiles_getTileForBlock(void *uniform _tileCache, uniform uint32 blockID); @@ -673,4 +666,3 @@ export void DDDVRRenderer_renderTile(void*uniform _self, } } -#endif diff --git a/modules/mpi/volume/DataDistributedBlockedVolume.cpp b/modules/mpi/volume/DataDistributedBlockedVolume.cpp index 491d49a50f..51b18f8b95 100644 --- a/modules/mpi/volume/DataDistributedBlockedVolume.cpp +++ b/modules/mpi/volume/DataDistributedBlockedVolume.cpp @@ -30,8 +30,6 @@ namespace ospray { -#if EXP_DATA_PARALLEL - //! Allocate storage and populate the volume, called through the OSPRay API. void DataDistributedBlockedVolume::commit() { @@ -290,6 +288,4 @@ namespace ospray { // that is capable of data-parallel rendering! OSP_REGISTER_VOLUME(DataDistributedBlockedVolume, data_distributed_volume); -#endif - } // ::ospray diff --git a/modules/mpi/volume/DataDistributedBlockedVolume.h b/modules/mpi/volume/DataDistributedBlockedVolume.h index 0c41814f61..95423cce1c 100644 --- a/modules/mpi/volume/DataDistributedBlockedVolume.h +++ b/modules/mpi/volume/DataDistributedBlockedVolume.h @@ -21,7 +21,6 @@ namespace ospray { -#if EXP_DATA_PARALLEL /*! \brief A type of structured volume that is data-distributed across multiple clients */ /*! \detailed This class implements a structured volume whose data @@ -91,7 +90,6 @@ namespace ospray { /*! list of data distributed blocks */ DDBlock *ddBlock; }; -#endif } // ::ospray diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 0a6267673e..9f3c945a8b 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -74,6 +74,8 @@ namespace ospray { std::string parm = av[i]; if (parm == "--osp:debug") { device->findParam("debug", true)->set(true); + // per default enable logging to cout; may be overridden later + device->error_fcn = [](const char *msg){ std::cout << msg; }; removeArgs(ac,av,i,1); } else if (parm == "--osp:verbose") { device->findParam("logLevel", true)->set(1); diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 2eec183860..b1f4420192 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -50,6 +50,7 @@ Light_SampleRes AmbientLight_sample(const uniform Light* uniform super, Light_EvalRes AmbientLight_eval(const uniform Light* uniform super, const DifferentialGeometry& dg, const vec3f& dir, + const float, const float maxDist) { uniform AmbientLight* uniform self = (uniform AmbientLight* uniform)super; diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index b5281277fb..fcb545591b 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -57,6 +57,7 @@ Light_SampleRes DirectionalLight_sample(const uniform Light* uniform super, Light_EvalRes DirectionalLight_eval(const uniform Light* uniform super, const DifferentialGeometry&, const vec3f& dir, + const float, const float maxDist) { uniform DirectionalLight* uniform self = (uniform DirectionalLight* uniform)super; diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index ce09512daf..f0a3853552 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -78,6 +78,7 @@ Light_SampleRes HDRILight_sample(const uniform Light* uniform super, Light_EvalRes HDRILight_eval(const uniform Light* uniform super, const DifferentialGeometry&, const vec3f& dir, + const float, const float maxDist) { uniform HDRILight* uniform self = (uniform HDRILight* uniform)super; diff --git a/ospray/lights/Light.ih b/ospray/lights/Light.ih index 3b482cd6e4..127d67c210 100644 --- a/ospray/lights/Light.ih +++ b/ospray/lights/Light.ih @@ -46,6 +46,7 @@ struct Light_EvalRes typedef Light_EvalRes (*Light_EvalFunc)(const uniform Light* uniform, const DifferentialGeometry&, //! point to evaluate illumination for >*/ const vec3f& dir, //! direction towards the light source, normalized >*/ + const float minDist, //! minimum distance to look for light contribution >*/ const float maxDist); //! maximum distance to look for light contribution >*/ @@ -56,7 +57,7 @@ struct Light bool isVisible; // either directly in camera, or via a straight path (i.e. through ThinGlass) }; -Light_EvalRes Light_eval(const uniform Light* uniform, const DifferentialGeometry&, const vec3f&, const float); +Light_EvalRes Light_eval(const uniform Light* uniform, const DifferentialGeometry&, const vec3f&, const float, const float); inline void Light_Constructor(uniform Light* uniform self) { diff --git a/ospray/lights/Light.ispc b/ospray/lights/Light.ispc index 3680875433..98ea9f7e24 100644 --- a/ospray/lights/Light.ispc +++ b/ospray/lights/Light.ispc @@ -19,6 +19,7 @@ Light_EvalRes Light_eval(const uniform Light* uniform, const DifferentialGeometry&, const vec3f&, + const float, const float) { Light_EvalRes res; diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 3751b39fde..00a15d6116 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -80,6 +80,7 @@ Light_SampleRes PointLight_sample(const uniform Light* uniform super, Light_EvalRes PointLight_eval(const uniform Light* uniform super, const DifferentialGeometry& dg, const vec3f& dir, + const float minDist, const float maxDist) { const PointLight* uniform self = (PointLight* uniform)super; @@ -98,7 +99,7 @@ Light_EvalRes PointLight_eval(const uniform Light* uniform super, const float t_near = (b - sqrt(radical)) / (2.f*a); const float t_far = (b + sqrt(radical)) / (2.f*a); - if (t_far > 0.0f & t_near <= maxDist) { + if (t_far > minDist & t_near <= maxDist) { // TODO: handle interior case const float sinTheta2 = sqr(self->radius) * rcp(centerDist2); diff --git a/ospray/lights/QuadLight.ispc b/ospray/lights/QuadLight.ispc index 05118d2e3c..c88f5afd04 100644 --- a/ospray/lights/QuadLight.ispc +++ b/ospray/lights/QuadLight.ispc @@ -70,6 +70,7 @@ Light_SampleRes QuadLight_sample(const uniform Light* uniform super, Light_EvalRes QuadLight_eval(const uniform Light* uniform super, const DifferentialGeometry& dg, const vec3f& dir, + const float minDist, const float maxDist) { uniform QuadLight* uniform self = (uniform QuadLight* uniform)super; @@ -93,7 +94,7 @@ Light_EvalRes QuadLight_eval(const uniform Light* uniform super, const float rcosd = rcp(cosd); const float dist = dot(self->nnormal, c) * rcosd; - if (dist > maxDist) + if (dist <= minDist | dist > maxDist) return res; res.radiance = self->radiance; diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index 482d1bce0b..a51f63565e 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -73,6 +73,7 @@ Light_SampleRes SpotLight_sample(const uniform Light* uniform super, Light_EvalRes SpotLight_eval(const uniform Light* uniform super, const DifferentialGeometry& dg, const vec3f& dir, + const float minDist, const float maxDist) { const SpotLight* uniform self = (SpotLight* uniform)super; @@ -84,17 +85,14 @@ Light_EvalRes SpotLight_eval(const uniform Light* uniform super, const float cosAngle = -dot(dir, self->frame.vz); if (cosAngle > self->cosAngleMax) { // inside illuminated cone? const vec3f vp = dg.P - self->position; - const float dp = dot(vp, self->frame.vz); - if (dp > 0.f) { // in front of light? - const float t = dp*rcp(cosAngle); - if (t <= maxDist) { - const vec3f vd = vp + t * dir; - if (dot(vd, vd) < sqr(self->radius)) { // inside disk? - const float angularAttenuation = min((cosAngle - self->cosAngleMax) * self->cosAngleScale, 1.f); - const float pdf = self->diskPdf * cosAngle; - res.radiance = self->power * (angularAttenuation * pdf); // *sqr(t)/sqr(t) cancels - res.pdf = pdf * sqr(t); - } + const float t = dot(vp, self->frame.vz) * rcp(cosAngle); + if (t > minDist & t <= maxDist) { + const vec3f vd = vp + t * dir; + if (dot(vd, vd) < sqr(self->radius)) { // inside disk? + const float angularAttenuation = min((cosAngle - self->cosAngleMax) * self->cosAngleScale, 1.f); + const float pdf = self->diskPdf * cosAngle; + res.radiance = self->power * (angularAttenuation * pdf); // *sqr(t)/sqr(t) cancels + res.pdf = pdf * sqr(t); } } } diff --git a/ospray/math/vec.ih b/ospray/math/vec.ih index 9d1f76df23..c09adba249 100644 --- a/ospray/math/vec.ih +++ b/ospray/math/vec.ih @@ -538,7 +538,7 @@ inline uniform float length(const uniform vec3f a) { return sqrtf(dot(a,a)); } inline varying float length(const varying vec3f a) { return sqrtf(dot(a,a)); } inline uniform float distance(const uniform vec3f a, const uniform vec3f b) { return length(a - b); } -inline varying float distance(const varying vec3f a, const uniform vec3f b) { return length(a - b); } +inline varying float distance(const varying vec3f a, const varying vec3f b) { return length(a - b); } inline uniform float dot(const uniform vec3fa a, const uniform vec3fa b) { return a.x*b.x+a.y*b.y+a.z*b.z; } @@ -548,7 +548,7 @@ inline uniform float length(const uniform vec3fa a) { return sqrtf(dot(a,a)); } inline varying float length(const varying vec3fa a) { return sqrtf(dot(a,a)); } inline uniform float distance(const uniform vec3fa a, const uniform vec3fa b) { return length(a - b); } -inline varying float distance(const varying vec3fa a, const uniform vec3fa b) { return length(a - b); } +inline varying float distance(const varying vec3fa a, const varying vec3fa b) { return length(a - b); } // ------------------------------------------------------------------ // cross product diff --git a/ospray/ospray.def b/ospray/ospray.def index 0b28761f8f..c6eed5b70e 100644 --- a/ospray/ospray.def +++ b/ospray/ospray.def @@ -35,9 +35,9 @@ GridAccelerator_intersect___un_3C_s_5B_unGridAccelerator_5D__3E_unfREFs_5B_vyRay GridAccelerator_intersectIsosurface___un_3C_s_5B_unGridAccelerator_5D__3E_unfun_3C_unf_3E_uniREFs_5B_vyRay_5D_avx GridAccelerator_intersectIsosurface___un_3C_s_5B_unGridAccelerator_5D__3E_unfun_3C_unf_3E_uniREFs_5B_vyRay_5D_avx2 GridAccelerator_intersectIsosurface___un_3C_s_5B_unGridAccelerator_5D__3E_unfun_3C_unf_3E_uniREFs_5B_vyRay_5D_sse4 -Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_Cvyfavx -Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_Cvyfavx2 -Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_Cvyfsse4 +Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_CvyfCvyfavx +Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_CvyfCvyfavx2 +Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_CvyfCvyfsse4 Renderer_Constructor___un_3C_s_5B_unRenderer_5D__3E_un_3C_unv_3E_avx Renderer_Constructor___un_3C_s_5B_unRenderer_5D__3E_un_3C_unv_3E_avx2 Renderer_Constructor___un_3C_s_5B_unRenderer_5D__3E_un_3C_unv_3E_sse4 diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index 6ccaa4a7e3..2ecbc20062 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -119,25 +119,33 @@ ScreenSample PathTraceIntegrator_Li(const uniform PathTracer* uniform self, const vec3f wo = neg(ray.dir); - float maxLightDist = ray.t; // per default, virtual lights are occluded by hit geometry - + float maxLightDist; // environment shading when nothing hit if (noHit(ray)) { - maxLightDist = inf; // also include envLights (i.e. the ones in infinity) + maxLightDist = inf; // include envLights (i.e. the ones in infinity) if (straightPath) { sample.alpha = 1.0f - luminance(Lw); + if ((bool)self->backplate) { + L = L + Lw * get3f(self->backplate, clamp2edge(self->backplate, pixel)); + maxLightDist = 1e38; // backplate hides envLights (i.e. the ones at infinity) + } } - if ((bool)self->backplate & straightPath) { - L = L + Lw * get3f(self->backplate, clamp2edge(self->backplate, pixel)); - maxLightDist = 1e38; // backplate hides envLights (i.e. the ones at infinity) - } - } + } else + // virtual lights are occluded by hit geometry + // because lastDg.P can be different from ray.org (when previously sampled a Dirac transmission) + // we cannot just use ray.t as maxDist + maxLightDist = distance(lastDg.P, ray.org + ray.t * ray.dir); + // add light from *virtual* lights by intersecting them for (uniform int i = self->numGeoLights; i < self->numLights; i++) { + const float minLightDist = distance(lastDg.P, ray.org); // minDist is not always zero, see above const uniform Light *uniform l = self->lights[i]; if (!straightPath || l->isVisible) { - Light_EvalRes le = l->eval(l, lastDg, ray.dir, maxLightDist); + // to correctly handle MIS through transparencies the light pdf needs to be calculated wrt. lastDg + // however, we only have a valid intersection with the light in [minLightDist, maxLightDist], + // otherwise light could be added twice + Light_EvalRes le = l->eval(l, lastDg, ray.dir, minLightDist, maxLightDist); if (reduce_max(le.radiance) > 0.0f) L = L + Lw * le.radiance * misHeuristic(lastBSDFPdf, le.pdf); } diff --git a/ospray/render/scivis/SciVisRenderer.ispc b/ospray/render/scivis/SciVisRenderer.ispc index 0769d0f045..a45964ee60 100644 --- a/ospray/render/scivis/SciVisRenderer.ispc +++ b/ospray/render/scivis/SciVisRenderer.ispc @@ -65,7 +65,7 @@ inline float lightAlpha(const uniform SciVisRenderer *uniform self, const float weight, const varying float &rayOffset, const varying vec3i &sampleID, - const uniform float &quality); + const uniform float quality); inline Volume * SciVisRenderer_intersectVolumes(const uniform SciVisRenderer *uniform renderer, @@ -160,10 +160,10 @@ inline float calculateAO(const uniform SciVisRenderer *uniform self, setRay(ao_ray, dg.P + (self->super.epsilon * dg.Ns), ao_dir, self->super.epsilon, self->aoDistance); - if (self->aoTransparencyEnabled || self->super.model->volumeCount) { + if (self->aoTransparencyEnabled) { const float rayOffset = self->super.epsilon*(1.f + s.x); occlusion += (1.f - lightAlpha(self, ao_ray, self->super.model, 1.0f, - rayOffset, sampleID, 0.1f)); + rayOffset, sampleID, 0.2f)); } else if (isOccluded(self->super.model, ao_ray)) occlusion += 1.f; } @@ -195,7 +195,7 @@ inline void shadeLights(const uniform SciVisRenderer *uniform self, varying vec3f &color, const varying float &rayOffset, const varying vec3i &sampleID, - const uniform float &quality) + const uniform float quality) { const vec3f R = ray.dir - ((2.f * dot(ray.dir, info.shadingNormal)) * info.shadingNormal); const vec3f P = dg.P + self->super.epsilon * dg.Ng; @@ -304,7 +304,7 @@ inline vec4f SciVisRenderer_computeVolumeSample(SciVisRenderer *uniform renderer vec3f litColor = make_vec3f(0.0f); info.Ns *= 0.3f; - shadeLights(renderer, ray, dg, info, litColor, rayOffset, sampleID,1.f); + shadeLights(renderer, ray, dg, info, litColor, rayOffset, sampleID,0.5f); sampleColor = litColor; } @@ -318,7 +318,7 @@ inline vec4f SciVisRenderer_computeVolumeSample(SciVisRenderer *uniform renderer vec4f SciVisRenderer_computeVolumeInterval(const SciVisRenderer *uniform renderer, Volume *uniform volume, varying Ray &ray, float tBegin, - float tEnd, float maxOpacity, bool isShadowRay, const varying float &rayOffset, const varying vec3i &sampleID, const uniform float& quality) + float tEnd, float maxOpacity, bool isShadowRay, const varying float &rayOffset, const varying vec3i &sampleID, uniform float quality) { vec3f singleCoordinates; float singleMax = -1.f; @@ -327,12 +327,12 @@ vec4f SciVisRenderer_computeVolumeInterval(const SciVisRenderer *uniform rendere float tSkipped = -1; //for adaptive, skip adapting sampling rate up to this value vec4f intervalColor = make_vec4f(0.f); volume->intersect(volume, ray); - const uniform float oneOverQuality = (1.f/quality); + // const uniform float oneOverQuality = (1.f/quality); float samplingRate = volume->samplingRate*quality; float lastSample = -1.f; const float adaptiveScalar = volume->adaptiveScalar*quality; const float maxSamplingRate = volume->adaptiveMaxSamplingRate*quality; //2.f nyquist frequency - const float adaptiveBacktrack = volume->adaptiveBacktrack*oneOverQuality; + const float adaptiveBacktrack = volume->adaptiveBacktrack; while (ray.t0 < tEnd && intervalColor.w < maxOpacity) { // Sample the volume at the hit point in world coordinates. @@ -350,7 +350,7 @@ vec4f SciVisRenderer_computeVolumeInterval(const SciVisRenderer *uniform rendere if (volume->adaptiveSampling && sampleOpacity > adaptiveBacktrack && ray.t0 > tSkipped) // adaptive backtack { //adaptively refine sampling rate - const float newSamplingRate = min(adaptiveScalar*sampleOpacity,maxSamplingRate); + const float newSamplingRate = min(adaptiveScalar*sampleOpacity*quality,maxSamplingRate); if (newSamplingRate > samplingRate + 0.01f) { samplingRate = newSamplingRate; @@ -407,7 +407,7 @@ vec4f SciVisRenderer_computeVolumeInterval(const SciVisRenderer *uniform rendere vec3f litColor = make_vec3f(0.0f); info.Ns *= 0.3f; - shadeLights(renderer, ray, dg, info, litColor, rayOffset, sampleID, quality); + shadeLights(renderer, ray, dg, info, litColor, rayOffset, sampleID, quality*0.5f); sampleColor = litColor; } } @@ -421,7 +421,7 @@ vec4f SciVisRenderer_computeVolumeInterval(const SciVisRenderer *uniform rendere intervalColor = intervalColor + (1.0f - intervalColor.w) * contribution; //adaptively refine sampling rate if (ray.t0 > tSkipped) - samplingRate = max(min(adaptiveScalar*sampleOpacity,maxSamplingRate)/*nyquist frequency*/,volume->samplingRate); + samplingRate = max(min(adaptiveScalar*sampleOpacity*quality,maxSamplingRate)/*nyquist frequency*/,volume->samplingRate*quality); volume->intersectAdaptive(volume, ray, samplingRate); } else @@ -462,7 +462,7 @@ vec4f SciVisRenderer_computeVolumeInterval(const SciVisRenderer *uniform rendere vec3f litColor = make_vec3f(0.0f); shadeAO(renderer, sampleID, dg, info, litColor); info.Ns *= 0.3f; - shadeLights(renderer, ray, dg, info, litColor, rayOffset, sampleID, quality); + shadeLights(renderer, ray, dg, info, litColor, rayOffset, sampleID, quality*0.5f); intervalColor = make_vec4f(litColor,intervalColor.w); } return intervalColor; @@ -511,7 +511,7 @@ vec4f SciVisRenderer_computeGeometrySample(SciVisRenderer *uniform self, if (info.local_opacity > 0.01f) { // worth shading? shadeAO(self, sampleID, dg, info, color); - shadeLights(self, ray, dg, info, color, rayOffset,sampleID, 1.f); + shadeLights(self, ray, dg, info, color, rayOffset,sampleID, 0.5f); } // Kill path when reached max depth or if remaining contribution too low @@ -593,7 +593,7 @@ inline float lightAlpha(const uniform SciVisRenderer *uniform self, const float weight, const varying float &rayOffset, const varying vec3i &sampleID, - const uniform float &quality) + const uniform float quality) { float alpha = 1.f; const float org_t_max = ray.t; @@ -651,7 +651,7 @@ inline float lightAlpha(const uniform SciVisRenderer *uniform self, float tEnd = volumeT+self->volumeEpsilon; foreach_unique (v in volume) { - vec4f volumeColor = SciVisRenderer_computeVolumeInterval(self, v, ray, tBegin, tEnd, 0.98f, 1, rayOffset, sampleID, quality*.5f); + vec4f volumeColor = SciVisRenderer_computeVolumeInterval(self, v, ray, tBegin, tEnd, 0.98f, 1, rayOffset, sampleID, quality); material_opacity = volumeColor.w; } } @@ -805,9 +805,7 @@ void SciVisRenderer_renderSample(uniform Renderer *uniform _self, } // Store the result in the sample. - sample.rgb.x = color.x; - sample.rgb.y = color.y; - sample.rgb.z = color.z; + sample.rgb = make_vec3f(color); sample.alpha = color.w; sample.z = depth; } diff --git a/ospray/volume/Volume.cpp b/ospray/volume/Volume.cpp index 19d9519069..24e794341b 100644 --- a/ospray/volume/Volume.cpp +++ b/ospray/volume/Volume.cpp @@ -114,7 +114,7 @@ namespace ospray { // Set the recommended sampling rate for ray casting based renderers. ispc::Volume_setSamplingRate(ispcEquivalent, - getParam1f("samplingRate", 1.25f)); + getParam1f("samplingRate", 0.125f)); vec3f specular = getParam3f("specular", vec3f(0.3f)); ispc::Volume_setSpecular(ispcEquivalent, (const ispc::vec3f &)specular); diff --git a/scripts/release/linux.sh b/scripts/release/linux.sh index 63d2ebddbc..0624de2acc 100755 --- a/scripts/release/linux.sh +++ b/scripts/release/linux.sh @@ -53,7 +53,7 @@ ROOT_DIR=$PWD DEP_DIR=$ROOT_DIR/deps DEP_LOCATION=http://sdvis.org/ospray/download/dependencies/linux -DEP_EMBREE=embree-2.13.0.x86_64.linux +DEP_EMBREE=embree-2.14.0.x86_64.linux DEP_ISPC=ispc-v1.9.1-linux DEP_TBB=tbb2017_20161128oss DEP_TARBALLS="$DEP_EMBREE.tar.gz $DEP_ISPC.tar.gz ${DEP_TBB}_lin.tgz" diff --git a/scripts/release/macosx.sh b/scripts/release/macosx.sh index 7b9073b139..fdac8f2bfa 100755 --- a/scripts/release/macosx.sh +++ b/scripts/release/macosx.sh @@ -31,7 +31,7 @@ ROOT_DIR=$PWD DEP_DIR=$ROOT_DIR/deps DEP_LOCATION=http://sdvis.org/ospray/download/dependencies/osx -DEP_EMBREE=embree-2.13.0.x86_64.macosx +DEP_EMBREE=embree-2.14.0.x86_64.macosx DEP_ISPC=ispc-v1.9.1-osx DEP_TBB=tbb2017_20161128oss DEP_TARBALLS="$DEP_EMBREE.tar.gz $DEP_ISPC.tar.gz ${DEP_TBB}_osx.tgz"