diff --git a/.gitignore b/.gitignore index dc3632bf3c..73e7930bfb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ *# bin *.user* -build* +/build* install* *.sw? tags diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f4a23bfe77..41812e4781 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -106,12 +106,20 @@ variables: - $env:Path += ";$CI_PROJECT_DIR\build\install\ospray\bin" - scripts\tests\run_tests.ps1 "$CI_PROJECT_DIR" AVX512SKX -.job_template: &benchmark_job +.job_template: &benchmark_manual_job stage: benchmark when: manual script: - scripts/tests/run-benchmarks.sh +.job_template: &benchmark_scheduled_job + stage: benchmark + only: + variables: + - $RUN_SCHEDULE_BENCHMARKS + script: + - scripts/tests/run-benchmarks.sh + ### BUILD JOBS ### build-arch-gcc: @@ -449,20 +457,20 @@ test-windows-debug-all: test-windows-msvc16-avx2: <<: *test_job_windows_avx2 - tags: [win, msvc16, avx2] + tags: [win, msvc16, avx2, mpi] needs: [build-windows-msvc16-mpi_and_md] allow_failure: true script: - $env:Path += ";$CI_PROJECT_DIR\build\install\ospray\bin" - - scripts\tests\run_tests.ps1 "$CI_PROJECT_DIR" AVX2 TEST_MULTIDEVICE + - scripts\tests\run_tests.ps1 "$CI_PROJECT_DIR" AVX2 TEST_MULTIDEVICE TEST_MPI test-windows-msvc16-avx512skx: <<: *test_job_windows_avx512skx - tags: [win, msvc16, avx512vl] + tags: [win, msvc16, avx512vl, mpi] needs: [build-windows-msvc16-mpi_and_md] script: - $env:Path += ";$CI_PROJECT_DIR\build\install\ospray\bin" - - scripts\tests\run_tests.ps1 "$CI_PROJECT_DIR" AVX512SKX TEST_MULTIDEVICE + - scripts\tests\run_tests.ps1 "$CI_PROJECT_DIR" AVX512SKX TEST_MULTIDEVICE TEST_MPI generate-ci-baseline-avx2: <<: *test_job_unix_avx2 @@ -488,13 +496,50 @@ generate-ci-baseline-avx512skx: expire_in: 3 day when: manual -### Benchmarks ### +### Benchmarks (Manual Runs) ### benchmark-x8280-1: - <<: *benchmark_job + <<: *benchmark_manual_job tags: [vis-perf-x8280-1] needs: [build-centos8] +benchmark-a-1: + <<: *benchmark_manual_job + tags: [vis-perf-a-1] + needs: [build-centos8] + +benchmark-adl-1: + <<: *benchmark_manual_job + tags: [vis-sdp-adl-1-perf] + needs: [build-centos8] + +benchmark-tgl-1: + <<: *benchmark_manual_job + tags: [vis-sdp-dg2-01-perf] + needs: [build-centos8] + +### Benchmarks (Scheduled Runs) ### + +benchmark-x8280-1-schedule: + <<: *benchmark_scheduled_job + tags: [vis-perf-x8280-1] + needs: [build-centos8] + +benchmark-a-1-schedule: + <<: *benchmark_scheduled_job + tags: [vis-perf-a-1] + needs: [build-centos8] + +benchmark-adl-1-schedule: + <<: *benchmark_scheduled_job + tags: [vis-sdp-adl-1-perf] + needs: [build-centos8] + +benchmark-tgl-1-schedule: + <<: *benchmark_scheduled_job + tags: [vis-sdp-dg2-01-perf] + needs: [build-centos8] + ### Documentation ### .job_template: &doc-defaults diff --git a/CHANGELOG.md b/CHANGELOG.md index f2203ad5e4..28971d10e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,26 +1,37 @@ Version History --------------- +### Changes in v2.8.0: + +- Lights can be now part of `OSPGroup` and thus instanced like + geometries and volumes and thus lights also support motion blur + (with the path tracer) +- Add cylinder light (with solid area sampling) +- Add support for rolling shutter of cameras +- Add support for quaternion motion blur for instance and camera to + allow for smoothly interpolated rotations +- Fix illumination from emissive quad meshes + ### Changes in v2.7.1: - Use Open VKL v1.0.1 to fix sporadic slowdowns when rendering structured regular and VDB volumes with the SciVis renderer - Fix CMake variables and logic -- Fix crash when transferfunction.opacity = 0 +- Fix crash when `transferfunction.opacity = 0` - Fix bug in MPI data-parallel rendering that caused rendering to hang - Workaround dynamic linking issue on Windows in MPI distributed rendering -- Correctly initialize renderFrame progress +- Correctly initialize `renderFrame` progress - Improved performance of data-parallel rendering for scenes with a large number of regions - Expanded camera model support of the data-parallel renderer, data-parallel rendering can now use all the camera models supported - by the scivis renderer + by the SciVis renderer - Clarify documentation and error messages ### Changes in v2.7.0: -- Add support for transformation and camera Motion Blur (with the path +- Add support for transformation and camera motion blur (with the path tracer) via `shutter` parameter of the camera and `motion.transform` array and `time` parameter of the instance and camera - OSPRay can now be built for ARM64 CPUs with NEON (e.g., Apple M1) diff --git a/README.md b/README.md index 06d06b412f..4aac50e5ed 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ OSPRay ====== -This is release v2.7.1 of Intel® OSPRay. For changes and new features +This is release v2.8.0 of Intel® OSPRay. For changes and new features see the [changelog](CHANGELOG.md). Visit http://www.ospray.org for more information. @@ -27,7 +27,7 @@ Embree](https://www.embree.org/) and [Intel ISPC (Implicit SPMD Program Compiler)](https://ispc.github.io/), and fully exploits modern instruction sets like Intel SSE4, AVX, AVX2, AVX-512 and NEON to achieve high rendering performance, thus a CPU with support for at least SSE4.1 -is required to run OSPRay on x86\_64 architectures. A CPU with support +is required to run OSPRay on x86_64 architectures. A CPU with support for NEON is required to run OSPRay on ARM64 architectures. OSPRay Support and Contact @@ -180,29 +180,29 @@ subdirectory per dependency. CMake options to note (all have sensible defaults): -CMAKE\_INSTALL\_PREFIX +CMAKE_INSTALL_PREFIX will be the root directory where everything gets installed. -BUILD\_JOBS +BUILD_JOBS sets the number given to `make -j` for parallel builds. -INSTALL\_IN\_SEPARATE\_DIRECTORIES +INSTALL_IN_SEPARATE_DIRECTORIES toggles installation of all libraries in separate or the same directory. -BUILD\_EMBREE\_FROM\_SOURCE +BUILD_EMBREE_FROM_SOURCE set to OFF will download a pre-built version of Embree. -BUILD\_OIDN\_FROM\_SOURCE +BUILD_OIDN_FROM_SOURCE set to OFF will download a pre-built version of Open Image Denoise. -OIDN\_VERSION +OIDN_VERSION determines which version of Open Image Denoise to pull down. -BUILD\_OSPRAY\_MODULE\_MPI +BUILD_OSPRAY_MODULE_MPI set to ON to build OSPRay’s MPI module for data-replicated and distributed parallel rendering on multiple nodes. -BUILD\_TBB\_FROM\_SOURCE +BUILD_TBB_FROM_SOURCE set to ON to build TBB from source (required for ARM support). The default setting is OFF. @@ -539,17 +539,17 @@ variables for easy changes to OSPRay’s behavior without needing to change the application (variables are prefixed by convention with “`OSPRAY_`”): -| Variable | Description | -|:------------------------|:-----------------------------------------------------------------------------------------------------------| -| OSPRAY\_NUM\_THREADS | equivalent to `--osp:num-threads` | -| OSPRAY\_LOG\_LEVEL | equivalent to `--osp:log-level` | -| OSPRAY\_LOG\_OUTPUT | equivalent to `--osp:log-output` | -| OSPRAY\_ERROR\_OUTPUT | equivalent to `--osp:error-output` | -| OSPRAY\_DEBUG | equivalent to `--osp:debug` | -| OSPRAY\_WARN\_AS\_ERROR | equivalent to `--osp:warn-as-error` | -| OSPRAY\_SET\_AFFINITY | equivalent to `--osp:set-affinity` | -| OSPRAY\_LOAD\_MODULES | equivalent to `--osp:load-modules`, can be a comma separated list of modules which will be loaded in order | -| OSPRAY\_DEVICE | equivalent to `--osp:device:` | +| Variable | Description | +|:---------------------|:-----------------------------------------------------------------------------------------------------------| +| OSPRAY_NUM_THREADS | equivalent to `--osp:num-threads` | +| OSPRAY_LOG_LEVEL | equivalent to `--osp:log-level` | +| OSPRAY_LOG_OUTPUT | equivalent to `--osp:log-output` | +| OSPRAY_ERROR_OUTPUT | equivalent to `--osp:error-output` | +| OSPRAY_DEBUG | equivalent to `--osp:debug` | +| OSPRAY_WARN_AS_ERROR | equivalent to `--osp:warn-as-error` | +| OSPRAY_SET_AFFINITY | equivalent to `--osp:set-affinity` | +| OSPRAY_LOAD_MODULES | equivalent to `--osp:load-modules`, can be a comma separated list of modules which will be loaded in order | +| OSPRAY_DEVICE | equivalent to `--osp:device:` | Environment variables interpreted by OSPRay. @@ -560,15 +560,15 @@ specified through `ospInit` or manually set device parameters. The following errors are currently used by OSPRay: -| Name | Description | -|:------------------------|:------------------------------------------------------------------------------| -| OSP\_NO\_ERROR | no error occurred | -| OSP\_UNKNOWN\_ERROR | an unknown error occurred | -| OSP\_INVALID\_ARGUMENT | an invalid argument was specified | -| OSP\_INVALID\_OPERATION | the operation is not allowed for the specified object | -| OSP\_OUT\_OF\_MEMORY | there is not enough memory to execute the command | -| OSP\_UNSUPPORTED\_CPU | the CPU is not supported (minimum ISA is SSE4.1 on x86\_64 and NEON on ARM64) | -| OSP\_VERSION\_MISMATCH | a module could not be loaded due to mismatching version | +| Name | Description | +|:----------------------|:-----------------------------------------------------------------------------| +| OSP_NO_ERROR | no error occurred | +| OSP_UNKNOWN_ERROR | an unknown error occurred | +| OSP_INVALID_ARGUMENT | an invalid argument was specified | +| OSP_INVALID_OPERATION | the operation is not allowed for the specified object | +| OSP_OUT_OF_MEMORY | there is not enough memory to execute the command | +| OSP_UNSUPPORTED_CPU | the CPU is not supported (minimum ISA is SSE4.1 on x86_64 and NEON on ARM64) | +| OSP_VERSION_MISMATCH | a module could not be loaded due to mismatching version | Possible error codes, i.e., valid named constants of type `OSPError`. @@ -787,39 +787,40 @@ The enum type `OSPDataType` describes the different element types that can be represented in OSPRay; valid constants are listed in the table below. -| Type/Name | Description | -|:-------------------------------|:---------------------------------------------------------------------------------------------| -| OSP\_DEVICE | API device object reference | -| OSP\_DATA | data reference | -| OSP\_OBJECT | generic object reference | -| OSP\_CAMERA | camera object reference | -| OSP\_FRAMEBUFFER | framebuffer object reference | -| OSP\_LIGHT | light object reference | -| OSP\_MATERIAL | material object reference | -| OSP\_TEXTURE | texture object reference | -| OSP\_RENDERER | renderer object reference | -| OSP\_WORLD | world object reference | -| OSP\_GEOMETRY | geometry object reference | -| OSP\_VOLUME | volume object reference | -| OSP\_TRANSFER\_FUNCTION | transfer function object reference | -| OSP\_IMAGE\_OPERATION | image operation object reference | -| OSP\_STRING | C-style zero-terminated character string | -| OSP\_CHAR, OSP\_VEC\[234\]C | 8 bit signed character scalar and \[234\]-element vector | -| OSP\_UCHAR, OSP\_VEC\[234\]UC | 8 bit unsigned character scalar and \[234\]-element vector | -| OSP\_SHORT, OSP\_VEC\[234\]S | 16 bit unsigned integer scalar and \[234\]-element vector | -| OSP\_USHORT, OSP\_VEC\[234\]US | 16 bit unsigned integer scalar and \[234\]-element vector | -| OSP\_INT, OSP\_VEC\[234\]I | 32 bit signed integer scalar and \[234\]-element vector | -| OSP\_UINT, OSP\_VEC\[234\]UI | 32 bit unsigned integer scalar and \[234\]-element vector | -| OSP\_LONG, OSP\_VEC\[234\]L | 64 bit signed integer scalar and \[234\]-element vector | -| OSP\_ULONG, OSP\_VEC\[234\]UL | 64 bit unsigned integer scalar and \[234\]-element vector | -| OSP\_HALF, OSP\_VEC\[234\]H | 16 bit half precision floating-point scalar and \[234\]-element vector (IEEE 754 `binary16`) | -| OSP\_FLOAT, OSP\_VEC\[234\]F | 32 bit single precision floating-point scalar and \[234\]-element vector | -| OSP\_DOUBLE, OSP\_VEC\[234\]D | 64 bit double precision floating-point scalar and \[234\]-element vector | -| OSP\_BOX\[1234\]I | 32 bit integer box (lower + upper bounds) | -| OSP\_BOX\[1234\]F | 32 bit single precision floating-point box (lower + upper bounds) | -| OSP\_LINEAR\[23\]F | 32 bit single precision floating-point linear transform (\[23\] vectors) | -| OSP\_AFFINE\[23\]F | 32 bit single precision floating-point affine transform (linear transform plus translation) | -| OSP\_VOID\_PTR | raw memory address (only found in module extensions) | +| Type/Name | Description | +|:-----------------------------|:---------------------------------------------------------------------------------------------| +| OSP_DEVICE | API device object reference | +| OSP_DATA | data reference | +| OSP_OBJECT | generic object reference | +| OSP_CAMERA | camera object reference | +| OSP_FRAMEBUFFER | framebuffer object reference | +| OSP_LIGHT | light object reference | +| OSP_MATERIAL | material object reference | +| OSP_TEXTURE | texture object reference | +| OSP_RENDERER | renderer object reference | +| OSP_WORLD | world object reference | +| OSP_GEOMETRY | geometry object reference | +| OSP_VOLUME | volume object reference | +| OSP_TRANSFER_FUNCTION | transfer function object reference | +| OSP_IMAGE_OPERATION | image operation object reference | +| OSP_STRING | C-style zero-terminated character string | +| OSP_CHAR, OSP_VEC\[234\]C | 8 bit signed character scalar and \[234\]-element vector | +| OSP_UCHAR, OSP_VEC\[234\]UC | 8 bit unsigned character scalar and \[234\]-element vector | +| OSP_SHORT, OSP_VEC\[234\]S | 16 bit unsigned integer scalar and \[234\]-element vector | +| OSP_USHORT, OSP_VEC\[234\]US | 16 bit unsigned integer scalar and \[234\]-element vector | +| OSP_INT, OSP_VEC\[234\]I | 32 bit signed integer scalar and \[234\]-element vector | +| OSP_UINT, OSP_VEC\[234\]UI | 32 bit unsigned integer scalar and \[234\]-element vector | +| OSP_LONG, OSP_VEC\[234\]L | 64 bit signed integer scalar and \[234\]-element vector | +| OSP_ULONG, OSP_VEC\[234\]UL | 64 bit unsigned integer scalar and \[234\]-element vector | +| OSP_HALF, OSP_VEC\[234\]H | 16 bit half precision floating-point scalar and \[234\]-element vector (IEEE 754 `binary16`) | +| OSP_FLOAT, OSP_VEC\[234\]F | 32 bit single precision floating-point scalar and \[234\]-element vector | +| OSP_DOUBLE, OSP_VEC\[234\]D | 64 bit double precision floating-point scalar and \[234\]-element vector | +| OSP_BOX\[1234\]I | 32 bit integer box (lower + upper bounds) | +| OSP_BOX\[1234\]F | 32 bit single precision floating-point box (lower + upper bounds) | +| OSP_LINEAR\[23\]F | 32 bit single precision floating-point linear transform (\[23\] vectors) | +| OSP_AFFINE\[23\]F | 32 bit single precision floating-point affine transform (linear transform plus translation) | +| OSP_QUATF | 32 bit single precision floating-point quaternion, in (*i*,*j*,*k*,*w*) layout | +| OSP_VOID_PTR | raw memory address (only found in module extensions) | Valid named constants for `OSPDataType`. @@ -907,8 +908,8 @@ table below. | Type | Name | Default | Description | |:--------|:---------------|------------------------------:|:-----------------------------------------------------------------------------------------------------------------------| -| vec3f | gridOrigin | (0, 0, 0) | origin of the grid in object-space | -| vec3f | gridSpacing | (1, 1, 1) | size of the grid cells in object-space | +| vec3f | gridOrigin | (0,0,0) | origin of the grid in object-space | +| vec3f | gridSpacing | (1,1,1) | size of the grid cells in object-space | | OSPData | data | | the actual voxel 3D [data](#data) | | int | filter | `OSP_VOLUME_FILTER_TRILINEAR` | filter used for reconstructing the field, also allowed is `OSP_VOLUME_FILTER_NEAREST` and `OSP_VOLUME_FILTER_TRICUBIC` | | int | gradientFilter | same as `filter` | filter used during gradient computations | @@ -939,8 +940,8 @@ below. | Type | Name | Default | Description | |:--------|:---------------|------------------------------:|:--------------------------------------------------------------------------------------| -| vec3f | gridOrigin | (0, 0, 0) | origin of the grid in units of (*r*, *θ*, *ϕ*); angles in degrees | -| vec3f | gridSpacing | (1, 1, 1) | size of the grid cells in units of (*r*, *θ*, *ϕ*); angles in degrees | +| vec3f | gridOrigin | (0,0,0) | origin of the grid in units of (*r*,*θ*,*ϕ*); angles in degrees | +| vec3f | gridSpacing | (1,1,1) | size of the grid cells in units of (*r*,*θ*,*ϕ*); angles in degrees | | OSPData | data | | the actual voxel 3D [data](#data) | | int | filter | `OSP_VOLUME_FILTER_TRILINEAR` | filter used for reconstructing the field, also allowed is `OSP_VOLUME_FILTER_NEAREST` | | int | gradientFilter | same as `filter` | filter used during gradient computations | @@ -948,8 +949,8 @@ below. Configuration parameters for structured spherical volumes. -The dimensions (*r*, *θ*, *ϕ*) of the volume are inferred from the size -of the 3D array `data`, as is the type of the voxel values (currently +The dimensions (*r*,*θ*,*ϕ*) of the volume are inferred from the size of +the 3D array `data`, as is the type of the voxel values (currently supported are: `OSP_UCHAR`, `OSP_SHORT`, `OSP_USHORT`, `OSP_HALF`, `OSP_FLOAT`, and `OSP_DOUBLE`). @@ -993,8 +994,8 @@ Note that cell widths are defined *per refinement level*, not per block. | box3i\[\] | block.bounds | NULL | [data](#data) array of grid sizes (in voxels) for each AMR block | | int\[\] | block.level | NULL | array of each block’s refinement level | | OSPData\[\] | block.data | NULL | [data](#data) array of OSPData containing the actual scalar voxel data, only `OSP_FLOAT` is supported as `OSPDataType` | -| 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 | +| vec3f | gridOrigin | (0,0,0) | origin of the grid | +| vec3f | gridSpacing | (1,1,1) | size of the grid cells | | float | background | `NaN` | value that is used when sampling an undefined region outside the volume domain | Configuration parameters for AMR volumes. @@ -1008,15 +1009,15 @@ cover Berger-Colella \[1\] and Chombo \[2\] AMR data. The `method` parameter above determines the interpolation method used when sampling the volume. -OSP\_AMR\_CURRENT +OSP_AMR_CURRENT finds the finest refinement level at that cell and interpolates through this “current” level -OSP\_AMR\_FINEST +OSP_AMR_FINEST will interpolate at the closest existing cell in the volume-wide finest refinement level regardless of the sample cell’s level -OSP\_AMR\_OCTANT +OSP_AMR_OCTANT interpolates through all available refinement levels at that cell. This method avoids discontinuities at refinement level boundaries at the cost of performance @@ -1341,25 +1342,25 @@ A geometry consisting of multiple curves is created by calling `ospNewGeometry` with type string “`curve`”. The parameters defining this geometry are listed in the table below. -| Type | Name | Description | -|:-----------|:------------------------|:---------------------------------------------------------------------------------| -| vec4f\[\] | vertex.position\_radius | [data](#data) array of vertex position and per-vertex radius | -| vec2f\[\] | vertex.texcoord | [data](#data) array of per-vertex texture coordinates | -| vec4f\[\] | vertex.color | [data](#data) array of corresponding vertex colors (linear RGBA) | -| vec3f\[\] | vertex.normal | [data](#data) array of curve normals (only for “ribbon” curves) | -| vec4f\[\] | vertex.tangent | [data](#data) array of curve tangents (only for “hermite” curves) | -| uint32\[\] | index | [data](#data) array of indices to the first vertex or tangent of a curve segment | -| uchar | type | `OSPCurveType` for rendering the curve. Supported types are: | -| | | `OSP_FLAT` | -| | | `OSP_ROUND` | -| | | `OSP_RIBBON` | -| | | `OSP_DISJOINT` | -| uchar | basis | `OSPCurveBasis` for defining the curve. Supported bases are: | -| | | `OSP_LINEAR` | -| | | `OSP_BEZIER` | -| | | `OSP_BSPLINE` | -| | | `OSP_HERMITE` | -| | | `OSP_CATMULL_ROM` | +| Type | Name | Description | +|:-----------|:-----------------------|:---------------------------------------------------------------------------------| +| vec4f\[\] | vertex.position_radius | [data](#data) array of vertex position and per-vertex radius | +| vec2f\[\] | vertex.texcoord | [data](#data) array of per-vertex texture coordinates | +| vec4f\[\] | vertex.color | [data](#data) array of corresponding vertex colors (linear RGBA) | +| vec3f\[\] | vertex.normal | [data](#data) array of curve normals (only for “ribbon” curves) | +| vec4f\[\] | vertex.tangent | [data](#data) array of curve tangents (only for “hermite” curves) | +| uint32\[\] | index | [data](#data) array of indices to the first vertex or tangent of a curve segment | +| uchar | type | `OSPCurveType` for rendering the curve. Supported types are: | +| | | `OSP_FLAT` | +| | | `OSP_ROUND` | +| | | `OSP_RIBBON` | +| | | `OSP_DISJOINT` | +| uchar | basis | `OSPCurveBasis` for defining the curve. Supported bases are: | +| | | `OSP_LINEAR` | +| | | `OSP_BEZIER` | +| | | `OSP_BSPLINE` | +| | | `OSP_HERMITE` | +| | | `OSP_CATMULL_ROM` | Parameters defining a curves geometry. @@ -1370,30 +1371,30 @@ internally for the relevant type/basis mapping. The following section describes the properties of different curve basis’ and how they use the data provided in data buffers: -OSP\_LINEAR +OSP_LINEAR The indices point to the first of 2 consecutive control points in the vertex buffer. The first control point is the start and the second control point the end of the line segment. The curve goes through all control points listed in the vertex buffer. -OSP\_BEZIER +OSP_BEZIER The indices point to the first of 4 consecutive control points in the vertex buffer. The first control point represents the start point of the curve, and the 4th control point the end point of the curve. The Bézier basis is interpolating, thus the curve does go exactly through the first and fourth control vertex. -OSP\_BSPLINE +OSP_BSPLINE The indices point to the first of 4 consecutive control points in the vertex buffer. This basis is not interpolating, thus the curve does in general not go through any of the control points directly. Using this basis, 3 control points can be shared for two continuous neighboring -curve segments, e.g., the curves (*p*0, *p*1, *p*2, *p*3) and -(*p*1, *p*2, *p*3, *p*4) are C1 continuous. This feature make this basis -a good choice to construct continuous multi-segment curves, as memory +curve segments, e.g., the curves (*p*0,*p*1,*p*2,*p*3) and +(*p*1,*p*2,*p*3,*p*4) are C1 continuous. This feature make this basis a +good choice to construct continuous multi-segment curves, as memory consumption can be kept minimal. -OSP\_HERMITE +OSP_HERMITE It is necessary to have both vertex buffer and tangent buffer for using this basis. The indices point to the first of 2 consecutive points in the vertex buffer, and the first of 2 consecutive tangents in the @@ -1403,32 +1404,32 @@ derivative at the begin and end matches exactly the value specified in the tangent buffer. When connecting two segments continuously, the end point and tangent of the previous segment can be shared. -OSP\_CATMULL\_ROM +OSP_CATMULL_ROM The indices point to the first of 4 consecutive control points in the -vertex buffer. If (*p*0, *p*1, *p*2, *p*3) represent the points then -this basis goes through *p*1 and *p*2, with tangents as (*p*2 − *p*0)/2 -and (*p*3 − *p*1)/2. +vertex buffer. If (*p*0,*p*1,*p*2,*p*3) represent the points then this +basis goes through *p*1 and *p*2, with tangents as (*p*2−*p*0)/2 and +(*p*3−*p*1)/2. The following section describes the properties of different curve types’ and how they define the geometry of a curve: -OSP\_FLAT +OSP_FLAT This type enables faster rendering as the curve is rendered as a connected sequence of ray facing quads. -OSP\_ROUND +OSP_ROUND This type enables rendering a real geometric surface for the curve which allows closeup views. This mode renders a sweep surface by sweeping a varying radius circle tangential along the curve. -OSP\_RIBBON +OSP_RIBBON The type enables normal orientation of the curve and requires a normal buffer be specified along with vertex buffer. The curve is rendered as a flat band whose center approximately follows the provided vertex buffer and whose normal orientation approximately follows the provided normal buffer. Not supported for basis `OSP_LINEAR`. -OSP\_DISJOINT +OSP_DISJOINT Only supported for basis `OSP_LINEAR`; the segments are open and not connected at the joints, i.e., the curve segments are either individual cones or cylinders. @@ -1453,10 +1454,10 @@ planes are infinite but their extents can be limited by defining optional bounding boxes. A planes geometry can be created by calling `ospNewGeometry` with type string “`plane`”. -| Type | Name | Description | -|:----------|:-------------------|:---------------------------------------------------------------| -| vec4f\[\] | plane.coefficients | [data](#data) array of plane coefficients (*a*, *b*, *c*, *d*) | -| box3f\[\] | plane.bounds | optional [data](#data) array of bounding boxes | +| Type | Name | Description | +|:----------|:-------------------|:------------------------------------------------------------| +| vec4f\[\] | plane.coefficients | [data](#data) array of plane coefficients (*a*,*b*,*c*,*d*) | +| box3f\[\] | plane.bounds | optional [data](#data) array of bounding boxes | Parameters defining a planes geometry. @@ -1549,13 +1550,13 @@ represented by a light’s `intensity` parameter is set using differ between the different light sources (see documentation of each specific light source). -| Name | Description | -|:-------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------| -| OSP\_INTENSITY\_QUANTITY\_POWER | the overall amount of light energy emitted by the light source into the scene, unit is W | -| OSP\_INTENSITY\_QUANTITY\_INTENSITY | the overall amount of light emitted by the light in a given direction, unit is W/sr | -| OSP\_INTENSITY\_QUANTITY\_RADIANCE | the amount of light emitted by a point on the light source in a given direction, unit is W/sr/m2 | -| OSP\_INTENSITY\_QUANTITY\_IRRADIANCE | the amount of light arriving at a surface point, assuming the light is oriented towards to the surface, unit is W/m2 | -| OSP\_INTENSITY\_QUANTITY\_SCALE | a linear scaling factor for light sources with a built-in quantity (e.g., `HDRI`, or `sunSky`). | +| Name | Description | +|:----------------------------------|:--------------------------------------------------------------------------------------------------------------------------------| +| OSP_INTENSITY_QUANTITY_POWER | the overall amount of light energy emitted by the light source into the scene, unit is W | +| OSP_INTENSITY_QUANTITY_INTENSITY | the overall amount of light emitted by the light in a given direction, unit is W/sr | +| OSP_INTENSITY_QUANTITY_RADIANCE | the amount of light emitted by a point on the light source in a given direction, unit is W/sr/m2 | +| OSP_INTENSITY_QUANTITY_IRRADIANCE | the amount of light arriving at a surface point, assuming the light is oriented towards to the surface, unit is W/m2 | +| OSP_INTENSITY_QUANTITY_SCALE | a linear scaling factor for light sources with a built-in quantity (e.g., `HDRI`, or `sunSky`). | Types of radiometric quantities used to interpret a light’s `intensity` parameter. @@ -1574,10 +1575,10 @@ parameter value. In addition to the [general parameters](#lights) understood by all lights the distant light supports the following special parameters: -| Type | Name | Description | -|:------|:----------------|:---------------------------------------------| -| vec3f | direction | main emission direction of the distant light | -| float | angularDiameter | apparent size (angle in degree) of the light | +| Type | Name | Default | Description | +|:------|:----------------|--------:|:---------------------------------------------| +| vec3f | direction | (0,0,1) | main emission direction of the distant light | +| float | angularDiameter | 0 | apparent size (angle in degree) of the light | Special parameters accepted by the distant light. @@ -1598,10 +1599,10 @@ supports `OSP_INTENSITY_QUANTITY_POWER`, value. In addition to the [general parameters](#lights) understood by all lights the sphere light supports the following special parameters: -| Type | Name | Description | -|:------|:---------|:-----------------------------------------------| -| vec3f | position | the center of the sphere light, in world-space | -| float | radius | the size of the sphere light | +| Type | Name | Default | Description | +|:------|:---------|--------:|:-------------------------------| +| vec3f | position | (0,0,0) | the center of the sphere light | +| float | radius | 0 | the size of the sphere light | Special parameters accepted by the sphere light. @@ -1620,16 +1621,16 @@ value. In addition to the [general parameters](#lights) understood by all lights the spotlight supports the special parameters listed in the table. -| Type | Name | Default | Description | -|:----------|:----------------------|----------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| vec3f | position | (0, 0, 0) | the center of the spotlight, in world-space | -| vec3f | direction | (0, 0, 1) | main emission direction of the spot | -| float | openingAngle | 180 | full opening angle (in degree) of the spot; outside of this cone is no illumination | -| float | penumbraAngle | 5 | size (angle in degree) of the “penumbra”, the region between the rim (of the illumination cone) and full intensity of the spot; should be smaller than half of `openingAngle` | -| float | radius | 0 | the size of the spotlight, the radius of a disk with normal `direction` | -| float | innerRadius | 0 | in combination with `radius` turns the disk into a ring | -| float\[\] | intensityDistribution | | luminous intensity distribution for photometric lights; can be 2D for asymmetric illumination; values are assumed to be uniformly distributed | -| vec3f | c0 | | orientation, i.e., direction of the C0-(half)plane (only needed if illumination via `intensityDistribution` is asymmetric) | +| Type | Name | Default | Description | +|:----------|:----------------------|--------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| vec3f | position | (0,0,0) | the center of the spotlight | +| vec3f | direction | (0,0,1) | main emission direction of the spot | +| float | openingAngle | 180 | full opening angle (in degree) of the spot; outside of this cone is no illumination | +| float | penumbraAngle | 5 | size (angle in degree) of the “penumbra”, the region between the rim (of the illumination cone) and full intensity of the spot; should be smaller than half of `openingAngle` | +| float | radius | 0 | the size of the spotlight, the radius of a disk with normal `direction` | +| float | innerRadius | 0 | in combination with `radius` turns the disk into a ring | +| float\[\] | intensityDistribution | | luminous intensity distribution for photometric lights; can be 2D for asymmetric illumination; values are assumed to be uniformly distributed | +| vec3f | c0 | | orientation, i.e., direction of the C0-(half)plane (only needed if illumination via `intensityDistribution` is asymmetric) | Special parameters accepted by the spotlight. @@ -1669,11 +1670,11 @@ type string “`quad`” to `ospNewLight`. The quad light supports parameter. In addition to the [general parameters](#lights) understood by all lights the quad light supports the following special parameters: -| Type | Name | Description | -|:------|:---------|:-----------------------------------------------------| -| vec3f | position | world-space position of one vertex of the quad light | -| vec3f | edge1 | vector to one adjacent vertex | -| vec3f | edge2 | vector to the other adjacent vertex | +| Type | Name | Default | Description | +|:------|:---------|--------:|:-----------------------------------------| +| vec3f | position | (0,0,0) | position of one vertex of the quad light | +| vec3f | edge1 | (1,0,0) | vector to one adjacent vertex | +| vec3f | edge2 | (0,1,0) | vector to the other adjacent vertex | Special parameters accepted by the quad light. @@ -1686,6 +1687,30 @@ tracer) will compute soft shadows from the quad light. Other renderers will just sample the center of the quad light, which results in hard shadows. +### Cylinder Light + +The cylinder light is a cylinderical, procedural area light source +emitting uniformly outwardly into the space beyond the boundary. It is +created by passing the type string “`cylinder`” to `ospNewLight`. The +cylinder light supports `OSP_INTENSITY_QUANTITY_POWER`, +`OSP_INTENSITY_QUANTITY_INTENSITY` and `OSP_INTENSITY_QUANTITY_RADIANCE` +(default) as `intensityQuantity` parameter. In addition to the [general +parameters](#lights) understood by all lights the cylinder light +supports the following special parameters: + +| Type | Name | Default | Description | +|:------|:----------|--------:|:--------------------------------------| +| vec3f | position0 | (0,0,0) | position of the start of the cylinder | +| vec3f | position1 | (0,0,1) | position of the end of the cylinder | +| float | radius | 1 | radius of the cylinder | + +Special parameters accepted by the cylinder light. + +Note that only renderers that use stochastic sampling (like the path +tracer) will compute soft shadows from the cylinder light. Other +renderers will just sample the closest point on the cylinder light, +which results in hard shadows. + ### HDRI Light The HDRI light is a textured light source surrounding the scene and @@ -1696,11 +1721,11 @@ as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) the HDRI light supports the following special parameters: -| Type | Name | Description | -|:-----------|:----------|:-----------------------------------------------------------------------------------------------------------------| -| vec3f | up | up direction of the light in world-space | -| vec3f | direction | direction to which the center of the texture will be mapped to (analog to [panoramic camera](#panoramic-camera)) | -| OSPTexture | map | environment map in latitude / longitude format | +| Type | Name | Default | Description | +|:-----------|:----------|--------:|:-----------------------------------------------------------------------------------------------------------------| +| vec3f | up | (0,1,0) | up direction of the light | +| vec3f | direction | (0,0,1) | direction to which the center of the texture will be mapped to (analog to [panoramic camera](#panoramic-camera)) | +| OSPTexture | map | | environment map in latitude / longitude format | Special parameters accepted by the HDRI light. @@ -1739,13 +1764,13 @@ default value for the `intensity` parameter is set to `0.025`. In addition to the [general parameters](#lights) the following special parameters are supported: -| Type | Name | Default | Description | -|:------|:-----------------|-------------:|:-----------------------------------------------------------------------------------------------------| -| vec3f | up | (0, 1, 0) | zenith of sky in world-space | -| vec3f | direction | (0,  − 1, 0) | main emission direction of the sun | -| float | turbidity | 3 | atmospheric turbidity due to particles, in \[1–10\] | -| float | albedo | 0.3 | ground reflectance, in \[0–1\] | -| float | horizonExtension | 0.01 | extend the sky dome by stretching the horizon, fraction of the lower hemisphere to cover, in \[0–1\] | +| Type | Name | Default | Description | +|:------|:-----------------|---------:|:-----------------------------------------------------------------------------------------------------| +| vec3f | up | (0,1,0) | zenith of sky | +| vec3f | direction | (0,−1,0) | main emission direction of the sun | +| float | turbidity | 3 | atmospheric turbidity due to particles, in \[1–10\] | +| float | albedo | 0.3 | ground reflectance, in \[0–1\] | +| float | horizonExtension | 0.01 | extend the sky dome by stretching the horizon, fraction of the lower hemisphere to cover, in \[0–1\] | Special parameters accepted by the `sunSky` light. @@ -1766,18 +1791,18 @@ Scene Hierarchy ### Groups -Groups in OSPRay represent collections of GeometricModels and -VolumetricModels which share a common local-space coordinate system. To -create a group call +Groups in OSPRay represent collections of GeometricModels, +VolumetricModels and Lights which share a common local-space coordinate +system. To create a group call ``` cpp OSPGroup ospNewGroup(); ``` -Groups take arrays of geometric models, volumetric models and clipping -geometric models, but they are optional. In other words, there is no -need to create empty arrays if there are no geometries or volumes in the -group. +Groups take arrays of geometric models, volumetric models, clipping +geometric models and lights, but they are all optional. In other words, +there is no need to create empty arrays if there are no geometries, +volumes or lights in the group. By adding `OSPGeometricModel`s to the `clippingGeometry` array a clipping geometry feature is enabled. Geometries assigned to this @@ -1793,22 +1818,18 @@ geometries from all groups and [Instances](#instances) will be combined together – a union of these areas will be applied to all other objects in the [world](#world). -| Type | Name | Default | Description | -|:-----------------------|:-----------------|--------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| OSPGeometricModel\[\] | geometry | NULL | [data](#data) array of [GeometricModels](#geometricmodels) | -| OSPVolumetricModel\[\] | volume | NULL | [data](#data) array of [VolumetricModels](#volumetricmodels) | -| OSPGeometricModel\[\] | clippingGeometry | NULL | [data](#data) array of [GeometricModels](#geometricmodels) used for clipping | -| bool | dynamicScene | false | use RTC\_SCENE\_DYNAMIC flag (faster BVH build, slower ray traversal), otherwise uses RTC\_SCENE\_STATIC flag (faster ray traversal, slightly slower BVH build) | -| bool | compactMode | false | tell Embree to use a more compact BVH in memory by trading ray traversal performance | -| bool | robustMode | false | tell Embree to enable more robust ray intersection code paths (slightly slower) | +| Type | Name | Default | Description | +|:-----------------------|:-----------------|--------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------| +| OSPGeometricModel\[\] | geometry | NULL | [data](#data) array of [GeometricModels](#geometricmodels) | +| OSPVolumetricModel\[\] | volume | NULL | [data](#data) array of [VolumetricModels](#volumetricmodels) | +| OSPGeometricModel\[\] | clippingGeometry | NULL | [data](#data) array of [GeometricModels](#geometricmodels) used for clipping | +| OSPLight\[\] | light | NULL | [data](#data) array of [lights](#lights) | +| bool | dynamicScene | false | use RTC_SCENE_DYNAMIC flag (faster BVH build, slower ray traversal), otherwise uses RTC_SCENE_STATIC flag (faster ray traversal, slightly slower BVH build) | +| bool | compactMode | false | tell Embree to use a more compact BVH in memory by trading ray traversal performance | +| bool | robustMode | false | tell Embree to enable more robust ray intersection code paths (slightly slower) | Parameters understood by groups. -Note that groups only need to re re-committed if a geometry or volume -changes (surface/scalar field representation). Appearance information on -`OSPGeometricModel` and `OSPVolumetricModel` can be changed freely, as -internal acceleration structures do not need to be reconstructed. - ### Instances Instances in OSPRay represent a single group’s placement into the world @@ -1818,11 +1839,15 @@ via a transform. To create and instance call OSPInstance ospNewInstance(OSPGroup); ``` -| Type | Name | Default | Description | -|:-------------|:-----------------|---------:|:------------------------------------------------------------------------------------------------| -| affine3f | transform | identity | world-space transform for all attached geometries and volumes, overridden by `motion.transform` | -| affine3f\[\] | motion.transform | | uniformly distributed world-space transforms | -| box1f | time | \[0, 1\] | time associated with first and last key in `motion.` arrays (for motion blur) | +| Type | Name | Default | Description | +|:-------------|:-------------------|---------:|:------------------------------------------------------------------------------------------------------------------------------------------------------| +| affine3f | transform | identity | world-space transform for all attached geometries and volumes, overridden by `motion.*` arrays | +| affine3f\[\] | motion.transform | | uniformly distributed world-space transforms | +| vec3f\[\] | motion.scale | | uniformly distributed world-space scale, overridden by `motion.transform` | +| vec3f\[\] | motion.pivot | | uniformly distributed world-space translation which is applied before `motion.rotation` (i.e., the rotation center), overridden by `motion.transform` | +| quatf\[\] | motion.rotation | | uniformly distributed world-space quaternion rotation, overridden by `motion.transform` | +| vec3f\[\] | motion.translation | | uniformly distributed world-space translation, overridden by `motion.transform` | +| box1f | time | \[0, 1\] | time associated with first and last key in `motion.*` arrays (for motion blur) | Parameters understood by instances. @@ -1862,13 +1887,13 @@ object types will return an empty bounding box. Finally, Worlds can be configured with parameters for making various feature/performance trade-offs (similar to groups). -| Type | Name | Default | Description | -|:----------------|:-------------|--------:|:----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| OSPInstance\[\] | instance | NULL | [data](#data) array with handles of the [instances](#instances) | -| OSPLight\[\] | light | NULL | [data](#data) array with handles of the [lights](#lights) | -| bool | dynamicScene | false | use RTC\_SCENE\_DYNAMIC flag (faster BVH build, slower ray traversal), otherwise uses RTC\_SCENE\_STATIC flag (faster ray traversal, slightly slower BVH build) | -| bool | compactMode | false | tell Embree to use a more compact BVH in memory by trading ray traversal performance | -| bool | robustMode | false | tell Embree to enable more robust ray intersection code paths (slightly slower) | +| Type | Name | Default | Description | +|:----------------|:-------------|--------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------| +| OSPInstance\[\] | instance | NULL | [data](#data) array with handles of the [instances](#instances) | +| OSPLight\[\] | light | NULL | [data](#data) array with handles of the [lights](#lights) | +| bool | dynamicScene | false | use RTC_SCENE_DYNAMIC flag (faster BVH build, slower ray traversal), otherwise uses RTC_SCENE_STATIC flag (faster ray traversal, slightly slower BVH build) | +| bool | compactMode | false | tell Embree to use a more compact BVH in memory by trading ray traversal performance | +| bool | robustMode | false | tell Embree to enable more robust ray intersection code paths (slightly slower) | Parameters understood by worlds. @@ -1892,8 +1917,8 @@ General parameters of all renderers are | float | minContribution | 0.001 | sample contributions below this value will be neglected to speedup rendering | | float | varianceThreshold | 0 | threshold for adaptive accumulation | | float / vec3f / vec4f | backgroundColor | black, transparent | background color and alpha (linear A/RGB/RGBA), if no `map_backplate` is set | -| OSPTexture | map\_backplate | | optional [texture](#texture) image used as background (use texture type `texture2d`) | -| OSPTexture | map\_maxDepth | | optional screen-sized float [texture](#texture) with maximum far distance per pixel (use texture type `texture2d`) | +| OSPTexture | map_backplate | | optional [texture](#texture) image used as background (use texture type `texture2d`) | +| OSPTexture | map_maxDepth | | optional screen-sized float [texture](#texture) with maximum far distance per pixel (use texture type `texture2d`) | | OSPMaterial\[\] | material | | optional [data](#data) array of [materials](#materials) which can be indexed by a [GeometricModel](#geometricmodels)’s `material` parameter | | uchar | pixelFilter | `OSP_PIXELFILTER_GAUSS` | `OSPPixelFilterType` to select the pixel filter used by the renderer for antialiasing. Possible pixel filters are listed below. | @@ -1927,13 +1952,13 @@ the filter depends on the selected filter type. The types of supported pixel filters are defined by the `OSPPixelFilterType` enum and can be set using the `pixelFilter` parameter. -| Name | Description | -|:-----------------------------------|:---------------------------------------------------------------------------------------------------------| -| OSP\_PIXELFILTER\_POINT | a point filter only samples the center of the pixel, therefore the filter width is *w* = 0 | -| OSP\_PIXELFILTER\_BOX | a uniform box filter with a width of *w* = 1 | -| OSP\_PIXELFILTER\_GAUSS | a truncated, smooth Gaussian filter with a standard deviation of *σ* = 0.5 and a filter width of *w* = 3 | -| OSP\_PIXELFILTER\_MITCHELL | the Mitchell-Netravali filter with a width of *w* = 4 | -| OSP\_PIXELFILTER\_BLACKMAN\_HARRIS | the Blackman-Harris filter with a width of *w* = 3 | +| Name | Description | +|:--------------------------------|:---------------------------------------------------------------------------------------------------------| +| OSP_PIXELFILTER_POINT | a point filter only samples the center of the pixel, therefore the filter width is *w* = 0 | +| OSP_PIXELFILTER_BOX | a uniform box filter with a width of *w* = 1 | +| OSP_PIXELFILTER_GAUSS | a truncated, smooth Gaussian filter with a standard deviation of *σ* = 0.5 and a filter width of *w* = 3 | +| OSP_PIXELFILTER_MITCHELL | the Mitchell-Netravali filter with a width of *w* = 4 | +| OSP_PIXELFILTER_BLACKMAN_HARRIS | the Blackman-Harris filter with a width of *w* = 3 | Pixel filter types supported by OSPRay for antialiasing in image space. @@ -2036,14 +2061,14 @@ format](http://paulbourke.net/dataformats/mtl/) of Lightwave’s OBJ scene files. To create an OBJ material pass the type string “`obj`” to `ospNewMaterial`. Its main parameters are -| Type | Name | Default | Description | -|:-----------|:----------|----------:|:------------------------------------------------------------| -| vec3f | kd | white 0.8 | diffuse color (linear RGB) | -| vec3f | ks | black | specular color (linear RGB) | -| float | ns | 10 | shininess (Phong exponent), usually in \[2–104\] | -| float | d | opaque | opacity | -| vec3f | tf | black | transparency filter color (linear RGB) | -| OSPTexture | map\_bump | NULL | normal map | +| Type | Name | Default | Description | +|:-----------|:---------|----------:|:------------------------------------------------------------| +| vec3f | kd | white 0.8 | diffuse color (linear RGB) | +| vec3f | ks | black | specular color (linear RGB) | +| float | ns | 10 | shininess (Phong exponent), usually in \[2–104\] | +| float | d | opaque | opacity | +| vec3f | tf | black | transparency filter color (linear RGB) | +| OSPTexture | map_bump | NULL | normal map | Main parameters of the OBJ material. @@ -2072,16 +2097,16 @@ the opacity `d`. Normal mapping can simulate small geometric features via the texture `map_Bump`. The normals *n* in the normal map are with respect to the -local tangential shading coordinate system and are encoded as -½(*n* + 1), thus a texel (0.5, 0.5, 1)[9] represents the unperturbed -shading normal (0, 0, 1). Because of this encoding an sRGB gamma -[texture](#texture) format is ignored and normals are always fetched as -linear from a normal map. Note that the orientation of normal maps is -important for a visually consistent look: by convention OSPRay uses a -coordinate system with the origin in the lower left corner; thus a -convexity will look green toward the top of the texture image (see also -the example image of a normal map). If this is not the case flip the -normal map vertically or invert its green channel. +local tangential shading coordinate system and are encoded as ½(*n*+1), +thus a texel (0.5,0.5,1)[9] represents the unperturbed shading normal +(0,0,1). Because of this encoding an sRGB gamma [texture](#texture) +format is ignored and normals are always fetched as linear from a normal +map. Note that the orientation of normal maps is important for a +visually consistent look: by convention OSPRay uses a coordinate system +with the origin in the lower left corner; thus a convexity will look +green toward the top of the texture image (see also the example image of +a normal map). If this is not the case flip the normal map vertically or +invert its green channel.
Normal map representing an exalted square pyramidal frustum. @@ -2441,23 +2466,23 @@ Parameters of `texture2d` texture type. The supported texture formats for `texture2d` are: -| Name | Description | -|:----------------------|:---------------------------------------------------------------------------| -| OSP\_TEXTURE\_RGBA8 | 8 bit \[0–255\] linear components red, green, blue, alpha | -| OSP\_TEXTURE\_SRGBA | 8 bit sRGB gamma encoded color components, and linear alpha | -| OSP\_TEXTURE\_RGBA32F | 32 bit float components red, green, blue, alpha | -| OSP\_TEXTURE\_RGB8 | 8 bit \[0–255\] linear components red, green, blue | -| OSP\_TEXTURE\_SRGB | 8 bit sRGB gamma encoded components red, green, blue | -| OSP\_TEXTURE\_RGB32F | 32 bit float components red, green, blue | -| OSP\_TEXTURE\_R8 | 8 bit \[0–255\] linear single component red | -| OSP\_TEXTURE\_RA8 | 8 bit \[0–255\] linear two components red, alpha | -| OSP\_TEXTURE\_L8 | 8 bit \[0–255\] gamma encoded luminance (replicated into red, green, blue) | -| OSP\_TEXTURE\_LA8 | 8 bit \[0–255\] gamma encoded luminance, and linear alpha | -| OSP\_TEXTURE\_R32F | 32 bit float single component red | -| OSP\_TEXTURE\_RGBA16 | 16 bit \[0–65535\] linear components red, green, blue, alpha | -| OSP\_TEXTURE\_RGB16 | 16 bit \[0–65535\] linear components red, green, blue | -| OSP\_TEXTURE\_RA16 | 16 bit \[0–65535\] linear two components red, alpha | -| OSP\_TEXTURE\_R16 | 16 bit \[0–65535\] linear single component red | +| Name | Description | +|:--------------------|:---------------------------------------------------------------------------| +| OSP_TEXTURE_RGBA8 | 8 bit \[0–255\] linear components red, green, blue, alpha | +| OSP_TEXTURE_SRGBA | 8 bit sRGB gamma encoded color components, and linear alpha | +| OSP_TEXTURE_RGBA32F | 32 bit float components red, green, blue, alpha | +| OSP_TEXTURE_RGB8 | 8 bit \[0–255\] linear components red, green, blue | +| OSP_TEXTURE_SRGB | 8 bit sRGB gamma encoded components red, green, blue | +| OSP_TEXTURE_RGB32F | 32 bit float components red, green, blue | +| OSP_TEXTURE_R8 | 8 bit \[0–255\] linear single component red | +| OSP_TEXTURE_RA8 | 8 bit \[0–255\] linear two components red, alpha | +| OSP_TEXTURE_L8 | 8 bit \[0–255\] gamma encoded luminance (replicated into red, green, blue) | +| OSP_TEXTURE_LA8 | 8 bit \[0–255\] gamma encoded luminance, and linear alpha | +| OSP_TEXTURE_R32F | 32 bit float single component red | +| OSP_TEXTURE_RGBA16 | 16 bit \[0–65535\] linear components red, green, blue, alpha | +| OSP_TEXTURE_RGB16 | 16 bit \[0–65535\] linear components red, green, blue | +| OSP_TEXTURE_RA16 | 16 bit \[0–65535\] linear two components red, alpha | +| OSP_TEXTURE_R16 | 16 bit \[0–65535\] linear single component red | Supported texture formats by `texture2d`, i.e., valid constants of type `OSPTextureFormat`. @@ -2501,13 +2526,13 @@ different transfer function than that of the sliced volume. All materials with textures also offer to manipulate the placement of these textures with the help of texture transformations. If so, this convention shall be used: the following parameters are prefixed with -“`texture_name.`”). +“`texture_name.*`”). | Type | Name | Description | |:---------|:------------|:-------------------------------------------------| | linear2f | transform | linear transformation (rotation, scale) | | float | rotation | angle in degree, counterclockwise, around center | -| vec2f | scale | enlarge texture, relative to center (0.5, 0.5) | +| vec2f | scale | enlarge texture, relative to center (0.5,0.5) | | vec2f | translation | move texture in positive direction (right/up) | Parameters to define 2D texture coordinate transformations. @@ -2537,18 +2562,28 @@ OSPCamera ospNewCamera(const char *type); All cameras accept these parameters: -| Type | Name | Description | -|:-------------|:-----------------|:------------------------------------------------------------------------------| -| vec3f | position | position of the camera in world-space | -| vec3f | direction | main viewing direction of the camera | -| vec3f | up | up direction of the camera | -| affine3f | transform | additional world-space transform, overridden by `motion.transform` | -| float | nearClip | near clipping distance | -| vec2f | imageStart | start of image region (lower left corner) | -| vec2f | imageEnd | end of image region (upper right corner) | -| affine3f\[\] | motion.transform | additional uniformly distributed world-space transforms | -| box1f | time | time associated with first and last key in `motion.` arrays, default \[0, 1\] | -| box1f | shutter | start and end of shutter time (for motion blur), default \[0.5, 0.5\] | +| Type | Name | Default | Description | +|:-------------|:-----------------------|---------------------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| vec3f | position | (0,0,0) | position of the camera | +| vec3f | direction | (0,0,1) | main viewing direction of the camera | +| vec3f | up | (0,1,0) | up direction of the camera | +| affine3f | transform | identity | additional world-space transform, overridden by `motion.*` arrays | +| float | nearClip | 10-6 | near clipping distance | +| vec2f | imageStart | (0,0) | start of image region (lower left corner) | +| vec2f | imageEnd | (1,1) | end of image region (upper right corner) | +| affine3f\[\] | motion.transform | | additional uniformly distributed world-space transforms | +| vec3f\[\] | motion.scale | | additional uniformly distributed world-space scale, overridden by `motion.transform` | +| vec3f\[\] | motion.pivot | | additional uniformly distributed world-space translation which is applied before `motion.rotation` (i.e., the rotation center), overridden by `motion.transform` | +| quatf\[\] | motion.rotation | | additional uniformly distributed world-space quaternion rotation, overridden by `motion.transform` | +| vec3f\[\] | motion.translation | | additional uniformly distributed world-space translation, overridden by `motion.transform` | +| box1f | time | \[0, 1\] | time associated with first and last key in `motion.*` arrays | +| box1f | shutter | \[0.5, 0.5\] | start and end of shutter time (for motion blur), in \[0, 1\] | +| uchar | shutterType | `OSP_SHUTTER_GLOBAL` | `OSPShutterType` for motion blur, also allowed are: | +| | | | `OSP_SHUTTER_ROLLING_RIGHT` | +| | | | `OSP_SHUTTER_ROLLING_LEFT` | +| | | | `OSP_SHUTTER_ROLLING_DOWN` | +| | | | `OSP_SHUTTER_ROLLING_UP` | +| float | rollingShutterDuration | 0 | for a rolling shutter (see `shutterType`) the “open” time per line, in \[0, `shutter`.upper-`shutter`.lower\] | Parameters accepted by all cameras. @@ -2580,20 +2615,19 @@ to the [general parameters](#cameras) understood by all cameras the perspective camera supports the special parameters listed in the table below. -| Type | Name | Description | -|:------|:-----------------------|:---------------------------------------------------------------------------| -| float | fovy | the field of view (angle in degree) of the frame’s height | -| float | aspect | ratio of width by height of the frame (and image region) | -| float | apertureRadius | size of the aperture, controls the depth of field | -| float | focusDistance | distance at where the image is sharpest when depth of field is enabled | -| bool | architectural | vertical edges are projected to be parallel | -| uchar | stereoMode | `OSPStereoMode` for stereo rendering, possible values are: | -| | | `OSP_STEREO_NONE` (default) | -| | | `OSP_STEREO_LEFT` | -| | | `OSP_STEREO_RIGHT` | -| | | `OSP_STEREO_SIDE_BY_SIDE` | -| | | `OSP_STEREO_TOP_BOTTOM` (left eye at top half) | -| float | interpupillaryDistance | distance between left and right eye when stereo is enabled, default 0.0635 | +| Type | Name | Default | Description | +|:------|:-----------------------|------------------:|:-----------------------------------------------------------------------| +| float | fovy | 60 | the field of view (angle in degree) of the frame’s height | +| float | aspect | 1 | ratio of width by height of the frame (and image region) | +| float | apertureRadius | 0 | size of the aperture, controls the depth of field | +| float | focusDistance | 1 | distance at where the image is sharpest when depth of field is enabled | +| bool | architectural | false | vertical edges are projected to be parallel | +| uchar | stereoMode | `OSP_STEREO_NONE` | `OSPStereoMode` for stereo rendering, also allowed are: | +| | | | `OSP_STEREO_LEFT` | +| | | | `OSP_STEREO_RIGHT` | +| | | | `OSP_STEREO_SIDE_BY_SIDE` | +| | | | `OSP_STEREO_TOP_BOTTOM` (left eye at top half) | +| float | interpupillaryDistance | 0.0635 | distance between left and right eye when stereo is enabled | Additional parameters accepted by the perspective camera. @@ -2737,12 +2771,12 @@ The parameter `format` describes the format the color buffer has *on the host*, and the format that `ospMapFrameBuffer` will eventually return. Valid values are: -| Name | Description | -|:-----------------|:------------------------------------------------------------| -| OSP\_FB\_NONE | framebuffer will not be mapped by the application | -| OSP\_FB\_RGBA8 | 8 bit \[0–255\] linear component red, green, blue, alpha | -| OSP\_FB\_SRGBA | 8 bit sRGB gamma encoded color components, and linear alpha | -| OSP\_FB\_RGBA32F | 32 bit float components red, green, blue, alpha | +| Name | Description | +|:---------------|:------------------------------------------------------------| +| OSP_FB_NONE | framebuffer will not be mapped by the application | +| OSP_FB_RGBA8 | 8 bit \[0–255\] linear component red, green, blue, alpha | +| OSP_FB_SRGBA | 8 bit sRGB gamma encoded color components, and linear alpha | +| OSP_FB_RGBA32F | 32 bit float components red, green, blue, alpha | Supported color formats of the framebuffer that can be passed to `ospNewFrameBuffer`, i.e., valid constants of type @@ -2752,14 +2786,14 @@ The parameter `frameBufferChannels` specifies which channels the framebuffer holds, and can be combined together by bitwise OR from the values of `OSPFrameBufferChannel` listed in the table below. -| Name | Description | -|:------------------|:-------------------------------------------------------------------------------------------------------------------------------------------| -| OSP\_FB\_COLOR | RGB color including alpha | -| OSP\_FB\_DEPTH | euclidean distance to the camera (*not* to the image plane), as linear 32 bit float; for multiple samples per pixel their minimum is taken | -| OSP\_FB\_ACCUM | accumulation buffer for progressive refinement | -| OSP\_FB\_VARIANCE | for estimation of the current noise level if OSP\_FB\_ACCUM is also present, see [rendering](#rendering) | -| OSP\_FB\_NORMAL | accumulated world-space normal of the first non-specular hit, as vec3f | -| OSP\_FB\_ALBEDO | accumulated material albedo (color without illumination) at the first hit, as vec3f | +| Name | Description | +|:----------------|:-------------------------------------------------------------------------------------------------------------------------------------------| +| OSP_FB_COLOR | RGB color including alpha | +| OSP_FB_DEPTH | euclidean distance to the camera (*not* to the image plane), as linear 32 bit float; for multiple samples per pixel their minimum is taken | +| OSP_FB_ACCUM | accumulation buffer for progressive refinement | +| OSP_FB_VARIANCE | for estimation of the current noise level if OSP_FB_ACCUM is also present, see [rendering](#rendering) | +| OSP_FB_NORMAL | accumulated world-space normal of the first non-specular hit, as vec3f | +| OSP_FB_ALBEDO | accumulated material albedo (color without illumination) at the first hit, as vec3f | Framebuffer channels constants (of type `OSPFrameBufferChannel`), naming optional information the framebuffer can store. These values can be @@ -2858,14 +2892,14 @@ tone mapping curve can be customized using the parameters listed in the table below. | Type | Name | Default | Description | -|:------|:----------|:--------|:-------------------------------------------------------------------------| -| float | exposure | 1.0 | amount of light per unit area | -| float | contrast | 1.6773 | contrast (toe of the curve); typically is in \[1–2\] | -| float | shoulder | 0.9714 | highlight compression (shoulder of the curve); typically is in \[0.9–1\] | -| float | midIn | 0.18 | mid-level anchor input; default is 18% gray | -| float | midOut | 0.18 | mid-level anchor output; default is 18% gray | +|:------|:----------|--------:|:-------------------------------------------------------------------------| +| float | exposure | 1.0 | amount of light per unit area | +| float | contrast | 1.6773 | contrast (toe of the curve); typically is in \[1–2\] | +| float | shoulder | 0.9714 | highlight compression (shoulder of the curve); typically is in \[0.9–1\] | +| float | midIn | 0.18 | mid-level anchor input; default is 18% gray | +| float | midOut | 0.18 | mid-level anchor output; default is 18% gray | | float | hdrMax | 11.0785 | maximum HDR input that is not clipped | -| bool | acesColor | true | apply the ACES color transforms | +| bool | acesColor | true | apply the ACES color transforms | Parameters accepted by the tone mapper. @@ -2941,13 +2975,13 @@ void ospWait(OSPFuture, OSPSyncEvent = OSP_TASK_FINISHED); The following are values which can be synchronized with the application -| Name | Description | -|:----------------------|:------------------------------------------------------------------------------------------------------------------------------------------------| -| OSP\_NONE\_FINISHED | Do not wait for anything to be finished (immediately return from `ospWait`) | -| OSP\_WORLD\_COMMITTED | Wait for the world to be committed (not yet implemented) | -| OSP\_WORLD\_RENDERED | Wait for the world to be rendered, but not post-processing operations (Pixel/Tile/Frame Op) | -| OSP\_FRAME\_FINISHED | Wait for all rendering operations to complete | -| OSP\_TASK\_FINISHED | Wait on full completion of the task associated with the future. The underlying task may involve one or more of the above synchronization events | +| Name | Description | +|:--------------------|:------------------------------------------------------------------------------------------------------------------------------------------------| +| OSP_NONE_FINISHED | Do not wait for anything to be finished (immediately return from `ospWait`) | +| OSP_WORLD_COMMITTED | Wait for the world to be committed (not yet implemented) | +| OSP_WORLD_RENDERED | Wait for the world to be rendered, but not post-processing operations (Pixel/Tile/Frame Op) | +| OSP_FRAME_FINISHED | Wait for all rendering operations to complete | +| OSP_TASK_FINISHED | Wait on full completion of the task associated with the future. The underlying task may involve one or more of the above synchronization events | Supported events that can be passed to `ospWait`. @@ -3113,9 +3147,9 @@ however, it can also take a specific MPI communicator to use as the world communicator. Only those ranks in the specified communicator will participate in rendering. -| Type | Name | Default | Description | -|:--------|:------------------|-----------------:|:--------------------------------------------------------------------------| -| void \* | worldCommunicator | MPI\_COMM\_WORLD | The MPI communicator which the OSPRay workers should treat as their world | +| Type | Name | Default | Description | +|:--------|:------------------|---------------:|:--------------------------------------------------------------------------| +| void \* | worldCommunicator | MPI_COMM_WORLD | The MPI communicator which the OSPRay workers should treat as their world | Parameters specific to the distributed `mpiDistributed` Device. @@ -3142,7 +3176,7 @@ shipping data out to the workers. When a parallel file system is available, this can improve data load times. Image-parallel rendering is selected by specifying the same data on each rank, and using any of the existing local renderers (e.g., `scivis`, `pathtracer`). See -[ospMPIDistributedTutorialReplicatedData](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistributedTutorialReplicatedData.cpp) +[ospMPIDistribTutorialReplicated](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorialReplicated.cpp) for an example. ### Data Parallel Rendering in the MPI Distributed Device @@ -3163,7 +3197,7 @@ regions out a set of regions (the `region` parameter) can pass as a parameter to the `OSPWorld` being rendered. Each rank can specify one or more non-overlapping `box3f`’s which bound the portions of its local data which it is responsible for rendering. See the -[ospMPIDistributedTutorialStructuredVolume](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistributedTutorialStructuredVolume.cpp) +[ospMPIDistribTutorialVolume](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorialVolume.cpp) for an example. Finally, the MPI distributed device also supports hybrid-parallel @@ -3172,7 +3206,7 @@ each shared piece of data the rendering work will be assigned image-parallel among the ranks. Partially-shared regions are determined by finding those ranks specifying data with the same bounds (matching regions) and merging them. See the -[ospMPIDistributedTutorialPartiallyReplicatedData](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistributedTutorialPartiallyReplicatedData.cpp) +[ospMPIDistribTutorialPartialRepl](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorialPartialRepl.cpp) for an example. #### Picking on Distributed Data in the MPI Distributed Device @@ -3205,7 +3239,7 @@ renders images by delegating off pixel tiles to a number of internal delegate OSPRay devices. Multidevice is in still in an development stage and is currently limited to automatically creating ISPCDevice delegates. -If you wish to try it set the OSPRAY\_NUM\_SUBDEVICES environmental +If you wish to try it set the OSPRAY_NUM_SUBDEVICES environmental variable to the number of subdevices you want to create and tell OSPRay to both load the multidevice extension and create a multidevice for rendering instead of the default ISPCDevice. @@ -3237,7 +3271,7 @@ gcc -std=c99 ../apps/ospTutorial/ospTutorial.c \ ``` On Windows build it can be build manually in a -“build\_directory\\$Configuration” directory with +“build_directory\\$Configuration” directory with ``` sh cl ..\..\apps\ospTutorial\ospTutorial.c -I ..\..\ospray\include -I ..\.. ospray.lib @@ -3308,7 +3342,7 @@ Given below are different scenes listed with their string identifiers: boxes A simple scene with `box` geometry type. -cornell\_box +cornell_box A scene depicting a classic cornell box with `quad` mesh geometry type for rendering two cubes and a `quad` light type. @@ -3317,29 +3351,29 @@ A simple scene with `curve` geometry type and options to change `curveBasis`. For details on different basis’ please check documentation of [curves](#curves). -gravity\_spheres\_volume +gravity_spheres_volume A scene with `structuredRegular` type of [volume](#volumes). -gravity\_spheres\_isosurface +gravity_spheres_isosurface A scene depicting iso-surface rendering of `gravity_spheres_volume` using geometry type `isosurface`. -perlin\_noise\_volumes +perlin_noise_volumes An example scene with `structuredRegular` volume type depicting perlin noise. -random\_spheres +random_spheres A simple scene depicting `sphere` geometry type. streamlines A scene showcasing streamlines geometry derived from `curve` geometry type. -subdivision\_cube +subdivision_cube A scene with a cube of `subdivision` geometry type to showcase subdivision surfaces. -unstructured\_volume +unstructured_volume A simple scene with a volume of `unstructured` volume type. ### Renderer @@ -3397,7 +3431,7 @@ mpicc -std=c99 ../modules/mpi/tutorials/ospMPIDistribTutorial.c \ ``` On Windows build it can be build manually in a -“build\_directory\\$Configuration” directory with +“build_directory\\$Configuration” directory with ``` sh cl ..\..\modules\mpi\tutorials\ospMPIDistribTutorial.c -I ..\..\ospray\include -I ..\.. ospray.lib @@ -3516,8 +3550,8 @@ subdivisions and curves [8] If there are multiple ambient lights then their contribution is added. -[9] respectively (127, 127, 255) for 8 bit textures and -(32767, 32767, 65535) for 16 bit textures +[9] respectively (127,127,255) for 8 bit textures and +(32767,32767,65535) for 16 bit textures [10] A C++ version that uses the C++ convenience wrappers of OSPRay’s C99 API via diff --git a/apps/common/arcball_camera/ArcballCamera.cpp b/apps/common/arcball_camera/ArcballCamera.cpp index 6f2b5b172a..89b5b2b97a 100644 --- a/apps/common/arcball_camera/ArcballCamera.cpp +++ b/apps/common/arcball_camera/ArcballCamera.cpp @@ -84,7 +84,7 @@ void ArcballCamera::updateCamera() invCamera = rcp(camera); } -void ArcballCamera::setRotation(rkcommon::math::quaternionf q) +void ArcballCamera::setRotation(rkcommon::math::quatf q) { rotation = q; updateCamera(); @@ -95,16 +95,16 @@ void ArcballCamera::updateWindowSize(const rkcommon::math::vec2i &windowSize) invWindowSize = rkcommon::math::vec2f(1) / rkcommon::math::vec2f(windowSize); } -rkcommon::math::quaternionf ArcballCamera::screenToArcball( +rkcommon::math::quatf ArcballCamera::screenToArcball( const rkcommon::math::vec2f &p) { const float dist = dot(p, p); // If we're on/in the sphere return the point on it if (dist <= 1.f) { - return rkcommon::math::quaternionf(0, p.x, p.y, std::sqrt(1.f - dist)); + return rkcommon::math::quatf(0, p.x, p.y, std::sqrt(1.f - dist)); } else { // otherwise we project the point onto the sphere const rkcommon::math::vec2f unitDir = normalize(p); - return rkcommon::math::quaternionf(0, unitDir.x, unitDir.y, 0); + return rkcommon::math::quatf(0, unitDir.x, unitDir.y, 0); } } diff --git a/apps/common/arcball_camera/ArcballCamera.h b/apps/common/arcball_camera/ArcballCamera.h index d11d86f739..e8f4cf0063 100644 --- a/apps/common/arcball_camera/ArcballCamera.h +++ b/apps/common/arcball_camera/ArcballCamera.h @@ -23,7 +23,7 @@ class ArcballCamera rkcommon::math::vec3f upDir() const; rkcommon::math::AffineSpace3f transform() const; - void setRotation(rkcommon::math::quaternionf); + void setRotation(rkcommon::math::quatf); void updateWindowSize(const rkcommon::math::vec2i &windowSize); @@ -31,10 +31,10 @@ class ArcballCamera void updateCamera(); // Project the point in [-1, 1] screen space onto the arcball sphere - rkcommon::math::quaternionf screenToArcball(const rkcommon::math::vec2f &p); + rkcommon::math::quatf screenToArcball(const rkcommon::math::vec2f &p); float zoomSpeed; rkcommon::math::vec2f invWindowSize; rkcommon::math::AffineSpace3f centerTranslation, translation, invCamera; - rkcommon::math::quaternionf rotation; + rkcommon::math::quatf rotation; }; diff --git a/apps/common/ospray_testing/CMakeLists.txt b/apps/common/ospray_testing/CMakeLists.txt index 6416c6182f..33358ee1f9 100644 --- a/apps/common/ospray_testing/CMakeLists.txt +++ b/apps/common/ospray_testing/CMakeLists.txt @@ -1,4 +1,4 @@ -## Copyright 2009-2020 Intel Corporation +## Copyright 2009-2021 Intel Corporation ## SPDX-License-Identifier: Apache-2.0 include(GenerateExportHeader) @@ -26,6 +26,7 @@ add_library(ospray_testing SHARED builders/ParticleVolume.cpp builders/VdbVolume.cpp builders/Transparency.cpp + builders/Instancing.cpp # regression test scenes builders/test_pt_glass.cpp diff --git a/apps/common/ospray_testing/builders/Instancing.cpp b/apps/common/ospray_testing/builders/Instancing.cpp new file mode 100644 index 0000000000..35d17c7cfb --- /dev/null +++ b/apps/common/ospray_testing/builders/Instancing.cpp @@ -0,0 +1,229 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "Builder.h" +#include "ospray_testing.h" +#include "rkcommon/utility/multidim_index_sequence.h" +#include "rkcommon/utility/random.h" +// stl +#include + +using namespace rkcommon::math; + +namespace ospray { +namespace testing { + +struct Instancing : public detail::Builder +{ + Instancing() = default; + ~Instancing() override = default; + + void commit() override; + + cpp::Group buildGroup() const override + { + return cpp::Group(); + } + cpp::Group buildGroupA() const; + cpp::Group buildGroupB() const; + cpp::Group buildGroupC() const; + cpp::World buildWorld() const override; + + private: + vec2ui numInstances{10, 10}; +}; + +// Inlined definitions //////////////////////////////////////////////////// + +// Helper functions // +namespace { + +cpp::Geometry makeBoxGeometry(const box3f &box) +{ + cpp::Geometry ospGeometry("box"); + ospGeometry.setParam("box", cpp::CopiedData(box)); + ospGeometry.commit(); + return ospGeometry; +} + +cpp::GeometricModel makeGeometricModel( + cpp::Geometry geo, const std::string &rendererType, const vec3f &kd) +{ + cpp::GeometricModel geometricModel(geo); + + if (rendererType == "pathtracer" || rendererType == "scivis" + || rendererType == "ao") { + cpp::Material objMaterial(rendererType, "obj"); + objMaterial.setParam("kd", kd); + objMaterial.commit(); + geometricModel.setParam("material", objMaterial); + } + geometricModel.commit(); + + return geometricModel; +} + +cpp::Volume makeVolume(const vec3f ¢er) +{ + cpp::Volume volume("structuredRegular"); + { + const vec3i volumeCells{10, 10, 10}; + const vec3f spacing{.25f}; + volume.setParam("gridOrigin", center - volumeCells * spacing / 2.f); + volume.setParam("gridSpacing", spacing); + std::vector voxels(volumeCells.long_product()); + index_sequence_3D numCell(volumeCells); + for (const vec3i i : numCell) + voxels[numCell.flatten(i)] = length(volumeCells - i / 2.f); + volume.setParam("data", cpp::CopiedData(voxels.data(), volumeCells)); + volume.commit(); + } + return volume; +} + +cpp::VolumetricModel makeVolumetricModel(cpp::Volume volume) +{ + cpp::VolumetricModel vModel(volume); + { + // Create transfer function + cpp::TransferFunction transferFunction("piecewiseLinear"); + { + std::vector colors = {{.1f, .4f, .8f}}; + std::vector opacities = {1.f}; + transferFunction.setParam("color", cpp::CopiedData(colors)); + transferFunction.setParam("opacity", cpp::CopiedData(opacities)); + transferFunction.setParam("valueRange", vec2f(0.f, 10.f)); + transferFunction.commit(); + } + + vModel.setParam("transferFunction", transferFunction); + vModel.setParam("densityScale", .5f); + vModel.setParam("gradientShadingScale", 1.f); + vModel.commit(); + } + return vModel; +} + +} // namespace + +// Instancing definitions // + +void Instancing::commit() +{ + Builder::commit(); + + numInstances = getParam("numInstances", numInstances); +} + +cpp::Group Instancing::buildGroupA() const +{ + cpp::Group group; + + cpp::Geometry box = makeBoxGeometry(box3f(vec3f(-1.f), vec3f(1.f))); + cpp::GeometricModel geometricModel = + makeGeometricModel(box, rendererType, vec3f(.1f, .4f, .8f)); + group.setParam("geometry", cpp::CopiedData(geometricModel)); + + cpp::Light light("quad"); + light.setParam("position", vec3f(0.f, 6.f, 0.f)); + light.setParam("edge1", vec3f(0.f, 0.f, -1.f)); + light.setParam("edge2", vec3f(1.f, 0.f, 0.f)); + light.setParam("intensity", 2.0f); + light.setParam("color", vec3f(2.6f, 2.5f, 2.3f)); + light.commit(); + group.setParam("light", cpp::CopiedData(light)); + + group.commit(); + return group; +} + +cpp::Group Instancing::buildGroupB() const +{ + cpp::Group group; + + cpp::Geometry box = makeBoxGeometry(box3f(vec3f(-1.f), vec3f(1.f))); + cpp::GeometricModel geometricModel = + makeGeometricModel(box, rendererType, vec3f(.1f, .4f, .8f)); + group.setParam("geometry", cpp::CopiedData(geometricModel)); + + cpp::Light light("spot"); + light.setParam("position", vec3f(0.f, 6.f, 0.f)); + light.setParam("direction", vec3f(0.f, -1.f, 0.f)); + light.setParam("c0", vec3f(0.f, 1.f, 0.f)); + light.setParam("openingAngle", 180.f); + light.setParam("penumbraAngle", 0.f); + light.setParam("radius", 0.3f); + light.setParam("intensity", 2.0f); + float lid1d[] = {0.f, 2.4f, 0.2f, 0.1f, 0.03f, 0.01f, 0.01f}; + light.setParam("intensityDistribution", cpp::CopiedData(lid1d, 7)); + light.setParam("color", vec3f(2.6f, 2.5f, 2.3f)); + light.commit(); + group.setParam("light", cpp::CopiedData(light)); + + group.commit(); + return group; +} + +cpp::Group Instancing::buildGroupC() const +{ + cpp::Group group; + + // Create volumetric model + group.setParam( + "volume", cpp::CopiedData(makeVolumetricModel(makeVolume(vec3f(0.f))))); + + cpp::Light light("sphere"); + light.setParam("position", vec3f(0.f, 2.f, 0.f)); + light.setParam("radius", .25f); + light.setParam("intensity", 2.0f); + light.setParam("color", vec3f(2.6f, 2.5f, 2.3f)); + light.commit(); + group.setParam("light", cpp::CopiedData(light)); + + group.commit(); + return group; +} + +cpp::World Instancing::buildWorld() const +{ + // Create all groups + std::vector groups; + groups.push_back(buildGroupA()); + groups.push_back(buildGroupB()); + groups.push_back(buildGroupC()); + + // Create instances + std::vector instances; + { + const float spacing = 2.5f; + const vec2f totalSize = spacing * (numInstances - 1); + box3f sceneBounds; + index_sequence_2D indexInstances(numInstances); + for (const vec2ui i : indexInstances) { + const float h = .3f * (sin(.7f * i.x) + sin(.7f * i.y)); + const vec3f position = spacing * vec3f(i.x, h, i.y) + - 0.5f * vec3f(totalSize.x, 0.0f, totalSize.y); + const float d = length(vec2f(position.x, position.z)); + const int gId = int(.18f * d) % groups.size(); + cpp::Instance instance(groups[gId]); + const affine3f xfm = affine3f::translate(position) + * affine3f::rotate(vec3f(0.f, 1.f, 0.f), .03f * (15.f - d)); + instance.setParam("transform", + affine3f::rotate(vec3f(-1.f, 0.f, 0.f), .3f * float(pi)) * xfm); + instance.commit(); + instances.push_back(instance); + } + } + + // Create world + cpp::World world; + world.setParam("instance", cpp::CopiedData(instances)); + + // Done + return world; +} + +OSP_REGISTER_TESTING_BUILDER(Instancing, instancing); + +} // namespace testing +} // namespace ospray diff --git a/apps/ospExamples/GLFWOSPRayWindow.cpp b/apps/ospExamples/GLFWOSPRayWindow.cpp index cccd56c290..63f03bc6a9 100644 --- a/apps/ospExamples/GLFWOSPRayWindow.cpp +++ b/apps/ospExamples/GLFWOSPRayWindow.cpp @@ -50,7 +50,8 @@ static const std::vector g_scenes = {"boxes_lit", "clip_particle_volume", "particle_volume", "particle_volume_isosurface", - "vdb_volume"}; + "vdb_volume", + "instancing"}; static const std::vector g_curveVariant = { "bspline", "hermite", "catmull-rom", "linear", "cones"}; @@ -282,6 +283,7 @@ void GLFWOSPRayWindow::reshape(const vec2i &newWindowSize) void GLFWOSPRayWindow::updateCamera() { camera.setParam("aspect", windowSize.x / float(windowSize.y)); + camera.setParam("stereoMode", cameraStereoMode); const auto xfm = arcballCamera->transform(); if (rendererType == OSPRayRendererType::PATHTRACER && cameraMotionBlur) { camera.removeParam("transform"); @@ -290,6 +292,8 @@ void GLFWOSPRayWindow::updateCamera() xfms.push_back(xfm); camera.setParam("motion.transform", cpp::CopiedData(xfms)); camera.setParam("shutter", range1f(1.0f - cameraMotionBlur, 1.0f)); + camera.setParam("shutterType", cameraShutterType); + camera.setParam("rollingShutterDuration", cameraRollingShutter); renderCameraMotionBlur = true; } else { camera.removeParam("motion.transform"); @@ -655,6 +659,35 @@ void GLFWOSPRayWindow::buildUI() addObjectToCommit(camera.handle()); } + if (cameraMotionBlur > 0.0f) { + static const char *cameraShutterTypes[] = {"global", + "rolling right", + "rolling left", + "rolling down", + "rolling up"}; + if (ImGui::BeginCombo("shutterType##cameraShutterType", + cameraShutterTypes[cameraShutterType])) { + for (int n = 0; n < 5; n++) { + bool is_selected = (cameraShutterType == n); + if (ImGui::Selectable(cameraShutterTypes[n], is_selected)) + cameraShutterType = (OSPShutterType)n; + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + } + + updateCamera(); + addObjectToCommit(camera.handle()); + } + + if (cameraShutterType != OSP_SHUTTER_GLOBAL + && ImGui::SliderFloat( + "rollingShutterDuration", &cameraRollingShutter, 0.f, 1.0f)) { + updateCamera(); + addObjectToCommit(camera.handle()); + } + if (ImGui::Checkbox("renderSunSky", &renderSunSky)) { if (renderSunSky) { sunSky.setParam("direction", sunDirection); @@ -690,6 +723,12 @@ void GLFWOSPRayWindow::buildUI() addObjectToCommit(renderer->handle()); } + static bool visibleLights = false; + if (ImGui::Checkbox("visibleLights", &visibleLights)) { + renderer->setParam("visibleLights", visibleLights); + addObjectToCommit(renderer->handle()); + } + static int aoSamples = 0; if (ImGui::SliderInt("aoSamples", &aoSamples, 0, 64)) { renderer->setParam("aoSamples", aoSamples); @@ -721,6 +760,23 @@ void GLFWOSPRayWindow::buildUI() } } + static const char *cameraStereoModes[] = { + "none", "left", "right", "side-by-side", "top/bottom"}; + if (ImGui::BeginCombo("camera stereoMode##cameraStereoMode", + cameraStereoModes[cameraStereoMode])) { + for (int n = 0; n < 5; n++) { + bool is_selected = (cameraStereoMode == n); + if (ImGui::Selectable(cameraStereoModes[n], is_selected)) + cameraStereoMode = (OSPStereoMode)n; + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + ImGui::EndCombo(); + + updateCamera(); + addObjectToCommit(camera.handle()); + } + if (uiCallback) { ImGui::Separator(); uiCallback(); diff --git a/apps/ospExamples/GLFWOSPRayWindow.h b/apps/ospExamples/GLFWOSPRayWindow.h index 40defad61c..0c13fbd25c 100644 --- a/apps/ospExamples/GLFWOSPRayWindow.h +++ b/apps/ospExamples/GLFWOSPRayWindow.h @@ -71,7 +71,10 @@ class GLFWOSPRayWindow // Arcball camera instance std::unique_ptr arcballCamera; affine3f lastXfm{one}; + OSPStereoMode cameraStereoMode{OSP_STEREO_NONE}; float cameraMotionBlur{0.0f}; + float cameraRollingShutter{0.0f}; + OSPShutterType cameraShutterType{OSP_SHUTTER_GLOBAL}; // only one frame during movement is rendered with MB, // during accumulation the camera is static and thus no MB bool renderCameraMotionBlur{false}; diff --git a/apps/ospTestSuite/CMakeLists.txt b/apps/ospTestSuite/CMakeLists.txt index 2b4ce76e66..db22330ea9 100644 --- a/apps/ospTestSuite/CMakeLists.txt +++ b/apps/ospTestSuite/CMakeLists.txt @@ -10,11 +10,27 @@ find_package(GTest REQUIRED CONFIG) ospray_disable_compiler_warnings() -add_executable(ospTestSuite - ${OSPRAY_RESOURCE} +add_library(ospray_gtest_utils environment.cpp - test_fixture.cpp test_tools.cpp + test_fixture.cpp +) + +target_link_libraries(ospray_gtest_utils +PUBLIC + arcball_camera + ospray_testing + GTest::gtest + stb_image +) + +target_include_directories(ospray_gtest_utils +PUBLIC + $ +) + +add_executable(ospTestSuite + ${OSPRAY_RESOURCE} test_geometry.cpp test_volumetric.cpp test_appearance.cpp @@ -28,11 +44,9 @@ add_executable(ospTestSuite target_link_libraries(ospTestSuite PRIVATE - arcball_camera ospray_testing ospray_module_ispc - GTest::gtest - stb_image + ospray_gtest_utils $<$:${GLM_TARGET}> ) diff --git a/apps/ospTestSuite/environment.cpp b/apps/ospTestSuite/environment.cpp index aa21bac953..c55b0a3ac0 100644 --- a/apps/ospTestSuite/environment.cpp +++ b/apps/ospTestSuite/environment.cpp @@ -1,4 +1,4 @@ -// Copyright 2017-2019 Intel Corporation +// Copyright 2017-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "environment.h" @@ -9,10 +9,10 @@ OSPRayEnvironment::OSPRayEnvironment(int argc, char **argv) baselineDir("regression_test_baseline"), failedDir("failed") { - ParsArgs(argc, argv); + ParseArgs(argc, argv); } -void OSPRayEnvironment::ParsArgs(int argc, char **argv) +void OSPRayEnvironment::ParseArgs(int argc, char **argv) { std::vector testArgs; for (int idx = 0; idx < argc; ++idx) { diff --git a/apps/ospTestSuite/environment.h b/apps/ospTestSuite/environment.h index dba329b198..9bea074e19 100644 --- a/apps/ospTestSuite/environment.h +++ b/apps/ospTestSuite/environment.h @@ -1,4 +1,4 @@ -// Copyright 2017-2020 Intel Corporation +// Copyright 2017-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -40,7 +40,7 @@ class OSPRayEnvironment : public ::testing::Environment return failedDir; } - void ParsArgs(int argc, char **argv); + void ParseArgs(int argc, char **argv); std::string GetStrArgValue(std::string *arg) const; int GetNumArgValue(std::string *arg) const; diff --git a/apps/ospTestSuite/test_fixture.h b/apps/ospTestSuite/test_fixture.h index 311cc2aaeb..c7e8474493 100644 --- a/apps/ospTestSuite/test_fixture.h +++ b/apps/ospTestSuite/test_fixture.h @@ -1,4 +1,4 @@ -// Copyright 2017-2020 Intel Corporation +// Copyright 2017-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -34,9 +34,9 @@ class Base void AddLight(cpp::Light new_light); void AddModel(cpp::GeometricModel model, affine3f xfm = one); void AddModel(cpp::VolumetricModel model, affine3f xfm = one); - void AddInstance(cpp::Instance instance); + virtual void AddInstance(cpp::Instance instance); - void PerformRenderTest(); + virtual void PerformRenderTest(); vec2i GetImgSize() const { diff --git a/apps/ospTestSuite/test_geometry.cpp b/apps/ospTestSuite/test_geometry.cpp index a561ec8838..0c0300bbea 100644 --- a/apps/ospTestSuite/test_geometry.cpp +++ b/apps/ospTestSuite/test_geometry.cpp @@ -147,7 +147,8 @@ INSTANTIATE_TEST_SUITE_P(TestScenesGeometry, "streamlines", "subdivision_cube", "planes", - "unstructured_volume_isosurface"), + "unstructured_volume_isosurface", + "instancing"), ::testing::Values("scivis", "pathtracer", "ao"), ::testing::Values(16))); diff --git a/apps/ospTestSuite/test_light.cpp b/apps/ospTestSuite/test_light.cpp index 65112c2dda..fa32fb9702 100644 --- a/apps/ospTestSuite/test_light.cpp +++ b/apps/ospTestSuite/test_light.cpp @@ -9,6 +9,12 @@ namespace OSPRayTestScenes { LightTest::LightTest() { samplesPerPixel = 16; + + // due to the way c0 in SpotLight is calculated we must rotate around X axis + // to get the same result with SciVis and ring light (because its + // approximation in SciVis is not rotation invariant) + xfm = affine3f::translate(vec3f(1.f, 2.f, 3.f)) + * affine3f::rotate(vec3f(1.f, 0.f, 0.f), pi); } void LightTest::SetUp() @@ -35,30 +41,25 @@ void LightTest::SetUp() camera.setParam("position", vec3f(0, 0, -2.4641)); } -SunSky::SunSky() +void LightTest::AddInstancedLightWithMB( + cpp::Light light, const affine3f &xfm1, const affine3f &xfm2) { - rendererType = "pathtracer"; - samplesPerPixel = 1; -} - -void SunSky::SetUp() -{ - Base::SetUp(); - auto params = GetParam(); - - cpp::Light light("sunSky"); - float turb = std::get<2>(params); - light.setParam("up", std::get<0>(params)); - light.setParam("direction", std::get<1>(params)); - light.setParam("turbidity", turb); - light.setParam("albedo", std::get<3>(params)); - // lower brightness with high turbidity - light.setParam("intensityQuantity", OSP_INTENSITY_QUANTITY_SCALE); - light.setParam("intensity", 0.025f / turb); - light.setParam("horizonExtension", std::get<4>(params)); - AddLight(light); + light.commit(); + cpp::Group group; + group.setParam("light", cpp::CopiedData(light)); + group.commit(); + cpp::Instance instance(group); + const affine3f xfmR = rcp(xfm); + if (motionBlur) { + std::vector xfms; + xfms.push_back(xfmR * xfm1); + xfms.push_back(xfmR * xfm2); + instance.setParam("motion.transform", cpp::CopiedData(xfms)); + camera.setParam("shutter", range1f(0, 1)); + } else + instance.setParam("transform", xfmR); - renderer.setParam("backgroundColor", vec4f(0.f, 0.f, 0.f, 1.0f)); + AddInstance(instance); } AmbientLight::AmbientLight() @@ -83,6 +84,7 @@ DistantLight::DistantLight() auto params = GetParam(); direction = std::get<0>(params); rendererType = std::get<1>(params); + motionBlur = std::get<2>(params); } void DistantLight::SetUp() @@ -90,10 +92,11 @@ void DistantLight::SetUp() LightTest::SetUp(); cpp::Light distant("distant"); - distant.setParam("direction", direction); + distant.setParam("direction", xfmVector(xfm, direction)); distant.setParam("color", vec3f(1.0f, 0.75f, 0.25f)); distant.setParam("angularDiameter", 1.0f); - AddLight(distant); + + AddInstancedLightWithRotateMB(distant); } GeometricLight::GeometricLight() @@ -167,19 +170,19 @@ void PhotometricLight::SetUp() cpp::Light light1d("spot"); light1d.setParam("intensity", 5.f); - light1d.setParam("position", vec3f(-0.6f, 0.8f, -0.5f)); - light1d.setParam("direction", vec3f(0.0f, -1.0f, 0.0f)); + light1d.setParam("position", xfmPoint(xfm, vec3f(-0.6f, 0.8f, -0.5f))); + light1d.setParam("direction", xfmVector(xfm, vec3f(0.0f, -1.0f, 0.0f))); light1d.setParam("openingAngle", 360.f); light1d.setParam("penumbraAngle", 0.f); light1d.setParam("radius", radius); float lid1d[] = {2.5f, 0.4f, 0.2f, 0.1f, 0.03f, 0.01f, 0.01f}; light1d.setParam("intensityDistribution", cpp::CopiedData(lid1d, 7)); - AddLight(light1d); + light1d.commit(); cpp::Light light2d("spot"); light2d.setParam("intensity", 1.f); - light2d.setParam("position", vec3f(0.3f, 0.6f, 0.f)); - light2d.setParam("direction", vec3f(0.0f, -1.0f, 0.0f)); + light2d.setParam("position", xfmPoint(xfm, vec3f(0.3f, 0.6f, 0.f))); + light2d.setParam("direction", xfmVector(xfm, vec3f(0.0f, -1.0f, 0.0f))); light2d.setParam("openingAngle", 270.f); light2d.setParam("penumbraAngle", 10.f); light2d.setParam("radius", radius); @@ -187,8 +190,16 @@ void PhotometricLight::SetUp() 1.5f, 5.0f, 6.0f, 0.3f, 0.01f, 0.15f, 0.5f, 1.6f, 0.1f, 0.01f}; light2d.setParam( "intensityDistribution", cpp::CopiedData(lid2d, vec2ul(5, 12))); - light2d.setParam("c0", vec3f(1.0f, 0.0f, 0.0f)); - AddLight(light2d); + light2d.setParam("c0", xfmVector(xfm, vec3f(1.0f, 0.0f, 0.0f))); + light2d.commit(); + + cpp::Group group; + std::vector lights{light1d, light2d}; + group.setParam("light", cpp::CopiedData(lights)); + group.commit(); + cpp::Instance instance(group); + instance.setParam("transform", rcp(xfm)); + AddInstance(instance); } QuadLight::QuadLight() @@ -197,6 +208,7 @@ QuadLight::QuadLight() size = std::get<0>(params); rendererType = std::get<1>(params); intensityQuantity = std::get<2>(params); + motionBlur = std::get<3>(params); } void QuadLight::SetUp() @@ -207,10 +219,38 @@ void QuadLight::SetUp() light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); light.setParam("intensity", 10.f); light.setParam("intensityQuantity", intensityQuantity); - light.setParam("position", vec3f(size / -2.0f, 0.98f, size / -2.0f)); - light.setParam("edge1", vec3f(size, 0.0f, 0.0f)); - light.setParam("edge2", vec3f(0.0f, 0.0f, size)); - AddLight(light); + light.setParam( + "position", xfmPoint(xfm, vec3f(size / -2.0f, 0.98f, size / -2.0f))); + light.setParam("edge1", xfmVector(xfm, vec3f(size, 0.0f, 0.0f))); + light.setParam("edge2", xfmVector(xfm, vec3f(0.0f, 0.0f, size))); + + AddInstancedLightWithTranslateMB(light); +} + +CylinderLight::CylinderLight() +{ + auto params = GetParam(); + size = std::get<0>(params); + rendererType = std::get<1>(params); + intensityQuantity = std::get<2>(params); + motionBlur = std::get<3>(params); +} + +void CylinderLight::SetUp() +{ + LightTest::SetUp(); + + cpp::Light light("cylinder"); + light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); + light.setParam("intensity", 5.0f); + light.setParam("intensityQuantity", intensityQuantity); + light.setParam( + "position0", xfmPoint(xfm, vec3f(-0.2f - 2.0 * size, 0.65f, 0.0f))); + light.setParam( + "position1", xfmPoint(xfm, vec3f(0.2f + 2.0 * size, 0.65f, 0.0f))); + light.setParam("radius", size); + + AddInstancedLightWithTranslateMB(light); } SphereLight::SphereLight() @@ -219,6 +259,7 @@ SphereLight::SphereLight() radius = std::get<0>(params); rendererType = std::get<1>(params); intensityQuantity = std::get<2>(params); + motionBlur = std::get<3>(params); } void SphereLight::SetUp() @@ -229,9 +270,10 @@ void SphereLight::SetUp() light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); light.setParam("intensity", 2.5f); light.setParam("intensityQuantity", intensityQuantity); - light.setParam("position", vec3f(0.0f, 0.48f, 0.0f)); + light.setParam("position", xfmPoint(xfm, vec3f(0.0f, 0.48f, 0.0f))); light.setParam("radius", radius); - AddLight(light); + + AddInstancedLightWithTranslateMB(light); } SpotLight::SpotLight() @@ -240,6 +282,7 @@ SpotLight::SpotLight() innerOuterRadius = std::get<0>(params); rendererType = std::get<1>(params); intensityQuantity = std::get<2>(params); + motionBlur = std::get<3>(params); } void SpotLight::SetUp() @@ -250,16 +293,19 @@ void SpotLight::SetUp() light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); light.setParam("intensity", 10.f); light.setParam("intensityQuantity", intensityQuantity); - light.setParam("position", vec3f(0.0f, 0.98f, 0.0f)); - light.setParam("direction", vec3f(0.0f, -1.0f, 0.0f)); + light.setParam("position", xfmPoint(xfm, vec3f(0.0f, 0.98f, 0.0f))); + light.setParam("direction", xfmVector(xfm, vec3f(0.0f, -1.0f, 0.0f))); light.setParam("radius", innerOuterRadius[1]); light.setParam("innerRadius", innerOuterRadius[0]); - AddLight(light); + + AddInstancedLightWithTranslateMB(light); } HDRILight::HDRILight() { - rendererType = GetParam(); + auto params = GetParam(); + rendererType = std::get<0>(params); + motionBlur = std::get<1>(params); } void HDRILight::SetUp() @@ -317,40 +363,47 @@ void HDRILight::SetUp() // prepare light cpp::Light light("hdri"); light.setParam("color", vec3f(0.78f, 0.551f, 0.183f)); - light.setParam("up", vec3f(0.f, 1.f, 0.f)); - light.setParam("direction", vec3f(0.f, 0.f, 1.f)); + light.setParam("up", xfmVector(xfm, vec3f(0.f, 1.f, 0.f))); + light.setParam("direction", xfmVector(xfm, vec3f(0.f, 0.f, 1.f))); light.setParam("map", envTex); - AddLight(light); + + AddInstancedLightWithRotateMB(light); renderer.setParam("backgroundColor", vec4f(0.f, 0.f, 0.f, 1.0f)); } -// Test Instantiations ////////////////////////////////////////////////////// +SunSky::SunSky() +{ + rendererType = "pathtracer"; + samplesPerPixel = 1; + auto params = GetParam(); + motionBlur = std::get<5>(params); +} -TEST_P(SunSky, parameter) +void SunSky::SetUp() { - PerformRenderTest(); + Base::SetUp(); + auto params = GetParam(); + + cpp::Light light("sunSky"); + float turb = std::get<2>(params); + light.setParam("up", xfmVector(xfm, std::get<0>(params))); + light.setParam("direction", xfmVector(xfm, std::get<1>(params))); + light.setParam("turbidity", turb); + light.setParam("albedo", std::get<3>(params)); + // lower brightness with high turbidity + light.setParam("intensityQuantity", OSP_INTENSITY_QUANTITY_SCALE); + light.setParam("intensity", 0.025f / turb); + light.setParam("horizonExtension", std::get<4>(params)); + + AddInstancedLightWithRotateMB(light); + + renderer.setParam("backgroundColor", vec4f(0.f, 0.f, 0.f, 1.0f)); } -INSTANTIATE_TEST_SUITE_P(Light, - SunSky, - ::testing::Combine(::testing::Values(vec3f(0.f, 0.8f, 0.4f)), - ::testing::Values(vec3f(0.f, 0.7f, -1.f), - vec3f(0.f, 0.4f, -1.f), - vec3f(0.f, 0.1f, -1.f), - vec3f(0.f, -0.3f, -1.f), - vec3f(0.f, -0.8f, 0.4f)), - ::testing::Values(1.0f, 3.0f, 10.0f), - ::testing::Values(0.0f), - ::testing::Values(0.01f))); +// Test Instantiations ////////////////////////////////////////////////////// -INSTANTIATE_TEST_SUITE_P(Light2, - SunSky, - ::testing::Combine(::testing::Values(vec3f(0.2f, -0.5f, 0.f)), - ::testing::Values(vec3f(0.2f, 0.4f, -1.f), vec3f(0.f, 0.f, -1.f)), - ::testing::Values(2.0f), - ::testing::Values(0.0f, 1.0f), - ::testing::Values(0.1f))); +// Ambient Light TEST_P(AmbientLight, parameter) { @@ -360,6 +413,8 @@ TEST_P(AmbientLight, parameter) INSTANTIATE_TEST_SUITE_P( Light, AmbientLight, ::testing::Values("scivis", "pathtracer")); +// Distant Light + TEST_P(DistantLight, parameter) { PerformRenderTest(); @@ -369,7 +424,15 @@ INSTANTIATE_TEST_SUITE_P(Light, DistantLight, ::testing::Combine( ::testing::Values(vec3f(0.0f, 0.0f, 1.0f), vec3f(-0.5f, 1.0f, 3.0f)), - ::testing::Values("scivis", "pathtracer"))); + ::testing::Values("scivis", "pathtracer"), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightMotionBlur, + DistantLight, + ::testing::Values( + std::make_tuple(vec3f(-0.5f, 1.0f, 3.0f), "pathtracer", true))); + +// Geometric Light TEST_P(GeometricLight, parameter) { @@ -386,26 +449,61 @@ INSTANTIATE_TEST_SUITE_P(LightMotionBlur, GeometricLight, ::testing::Values(std::make_tuple(0.2f, false, true))); -TEST_P(PhotometricLight, parameter) +// Quad Light + +TEST_P(QuadLight, parameter) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Light, - PhotometricLight, - ::testing::Combine(::testing::Values(0.0f, 0.1f), - ::testing::Values("scivis", "pathtracer"))); + QuadLight, + ::testing::Combine(::testing::Values(0.2f, 0.4f), + ::testing::Values("scivis", "pathtracer"), + ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY), + ::testing::Values(false))); -TEST_P(QuadLight, parameter) +INSTANTIATE_TEST_SUITE_P(LightIntensityQuantity, + QuadLight, + ::testing::Combine(::testing::Values(0.2f, 0.4f), + ::testing::Values("pathtracer"), + ::testing::Values( + OSP_INTENSITY_QUANTITY_RADIANCE, OSP_INTENSITY_QUANTITY_POWER), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightMotionBlur, + QuadLight, + ::testing::Values(std::make_tuple( + 0.2f, "pathtracer", OSP_INTENSITY_QUANTITY_INTENSITY, true))); + +// Cylinder Light + +TEST_P(CylinderLight, parameter) { PerformRenderTest(); } INSTANTIATE_TEST_SUITE_P(Light, - QuadLight, - ::testing::Combine(::testing::Values(0.2f, 0.4f), + CylinderLight, + ::testing::Combine(::testing::Values(0.02f, 0.15f), ::testing::Values("scivis", "pathtracer"), - ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY))); + ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightIntensityQuantity, + CylinderLight, + ::testing::Combine(::testing::Values(0.02f, 0.15), + ::testing::Values("pathtracer"), + ::testing::Values( + OSP_INTENSITY_QUANTITY_RADIANCE, OSP_INTENSITY_QUANTITY_POWER), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightMotionBlur, + CylinderLight, + ::testing::Values(std::make_tuple( + 0.02f, "pathtracer", OSP_INTENSITY_QUANTITY_INTENSITY, true))); + +// Sphere Light TEST_P(SphereLight, parameter) { @@ -416,7 +514,23 @@ INSTANTIATE_TEST_SUITE_P(Light, SphereLight, ::testing::Combine(::testing::Values(0.0f, 0.2f, 0.3f), ::testing::Values("scivis", "pathtracer"), - ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY))); + ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightIntensityQuantity, + SphereLight, + ::testing::Combine(::testing::Values(0.0f, 0.2f, 0.3f), + ::testing::Values("pathtracer"), + ::testing::Values( + OSP_INTENSITY_QUANTITY_RADIANCE, OSP_INTENSITY_QUANTITY_POWER), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightMotionBlur, + SphereLight, + ::testing::Values(std::make_tuple( + 0.3f, "pathtracer", OSP_INTENSITY_QUANTITY_RADIANCE, true))); + +// Spot Light TEST_P(SpotLight, parameter) { @@ -431,21 +545,8 @@ INSTANTIATE_TEST_SUITE_P(Light, vec2f(0.2f, 0.4f), vec2f(0.7f, 0.8f)), ::testing::Values("scivis", "pathtracer"), - ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY))); - -INSTANTIATE_TEST_SUITE_P(LightIntensityQuantity, - QuadLight, - ::testing::Combine(::testing::Values(0.2f, 0.4f), - ::testing::Values("pathtracer"), - ::testing::Values( - OSP_INTENSITY_QUANTITY_RADIANCE, OSP_INTENSITY_QUANTITY_POWER))); - -INSTANTIATE_TEST_SUITE_P(LightIntensityQuantity, - SphereLight, - ::testing::Combine(::testing::Values(0.0f, 0.2f, 0.3f), - ::testing::Values("pathtracer"), - ::testing::Values( - OSP_INTENSITY_QUANTITY_RADIANCE, OSP_INTENSITY_QUANTITY_POWER))); + ::testing::Values(OSP_INTENSITY_QUANTITY_INTENSITY), + ::testing::Values(false))); INSTANTIATE_TEST_SUITE_P(LightIntensityQuantity, SpotLight, @@ -454,14 +555,80 @@ INSTANTIATE_TEST_SUITE_P(LightIntensityQuantity, vec2f(0.0f, 0.0f), vec2f(0.0f, 0.2f), vec2f(0.0f, 0.4f)), ::testing::Values("pathtracer"), ::testing::Values( - OSP_INTENSITY_QUANTITY_RADIANCE, OSP_INTENSITY_QUANTITY_POWER))); + OSP_INTENSITY_QUANTITY_RADIANCE, OSP_INTENSITY_QUANTITY_POWER), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightMotionBlur, + SpotLight, + ::testing::Values(std::make_tuple(vec2f(0.0f, 0.4f), + "pathtracer", + OSP_INTENSITY_QUANTITY_RADIANCE, + true))); + +// Photometric (Spot) Light + +TEST_P(PhotometricLight, parameter) +{ + PerformRenderTest(); +} + +INSTANTIATE_TEST_SUITE_P(Light, + PhotometricLight, + ::testing::Combine(::testing::Values(0.0f, 0.1f), + ::testing::Values("scivis", "pathtracer"))); + +// HDRI Light TEST_P(HDRILight, parameter) { PerformRenderTest(); } -INSTANTIATE_TEST_SUITE_P( - Light, HDRILight, ::testing::Values("scivis", "pathtracer")); +INSTANTIATE_TEST_SUITE_P(Light, + HDRILight, + ::testing::Combine( + ::testing::Values("scivis", "pathtracer"), ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightMotionBlur, + HDRILight, + ::testing::Values(std::make_tuple("pathtracer", true))); + +// SunSky Light + +TEST_P(SunSky, parameter) +{ + PerformRenderTest(); +} + +INSTANTIATE_TEST_SUITE_P(Light, + SunSky, + ::testing::Combine(::testing::Values(vec3f(0.f, 0.8f, 0.4f)), + ::testing::Values(vec3f(0.f, 0.7f, -1.f), + vec3f(0.f, 0.4f, -1.f), + vec3f(0.f, 0.1f, -1.f), + vec3f(0.f, -0.3f, -1.f), + vec3f(0.f, -0.8f, 0.4f)), + ::testing::Values(1.0f, 3.0f, 10.0f), + ::testing::Values(0.0f), + ::testing::Values(0.01f), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(Light2, + SunSky, + ::testing::Combine(::testing::Values(vec3f(0.2f, -0.5f, 0.f)), + ::testing::Values(vec3f(0.2f, 0.4f, -1.f), vec3f(0.f, 0.f, -1.f)), + ::testing::Values(2.0f), + ::testing::Values(0.0f, 1.0f), + ::testing::Values(0.1f), + ::testing::Values(false))); + +INSTANTIATE_TEST_SUITE_P(LightMotionBlur, + SunSky, + ::testing::Values(std::make_tuple(vec3f(0.2f, -0.5f, 0.f), + vec3f(0.2f, 0.4f, -1.f), + 2.0f, + 0.0f, + 0.1f, + true))); } // namespace OSPRayTestScenes diff --git a/apps/ospTestSuite/test_light.h b/apps/ospTestSuite/test_light.h index 9e046b9ad4..89bf9abe83 100644 --- a/apps/ospTestSuite/test_light.h +++ b/apps/ospTestSuite/test_light.h @@ -10,18 +10,24 @@ class LightTest : public Base public: LightTest(); void SetUp() override; -}; - -class SunSky : public LightTest, - public ::testing::TestWithParam> -{ - public: - SunSky(); - void SetUp() override; + void AddInstancedLightWithMB( + cpp::Light light, const affine3f &xfm1, const affine3f &xfm2); + void AddInstancedLightWithTranslateMB(cpp::Light light) + { + AddInstancedLightWithMB(light, + affine3f::translate(vec3f(-0.5, 0, 0)), + affine3f::translate(vec3f(0.5, 0, 0))); + }; + void AddInstancedLightWithRotateMB(cpp::Light light) + { + AddInstancedLightWithMB(light, + affine3f::rotate(vec3f(0.f, 0.f, 1.f), -.25f * float(pi)), + affine3f::rotate(vec3f(0.f, 0.f, 1.f), .25f * float(pi))); + }; + + protected: + affine3f xfm; + bool motionBlur{false}; }; class AmbientLight @@ -35,8 +41,9 @@ class AmbientLight class DistantLight : public LightTest, - public ::testing::TestWithParam< - std::tuple> + public ::testing::TestWithParam> { public: DistantLight(); @@ -59,7 +66,6 @@ class GeometricLight private: float size{0.2}; bool useMaterialList{true}; - bool motionBlur{false}; }; class PhotometricLight @@ -78,7 +84,8 @@ class PhotometricLight class QuadLight : public LightTest, public ::testing::TestWithParam> + OSPIntensityQuantity, + bool /*motionBlur*/>> { public: QuadLight(); @@ -89,10 +96,26 @@ class QuadLight : public LightTest, OSPIntensityQuantity intensityQuantity{OSP_INTENSITY_QUANTITY_UNKNOWN}; }; +class CylinderLight : public LightTest, + public ::testing::TestWithParam> +{ + public: + CylinderLight(); + void SetUp() override; + + private: + float size{0.2}; + OSPIntensityQuantity intensityQuantity{OSP_INTENSITY_QUANTITY_UNKNOWN}; +}; + class SphereLight : public LightTest, public ::testing::TestWithParam> + OSPIntensityQuantity, + bool /*motionBlur*/>> { public: SphereLight(); @@ -107,7 +130,8 @@ class SpotLight : public LightTest, public ::testing::TestWithParam> + OSPIntensityQuantity, + bool /*motionBlur*/>> { public: SpotLight(); @@ -120,11 +144,25 @@ class SpotLight class HDRILight : public LightTest, - public ::testing::TestWithParam + public ::testing::TestWithParam< + std::tuple> { public: HDRILight(); void SetUp() override; }; +class SunSky : public LightTest, + public ::testing::TestWithParam> +{ + public: + SunSky(); + void SetUp() override; +}; + } // namespace OSPRayTestScenes diff --git a/apps/ospTestSuite/test_motionblur.cpp b/apps/ospTestSuite/test_motionblur.cpp index 8b8cab1be4..8451c3c395 100644 --- a/apps/ospTestSuite/test_motionblur.cpp +++ b/apps/ospTestSuite/test_motionblur.cpp @@ -8,17 +8,29 @@ namespace OSPRayTestScenes { class MotionBlurBoxes : public Base, - public ::testing::TestWithParam + public ::testing::TestWithParam> { public: MotionBlurBoxes(); void SetUp() override; + + protected: + OSPStereoMode stereoMode{OSP_STEREO_NONE}; + OSPShutterType shutterType{OSP_SHUTTER_GLOBAL}; + float rollingShutterDuration{0.f}; }; MotionBlurBoxes::MotionBlurBoxes() { - rendererType = GetParam(); - samplesPerPixel = 64; + auto params = GetParam(); + rendererType = std::get<0>(params); + stereoMode = std::get<1>(params); + shutterType = std::get<2>(params); + rollingShutterDuration = std::get<3>(params); + samplesPerPixel = rendererType == "pathtracer" ? 64 : 16; } void MotionBlurBoxes::SetUp() @@ -26,7 +38,10 @@ void MotionBlurBoxes::SetUp() Base::SetUp(); renderer.setParam("backgroundColor", vec4f(0.2, 0.2, 0.2, 1.0f)); camera.setParam("position", vec3f(0, 0, -9)); + camera.setParam("stereoMode", stereoMode); camera.setParam("shutter", range1f(0.0f, 1.0f)); + camera.setParam("shutterType", shutterType); + camera.setParam("rollingShutterDuration", rollingShutterDuration); cpp::Geometry boxGeometry("box"); boxGeometry.setParam( @@ -128,6 +143,26 @@ void MotionBlurBoxes::SetUp() AddInstance(instance); } + { // quaternion + cpp::Instance instance(group); + std::vector ss; + ss.push_back(vec3f(0, -4, 0)); + ss.push_back(vec3f(0, -4, 0)); + ss.push_back(vec3f(0, -4, 0)); + instance.setParam("motion.pivot", cpp::CopiedData(ss)); + std::vector qs; + qs.push_back(quatf::rotate(vec3f(0, 0, 1), -0.8)); + qs.push_back(quatf::rotate(vec3f(0, 0, 1), -1.2)); + qs.push_back(quatf::rotate(vec3f(0, 0, 1), -1.6)); + instance.setParam("motion.rotation", cpp::CopiedData(qs)); + std::vector ts; + ts.push_back(vec3f(0, 4, 0)); + ts.push_back(vec3f(0, 4, 0)); + ts.push_back(vec3f(0, 4, 0)); + instance.setParam("motion.translation", cpp::CopiedData(ts)); + AddInstance(instance); + } + cpp::Light distant("distant"); distant.setParam("intensity", 3.0f); distant.setParam("direction", vec3f(0.3f, -4.0f, 2.8f)); @@ -142,9 +177,10 @@ void MotionBlurBoxes::SetUp() } // Test camera MB (also in combination with stereo) //////////////////////////// -class MotionCamera : public Base, - public ::testing::TestWithParam< - std::tuple> +class MotionCamera + : public Base, + public ::testing::TestWithParam< + std::tuple> { public: MotionCamera(); @@ -153,7 +189,8 @@ class MotionCamera : public Base, protected: std::string cameraType; vec3f pos{0.0f, 0.0f, -0.5f}; - OSPStereoMode stereoMode; + OSPStereoMode stereoMode{OSP_STEREO_NONE}; + OSPShutterType shutterType{OSP_SHUTTER_GLOBAL}; }; MotionCamera::MotionCamera() @@ -164,6 +201,7 @@ MotionCamera::MotionCamera() auto params = GetParam(); cameraType = std::get<0>(params); stereoMode = std::get<1>(params); + shutterType = std::get<2>(params); } void MotionCamera::SetUp() @@ -178,7 +216,6 @@ void MotionCamera::SetUp() world = ospray::testing::buildWorld(builder); ospray::testing::release(builder); - world.commit(); camera = cpp::Camera(cameraType); if (cameraType != "panoramic") { @@ -196,7 +233,7 @@ void MotionCamera::SetUp() xfms.push_back(affine3f::rotate(vec3f(0, 4, 0), vec3f(0, 0, 1), 0.12)); camera.setParam("motion.transform", cpp::CopiedData(xfms)); camera.setParam("shutter", range1f(0.0f, 1.0f)); - camera.commit(); + camera.setParam("shutterType", shutterType); } // Test Instantiations ////////////////////////////////////////////////////// @@ -206,8 +243,29 @@ TEST_P(MotionBlurBoxes, instance_mb) PerformRenderTest(); } -INSTANTIATE_TEST_SUITE_P( - TestMotionBlur, MotionBlurBoxes, ::testing::Values("scivis", "pathtracer")); +INSTANTIATE_TEST_SUITE_P(TestMotionBlur, + MotionBlurBoxes, + ::testing::Combine(::testing::Values("scivis", "pathtracer"), + ::testing::Values(OSP_STEREO_NONE), + ::testing::Values(OSP_SHUTTER_GLOBAL), + ::testing::Values(0.f))); + +INSTANTIATE_TEST_SUITE_P(CameraRollingShutter, + MotionBlurBoxes, + ::testing::Combine(::testing::Values("pathtracer"), + ::testing::Values(OSP_STEREO_NONE), + ::testing::Values(OSP_SHUTTER_ROLLING_RIGHT, + OSP_SHUTTER_ROLLING_LEFT, + OSP_SHUTTER_ROLLING_DOWN, + OSP_SHUTTER_ROLLING_UP), + ::testing::Values(0.f, 0.1f))); + +INSTANTIATE_TEST_SUITE_P(CameraStereoRollingShutter, + MotionBlurBoxes, + ::testing::Combine(::testing::Values("pathtracer"), + ::testing::Values(OSP_STEREO_TOP_BOTTOM), + ::testing::Values(OSP_SHUTTER_ROLLING_DOWN), + ::testing::Values(0.f))); TEST_P(MotionCamera, camera_mb) { @@ -217,11 +275,22 @@ TEST_P(MotionCamera, camera_mb) INSTANTIATE_TEST_SUITE_P(Camera, MotionCamera, ::testing::Combine(::testing::Values("perspective", "panoramic"), - ::testing::Values( - OSP_STEREO_NONE, OSP_STEREO_RIGHT, OSP_STEREO_SIDE_BY_SIDE))); + ::testing::Values(OSP_STEREO_NONE, + OSP_STEREO_RIGHT, + OSP_STEREO_LEFT, + OSP_STEREO_SIDE_BY_SIDE, + OSP_STEREO_TOP_BOTTOM), + ::testing::Values(OSP_SHUTTER_GLOBAL))); INSTANTIATE_TEST_SUITE_P(CameraOrtho, MotionCamera, - ::testing::Values(std::make_tuple("orthographic", OSP_STEREO_NONE))); + ::testing::Values( + std::make_tuple("orthographic", OSP_STEREO_NONE, OSP_SHUTTER_GLOBAL))); + +INSTANTIATE_TEST_SUITE_P(CameraStereoRollingShutter, + MotionCamera, + ::testing::Combine(::testing::Values("perspective"), + ::testing::Values(OSP_STEREO_TOP_BOTTOM), + ::testing::Values(OSP_SHUTTER_ROLLING_DOWN))); } // namespace OSPRayTestScenes diff --git a/cmake/ospray_options.cmake b/cmake/ospray_options.cmake index 2f90f5d5b9..c7cfa34e28 100644 --- a/cmake/ospray_options.cmake +++ b/cmake/ospray_options.cmake @@ -11,7 +11,7 @@ include(CMakeDependentOption) set(OSPRAY_CMAKECONFIG_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/ospray-${OSPRAY_VERSION}") -set(RKCOMMON_VERSION_REQUIRED 1.7.0) +set(RKCOMMON_VERSION_REQUIRED 1.8.0) set(EMBREE_VERSION_REQUIRED 3.13.1) set(OPENVKL_VERSION_REQUIRED 1.0.1) diff --git a/cmake/ospray_version.cmake b/cmake/ospray_version.cmake index cb1bdddf9c..1324feb790 100644 --- a/cmake/ospray_version.cmake +++ b/cmake/ospray_version.cmake @@ -2,8 +2,8 @@ ## SPDX-License-Identifier: Apache-2.0 set(OSPRAY_VERSION_MAJOR 2) -set(OSPRAY_VERSION_MINOR 7) -set(OSPRAY_VERSION_PATCH 1) +set(OSPRAY_VERSION_MINOR 8) +set(OSPRAY_VERSION_PATCH 0) set(OSPRAY_SOVERSION 2) set(OSPRAY_VERSION_GITHASH 0) set(OSPRAY_VERSION_NOTE "") diff --git a/cmake/package.cmake b/cmake/package.cmake index 910fb8d4bf..f251fb68dc 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -7,7 +7,7 @@ if (OSPRAY_ZIP_MODE) set(CMAKE_SKIP_INSTALL_RPATH OFF) if (APPLE) set(CMAKE_MACOSX_RPATH ON) - set(CMAKE_INSTALL_RPATH "@executable_path/" "@executable_path/../${CMAKE_INSTALL_LIBDIR}") + set(CMAKE_INSTALL_RPATH "@loader_path/" "@loader_path/../${CMAKE_INSTALL_LIBDIR}") else() set(CMAKE_INSTALL_RPATH "\$ORIGIN:\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") # on per target basis: diff --git a/doc/api.md b/doc/api.md index c402b47e1a..fa96bac7c7 100644 --- a/doc/api.md +++ b/doc/api.md @@ -494,6 +494,9 @@ below. OSP_AFFINE[23]F 32\ bit single precision floating-point affine transform (linear transform plus translation) + OSP_QUATF 32\ bit single precision floating-point quaternion, + in $(i, j, k, w)$ layout + OSP_VOID_PTR raw memory address (only found in module extensions) -------------------------- --------------------------------------------------- : Valid named constants for `OSPDataType`. @@ -707,10 +710,9 @@ Note that cell widths are defined _per refinement level_, not per block. `OSP_FLOAT` is supported as `OSPDataType` - vec3f gridOrigin $(0, 0, 0)$ origin of the grid in world-space + vec3f gridOrigin $(0, 0, 0)$ origin of the grid - vec3f gridSpacing $(1, 1, 1)$ size of the grid cells in - world-space + vec3f gridSpacing $(1, 1, 1)$ size of the grid cells float background `NaN` value that is used when sampling an undefined region outside the @@ -1433,7 +1435,7 @@ specific light source). OSP_INTENSITY_QUANTITY_IRRADIANCE the amount of light arriving at a surface point, assuming the light is oriented towards to the surface, unit is W/m^2^ - + OSP_INTENSITY_QUANTITY_SCALE a linear scaling factor for light sources with a built-in quantity (e.g., `HDRI`, or `sunSky`). ---------------------------------- ---------------------------------------------------- @@ -1453,11 +1455,11 @@ parameter value. In addition to the [general parameters](#lights) understood by all lights the distant light supports the following special parameters: - Type Name Description - --------- ---------------- --------------------------------------------- - vec3f direction main emission direction of the distant light - float angularDiameter apparent size (angle in degree) of the light - --------- ---------------- --------------------------------------------- + Type Name Default Description + --------- ---------------- ------------ --------------------------------------------- + vec3f direction $(0, 0, 1)$ main emission direction of the distant light + float angularDiameter 0 apparent size (angle in degree) of the light + --------- ---------------- ------------ --------------------------------------------- : Special parameters accepted by the distant light. Setting the angular diameter to a value greater than zero will result in @@ -1476,11 +1478,11 @@ supports `OSP_INTENSITY_QUANTITY_POWER`, In addition to the [general parameters](#lights) understood by all lights the sphere light supports the following special parameters: - Type Name Description - --------- --------- ----------------------------------------------- - vec3f position the center of the sphere light, in world-space - float radius the size of the sphere light - --------- --------- ----------------------------------------------- + Type Name Default Description + ------- ---------- ------------ -------------------------------- + vec3f position $(0, 0, 0)$ the center of the sphere light + float radius 0 the size of the sphere light + ------- ---------- ------------ -------------------------------- : Special parameters accepted by the sphere light. Setting the radius to a value greater than zero will result in soft @@ -1501,8 +1503,7 @@ table. ---------- --------------------- ----------- --------------------------------- Type Name Default Description ---------- --------------------- ----------- --------------------------------- - vec3f position $(0, 0, 0)$ the center of the spotlight, in - world-space + vec3f position $(0, 0, 0)$ the center of the spotlight vec3f direction $(0, 0, 1)$ main emission direction of the spot @@ -1576,12 +1577,12 @@ light supports `OSP_INTENSITY_QUANTITY_POWER`, parameters](#lights) understood by all lights the quad light supports the following special parameters: - Type Name Description - ------ --------- ----------------------------------------------------- - vec3f position world-space position of one vertex of the quad light - vec3f edge1 vector to one adjacent vertex - vec3f edge2 vector to the other adjacent vertex - ------ --------- ----------------------------------------------------- + Type Name Default Description + ------ --------- ------------ ----------------------------------------- + vec3f position $(0, 0, 0)$ position of one vertex of the quad light + vec3f edge1 $(1, 0, 0)$ vector to one adjacent vertex + vec3f edge2 $(0, 1, 0)$ vector to the other adjacent vertex + ------ --------- ------------ ----------------------------------------- : Special parameters accepted by the quad light. ![Defining a quad light which emits toward the reader.][imgQuadLight] @@ -1592,6 +1593,30 @@ tracer) will compute soft shadows from the quad light. Other renderers will just sample the center of the quad light, which results in hard shadows. +### Cylinder Light + +The cylinder light is a cylinderical, procedural area light source +emitting uniformly outwardly into the space beyond the boundary. It is +created by passing the type string "`cylinder`" to `ospNewLight`. The +cylinder light supports `OSP_INTENSITY_QUANTITY_POWER`, +`OSP_INTENSITY_QUANTITY_INTENSITY` and `OSP_INTENSITY_QUANTITY_RADIANCE` +(default) as `intensityQuantity` parameter. In addition to the [general +parameters](#lights) understood by all lights the cylinder light supports +the following special parameters: + + Type Name Default Description + ------- ----------- ------------ -------------------------------------- + vec3f position0 $(0, 0, 0)$ position of the start of the cylinder + vec3f position1 $(0, 0, 1)$ position of the end of the cylinder + float radius 1 radius of the cylinder + ------- ----------- ------------ -------------------------------------- + : Special parameters accepted by the cylinder light. + +Note that only renderers that use stochastic sampling (like the path +tracer) will compute soft shadows from the cylinder light. Other renderers +will just sample the closest point on the cylinder light, which results in +hard shadows. + ### HDRI Light The HDRI light is a textured light source surrounding the scene and @@ -1602,16 +1627,16 @@ as `intensityQuantity` parameter value. In addition to the [general parameters](#lights) the HDRI light supports the following special parameters: - ------------ --------- -------------------------------------------------- - Type Name Description - ------------ --------- -------------------------------------------------- - vec3f up up direction of the light in world-space + ------------ --------- ------------ -------------------------------------------------- + Type Name Default Description + ------------ --------- ------------ -------------------------------------------------- + vec3f up $(0, 1, 0)$ up direction of the light - vec3f direction direction to which the center of the texture will - be mapped to (analog to [panoramic camera]) + vec3f direction $(0, 0, 1)$ direction to which the center of the texture will + be mapped to (analog to [panoramic camera]) - OSPTexture map environment map in latitude / longitude format - ------------ --------- -------------------------------------------------- + OSPTexture map environment map in latitude / longitude format + ------------ --------- ------------ -------------------------------------------------- : Special parameters accepted by the HDRI light. ![Orientation and Mapping of an HDRI Light.][imgHDRILight] @@ -1651,7 +1676,7 @@ following special parameters are supported: --------- ---------------- ------------ ------------------------------------- Type Name Default Description --------- ---------------- ------------ ------------------------------------- - vec3f up $(0, 1, 0)$ zenith of sky in world-space + vec3f up $(0, 1, 0)$ zenith of sky vec3f direction $(0, -1, 0)$ main emission direction of the sun @@ -1683,16 +1708,16 @@ Scene Hierarchy ### Groups -Groups in OSPRay represent collections of GeometricModels and -VolumetricModels which share a common local-space coordinate system. To +Groups in OSPRay represent collections of GeometricModels, VolumetricModels +and Lights which share a common local-space coordinate system. To create a group call OSPGroup ospNewGroup(); -Groups take arrays of geometric models, volumetric models and clipping -geometric models, but they are optional. In other words, there is no -need to create empty arrays if there are no geometries or volumes in the -group. +Groups take arrays of geometric models, volumetric models, clipping +geometric models and lights, but they are all optional. In other words, +there is no need to create empty arrays if there are no geometries, volumes +or lights in the group. By adding `OSPGeometricModel`s to the `clippingGeometry` array a clipping geometry feature is enabled. Geometries assigned to this @@ -1718,6 +1743,8 @@ areas will be applied to all other objects in the [world]. OSPGeometricModel[] clippingGeometry NULL [data] array of [GeometricModels] used for clipping + OSPLight[] light NULL [data] array of [lights] + bool dynamicScene false use RTC_SCENE_DYNAMIC flag (faster BVH build, slower ray traversal), otherwise uses RTC_SCENE_STATIC flag @@ -1734,10 +1761,6 @@ areas will be applied to all other objects in the [world]. -------------------- ---------------- ---------- --------------------------------------- : Parameters understood by groups. -Note that groups only need to re re-committed if a geometry or volume -changes (surface/scalar field representation). Appearance information -on `OSPGeometricModel` and `OSPVolumetricModel` can be changed freely, -as internal acceleration structures do not need to be reconstructed. ### Instances @@ -1750,12 +1773,25 @@ via a transform. To create and instance call Type Name Default Description ------------ ----------------- ---------- -------------------------------------------------------- affine3f transform identity world-space transform for all attached geometries and - volumes, overridden by `motion.transform` + volumes, overridden by `motion.*` arrays affine3f[] motion.transform uniformly distributed world-space transforms - box1f time [0, 1] time associated with first and last key in - `motion.` arrays (for motion blur) + vec3f[] motion.scale uniformly distributed world-space scale, overridden + by `motion.transform` + + vec3f[] motion.pivot uniformly distributed world-space translation which is + applied before `motion.rotation` (i.e., the rotation + center), overridden by `motion.transform` + + quatf[] motion.rotation uniformly distributed world-space quaternion rotation, + overridden by `motion.transform` + + vec3f[] motion.translation uniformly distributed world-space translation, + overridden by `motion.transform` + + box1f time [0, 1] time associated with first and last key in `motion.*` + arrays (for motion blur) ------------ ----------------- ---------- -------------------------------------------------------- : Parameters understood by instances. @@ -2522,13 +2558,13 @@ different transfer function than that of the sliced volume. All materials with textures also offer to manipulate the placement of these textures with the help of texture transformations. If so, this convention shall be used: the following parameters are prefixed with -"`texture_name.`"). +"`texture_name.*`"). Type Name Description --------- ------------ ------------------------------------------------- linear2f transform linear transformation (rotation, scale) float rotation angle in degree, counterclockwise, around center - vec2f scale enlarge texture, relative to center (0.5, 0.5) + vec2f scale enlarge texture, relative to center $(0.5, 0.5)$ vec2f translation move texture in positive direction (right/up) --------- ------------ ------------------------------------------------- : Parameters to define 2D texture coordinate transformations. @@ -2556,19 +2592,63 @@ To create a new camera of given type `type` use All cameras accept these parameters: - Type Name Description - ----------- ----------------- ------------------------------------------ - vec3f position position of the camera in world-space - vec3f direction main viewing direction of the camera - vec3f up up direction of the camera - affine3f transform additional world-space transform, overridden by `motion.transform` - float nearClip near clipping distance - vec2f imageStart start of image region (lower left corner) - vec2f imageEnd end of image region (upper right corner) - affine3f[] motion.transform additional uniformly distributed world-space transforms - box1f time time associated with first and last key in `motion.` arrays, default [0, 1] - box1f shutter start and end of shutter time (for motion blur), default [0.5, 0.5] - ------ ----------- ------------------------------------------ + ----------- ----------------------- --------------------- ------------------------------------------ + Type Name Default Description + ----------- ----------------------- --------------------- ------------------------------------------ + vec3f position $(0, 0, 0)$ position of the camera + + vec3f direction $(0, 0, 1)$ main viewing direction of the camera + + vec3f up $(0, 1, 0)$ up direction of the camera + + affine3f transform identity additional world-space transform, overridden + by `motion.*` arrays + + float nearClip 10^-6^ near clipping distance + + vec2f imageStart $(0, 0)$ start of image region (lower left corner) + + vec2f imageEnd $(1, 1)$ end of image region (upper right corner) + + affine3f[] motion.transform additional uniformly distributed world-space + transforms + + vec3f[] motion.scale additional uniformly distributed world-space + scale, overridden by `motion.transform` + + vec3f[] motion.pivot additional uniformly distributed world-space + translation which is applied before + `motion.rotation` (i.e., the rotation + center), overridden by `motion.transform` + + quatf[] motion.rotation additional uniformly distributed world-space + quaternion rotation, overridden by + `motion.transform` + + vec3f[] motion.translation additional uniformly distributed world-space + translation, overridden by `motion.transform` + + box1f time [0, 1] time associated with first and last key in + `motion.*` arrays + + box1f shutter [0.5, 0.5] start and end of shutter time (for motion + blur), in [0, 1] + + uchar shutterType `OSP_SHUTTER_GLOBAL` `OSPShutterType` for motion blur, also + allowed are: + + `OSP_SHUTTER_ROLLING_RIGHT` + + `OSP_SHUTTER_ROLLING_LEFT` + + `OSP_SHUTTER_ROLLING_DOWN` + + `OSP_SHUTTER_ROLLING_UP` + + float rollingShutterDuration 0 for a rolling shutter (see `shutterType`) + the "open" time per line, in [0, + `shutter`.upper-`shutter`.lower] + ----------- ----------------------- --------------------- ------------------------------------------ : Parameters accepted by all cameras. The camera is placed and oriented in the world with `position`, @@ -2598,40 +2678,38 @@ string "`perspective`" to `ospNewCamera`. In addition to the [general parameters](#cameras) understood by all cameras the perspective camera supports the special parameters listed in the table below. - ----- ---------------------- ----------------------------------------- - Type Name Description - ----- ---------------------- ----------------------------------------- - float fovy the field of view (angle in degree) of - the frame's height - - float aspect ratio of width by height of the frame - (and image region) + ----- ----------------------- ----------------- ----------------------------------------- + Type Name Default Description + ----- ----------------------- ----------------- ----------------------------------------- + float fovy 60 the field of view (angle in degree) of + the frame's height - float apertureRadius size of the aperture, controls the depth - of field + float aspect 1 ratio of width by height of the frame + (and image region) - float focusDistance distance at where the image is sharpest - when depth of field is enabled + float apertureRadius 0 size of the aperture, controls the depth + of field - bool architectural vertical edges are projected to be - parallel + float focusDistance 1 distance at where the image is sharpest + when depth of field is enabled - uchar stereoMode `OSPStereoMode` for stereo rendering, - possible values are: + bool architectural false vertical edges are projected to be + parallel - `OSP_STEREO_NONE` (default) + uchar stereoMode `OSP_STEREO_NONE` `OSPStereoMode` for stereo rendering, + also allowed are: - `OSP_STEREO_LEFT` + `OSP_STEREO_LEFT` - `OSP_STEREO_RIGHT` + `OSP_STEREO_RIGHT` - `OSP_STEREO_SIDE_BY_SIDE` + `OSP_STEREO_SIDE_BY_SIDE` - `OSP_STEREO_TOP_BOTTOM` (left eye at top half) + `OSP_STEREO_TOP_BOTTOM` (left eye at top half) - float interpupillaryDistance distance between left and right eye when - stereo is enabled, default 0.0635 - ----- ---------------------- ----------------------------------------- + float interpupillaryDistance 0.0635 distance between left and right eye when + stereo is enabled + ----- ----------------------- ----------------- ----------------------------------------- : Additional parameters accepted by the perspective camera. Note that when computing the `aspect` ratio a potentially set image region @@ -2869,27 +2947,27 @@ Color Encoding System (ACES). The tone mapper is created by passing the type string "`tonemapper`" to `ospNewImageOperation`. The tone mapping curve can be customized using the parameters listed in the table below. - ----- --------- -------- ----------------------------------------- - Type Name Default Description - ----- --------- -------- ----------------------------------------- - float exposure 1.0 amount of light per unit area + ------ ---------- --------- ----------------------------------------- + Type Name Default Description + ------ ---------- --------- ----------------------------------------- + float exposure 1.0 amount of light per unit area - float contrast 1.6773 contrast (toe of the curve); typically is + float contrast 1.6773 contrast (toe of the curve); typically is in [1–2] - float shoulder 0.9714 highlight compression (shoulder of the + float shoulder 0.9714 highlight compression (shoulder of the curve); typically is in [0.9–1] - float midIn 0.18 mid-level anchor input; default is 18% + float midIn 0.18 mid-level anchor input; default is 18% gray - float midOut 0.18 mid-level anchor output; default is 18% + float midOut 0.18 mid-level anchor output; default is 18% gray - float hdrMax 11.0785 maximum HDR input that is not clipped + float hdrMax 11.0785 maximum HDR input that is not clipped - bool acesColor true apply the ACES color transforms - ----- --------- -------- ----------------------------------------- + bool acesColor true apply the ACES color transforms + ------ ---------- --------- ----------------------------------------- : Parameters accepted by the tone mapper. To use the popular "Uncharted 2" filmic tone mapping curve instead, set the @@ -3189,7 +3267,7 @@ shipping data out to the workers. When a parallel file system is available, this can improve data load times. Image-parallel rendering is selected by specifying the same data on each rank, and using any of the existing local renderers (e.g., `scivis`, `pathtracer`). See -[ospMPIDistributedTutorialReplicatedData](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistributedTutorialReplicatedData.cpp) +[ospMPIDistribTutorialReplicated](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorialReplicated.cpp) for an example. ### Data Parallel Rendering in the MPI Distributed Device @@ -3210,7 +3288,7 @@ regions out a set of regions (the `region` parameter) can pass as a parameter to the `OSPWorld` being rendered. Each rank can specify one or more non-overlapping `box3f`'s which bound the portions of its local data which it is responsible for rendering. See the -[ospMPIDistributedTutorialStructuredVolume](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistributedTutorialStructuredVolume.cpp) +[ospMPIDistribTutorialVolume](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorialVolume.cpp) for an example. Finally, the MPI distributed device also supports hybrid-parallel @@ -3219,7 +3297,7 @@ each shared piece of data the rendering work will be assigned image-parallel among the ranks. Partially-shared regions are determined by finding those ranks specifying data with the same bounds (matching regions) and merging them. See the -[ospMPIDistributedTutorialPartiallyReplicatedData](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistributedTutorialPartiallyReplicatedData.cpp) +[ospMPIDistribTutorialPartialRepl](https://github.com/ospray/ospray/blob/master/modules/mpi/tutorials/ospMPIDistribTutorialPartialRepl.cpp) for an example. #### Picking on Distributed Data in the MPI Distributed Device {-} diff --git a/doc/ospray-doc b/doc/ospray-doc index e3eefe47b8..00a81c08f7 160000 --- a/doc/ospray-doc +++ b/doc/ospray-doc @@ -1 +1 @@ -Subproject commit e3eefe47b89aa0cdcb0eb853e68a3f6277d6297d +Subproject commit 00a81c08f722cf890bc37e5588fbc1058cd3819e diff --git a/modules/mpi/CMakeLists.txt b/modules/mpi/CMakeLists.txt index e077741b95..53c732d2be 100644 --- a/modules/mpi/CMakeLists.txt +++ b/modules/mpi/CMakeLists.txt @@ -49,3 +49,6 @@ if (OSPRAY_MPI_BUILD_TUTORIALS) add_subdirectory(tutorials) endif() +if (OSPRAY_APPS_TESTING) + add_subdirectory(testing) +endif() diff --git a/modules/mpi/ospray/common/DistributedWorld.cpp b/modules/mpi/ospray/common/DistributedWorld.cpp index 4dfb2a4743..c6568d5156 100644 --- a/modules/mpi/ospray/common/DistributedWorld.cpp +++ b/modules/mpi/ospray/common/DistributedWorld.cpp @@ -19,7 +19,7 @@ using namespace rkcommon; DistributedWorld::DistributedWorld() : mpiGroup(mpicommon::worker.dup()) { managedObjectType = OSP_WORLD; - this->ispcEquivalent = ispc::DistributedWorld_create(this); + this->ispcEquivalent = ispc::DistributedWorld_create(); } DistributedWorld::~DistributedWorld() @@ -95,7 +95,7 @@ void DistributedWorld::commit() if (allRegions.size() > 0) { // Setup the boxes geometry which we'll use to leverage Embree for // accurately determining region visibility - Data* allRegionsData = new Data(allRegions.data(), + Data *allRegionsData = new Data(allRegions.data(), OSP_BOX3F, vec3ul(allRegions.size(), 1, 1), vec3l(0)); @@ -205,4 +205,3 @@ void DistributedWorld::exchangeRegions() } // namespace mpi } // namespace ospray - diff --git a/modules/mpi/ospray/common/DistributedWorld.ispc b/modules/mpi/ospray/common/DistributedWorld.ispc index c78eedf2c2..5b5fcb77d8 100644 --- a/modules/mpi/ospray/common/DistributedWorld.ispc +++ b/modules/mpi/ospray/common/DistributedWorld.ispc @@ -4,10 +4,10 @@ #include "DistributedWorld.ih" #include "common/World.ih" -export void *uniform DistributedWorld_create(void *uniform cppE) +export void *uniform DistributedWorld_create() { DistributedWorld *uniform world = uniform new DistributedWorld; - World_Constructor(&world->super, cppE); + World_Constructor(&world->super); return (void *uniform)world; } diff --git a/modules/mpi/ospray/fb/DistributedFrameBuffer.cpp b/modules/mpi/ospray/fb/DistributedFrameBuffer.cpp index 6934af7f09..c9ffaa273b 100644 --- a/modules/mpi/ospray/fb/DistributedFrameBuffer.cpp +++ b/modules/mpi/ospray/fb/DistributedFrameBuffer.cpp @@ -59,7 +59,7 @@ DFB::DistributedFrameBuffer(const vec2i &numPixels, frameIsActive(false), frameIsDone(false) { - this->ispcEquivalent = ispc::DFB_create(this); + this->ispcEquivalent = ispc::DFB_create(); ispc::DFB_set(getIE(), numPixels.x, numPixels.y, colorBufferFormat); // TODO: accumID is eventually only needed on master once static diff --git a/modules/mpi/ospray/fb/DistributedFrameBuffer.ispc b/modules/mpi/ospray/fb/DistributedFrameBuffer.ispc index 508aec3c31..3f6aef8597 100644 --- a/modules/mpi/ospray/fb/DistributedFrameBuffer.ispc +++ b/modules/mpi/ospray/fb/DistributedFrameBuffer.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "fb/FrameBuffer.ih" @@ -230,11 +230,11 @@ export void DFB_zComposite( } } -export void *uniform DFB_create(void *uniform cClassPtr) +export void *uniform DFB_create() { DistributedFrameBuffer *uniform self = uniform new uniform DistributedFrameBuffer; - FrameBuffer_Constructor(&self->super, cClassPtr); + FrameBuffer_Constructor(&self->super); return self; } diff --git a/modules/mpi/ospray/render/distributed/DistributedRaycast.cpp b/modules/mpi/ospray/render/distributed/DistributedRaycast.cpp index f5798e3b7a..90562dcbb1 100644 --- a/modules/mpi/ospray/render/distributed/DistributedRaycast.cpp +++ b/modules/mpi/ospray/render/distributed/DistributedRaycast.cpp @@ -32,7 +32,7 @@ static bool DETAILED_LOGGING = false; DistributedRaycastRenderer::DistributedRaycastRenderer() : mpiGroup(mpicommon::worker.dup()) { - ispcEquivalent = ispc::DistributedRaycastRenderer_create(this); + ispcEquivalent = ispc::DistributedRaycastRenderer_create(); DETAILED_LOGGING = utility::getEnvVar("OSPRAY_DP_API_TRACING").value_or(0); diff --git a/modules/mpi/ospray/render/distributed/DistributedRaycast.ispc b/modules/mpi/ospray/render/distributed/DistributedRaycast.ispc index a2582100ae..60f26069a6 100644 --- a/modules/mpi/ospray/render/distributed/DistributedRaycast.ispc +++ b/modules/mpi/ospray/render/distributed/DistributedRaycast.ispc @@ -345,12 +345,12 @@ void DRR_renderRegionSample(DistributedRenderer *uniform _self, // Exported functions ///////////////////////////////////////////////////////// -export void *uniform DistributedRaycastRenderer_create(void *uniform cppE) +export void *uniform DistributedRaycastRenderer_create() { DistributedRaycastRenderer *uniform self = uniform new uniform DistributedRaycastRenderer; - DistributedRenderer_Constructor(&self->super, cppE); + DistributedRenderer_Constructor(&self->super); self->super.renderRegionSample = DRR_renderRegionSample; self->aoSamples = 0; self->shadowsEnabled = false; diff --git a/modules/mpi/ospray/render/distributed/DistributedRenderer.cpp b/modules/mpi/ospray/render/distributed/DistributedRenderer.cpp index b6adad6104..53c524bdf7 100644 --- a/modules/mpi/ospray/render/distributed/DistributedRenderer.cpp +++ b/modules/mpi/ospray/render/distributed/DistributedRenderer.cpp @@ -3,6 +3,7 @@ #include "DistributedRenderer.h" #include "render/distributed/DistributedRenderer_ispc.h" +#include "geometry/GeometricModel.h" namespace ospray { namespace mpi { diff --git a/modules/mpi/ospray/render/distributed/DistributedRenderer.ih b/modules/mpi/ospray/render/distributed/DistributedRenderer.ih index c61a91fcce..03d5ee3792 100644 --- a/modules/mpi/ospray/render/distributed/DistributedRenderer.ih +++ b/modules/mpi/ospray/render/distributed/DistributedRenderer.ih @@ -48,5 +48,4 @@ struct DistributedRenderer DR_RenderRegionTileFct renderRegionToTile; }; -void DistributedRenderer_Constructor( - uniform DistributedRenderer *uniform self, void *uniform cppE); +void DistributedRenderer_Constructor(uniform DistributedRenderer *uniform self); diff --git a/modules/mpi/ospray/render/distributed/DistributedRenderer.ispc b/modules/mpi/ospray/render/distributed/DistributedRenderer.ispc index afd166e352..bdb4a8c275 100644 --- a/modules/mpi/ospray/render/distributed/DistributedRenderer.ispc +++ b/modules/mpi/ospray/render/distributed/DistributedRenderer.ispc @@ -239,10 +239,9 @@ unmasked void DR_default_renderRegionToTile(DistributedRenderer *uniform self, } } -void DistributedRenderer_Constructor( - uniform DistributedRenderer *uniform self, void *uniform cppE) +void DistributedRenderer_Constructor(uniform DistributedRenderer *uniform self) { - Renderer_Constructor(&self->super, cppE); + Renderer_Constructor(&self->super); self->computeRegionVisibility = DR_default_computeRegionVisibility; self->renderRegionSample = DR_default_renderRegionSample; diff --git a/modules/mpi/testing/CMakeLists.txt b/modules/mpi/testing/CMakeLists.txt new file mode 100644 index 0000000000..7fce91d982 --- /dev/null +++ b/modules/mpi/testing/CMakeLists.txt @@ -0,0 +1,26 @@ +## Copyright 2021 Intel Corporation +## SPDX-License-Identifier: Apache-2.0 + +ospray_disable_compiler_warnings() + +add_executable(ospMPIDistribTestSuite + ${OSPRAY_RESOURCE} + distributed_test_fixture.cpp + ospMPIDistribTestSuite.cpp +) + +target_link_libraries(ospMPIDistribTestSuite +PRIVATE + arcball_camera + ospray_testing + ospray_module_ispc + ospray_gtest_utils + MPI::MPI_CXX +) + +ospray_sign_target(ospMPIDistribTestSuite) + +install(TARGETS ospMPIDistribTestSuite + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT apps +) diff --git a/modules/mpi/testing/distributed_test_fixture.cpp b/modules/mpi/testing/distributed_test_fixture.cpp new file mode 100644 index 0000000000..aee9e7164e --- /dev/null +++ b/modules/mpi/testing/distributed_test_fixture.cpp @@ -0,0 +1,146 @@ +// Copyright 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "distributed_test_fixture.h" +#include +#include "ArcballCamera.h" +#include "ospray_testing.h" + +extern OSPRayEnvironment *ospEnv; + +namespace MPIDistribOSPRayTestScenes { + +bool computeDivisor(int x, int &divisor) +{ + int upperBound = std::sqrt(x); + for (int i = 2; i <= upperBound; ++i) { + if (x % i == 0) { + divisor = i; + return true; + } + } + return false; +} + +// Compute an X x Y x Z grid to have 'num' grid cells, +// only gives a nice grid for numbers with even factors since +// we don't search for factors of the number, we just try dividing by two +vec3i computeGrid(int num) +{ + vec3i grid(1); + int axis = 0; + int divisor = 0; + while (computeDivisor(num, divisor)) { + grid[axis] *= divisor; + num /= divisor; + axis = (axis + 1) % 3; + } + if (num != 1) { + grid[axis] *= num; + } + return grid; +} + +MPIDistribBase::MPIDistribBase() +{ + MPI_Comm_size(MPI_COMM_WORLD, &mpiSize); + MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank); + + rankGridDims = computeGrid(mpiSize); + rankBrickId = vec3i(mpiRank % rankGridDims.x, + (mpiRank / rankGridDims.x) % rankGridDims.y, + mpiRank / (rankGridDims.x * rankGridDims.y)); +} + +void MPIDistribBase::AddInstance(cpp::Instance instance) +{ + worldBounds.extend(instance.getBounds()); + Base::AddInstance(instance); +} + +void MPIDistribBase::PerformRenderTest() +{ + SetLights(); + + if (!instances.empty()) { + world.setParam("instance", cpp::CopiedData(instances)); + + // Determine the bounds of this rank's region in world space + const vec3f regionDims = worldBounds.size() / vec3f(rankGridDims); + box3f localRegion(rankBrickId * regionDims + worldBounds.lower, + rankBrickId * regionDims + regionDims + worldBounds.lower); + + // Special case for the ospray test data: we might have geometry right at + // the region bounding box which will z-fight with the clipping region. If + // we have a region at the edge of the domain, apply some padding + for (int i = 0; i < 3; ++i) { + if (localRegion.lower[i] == worldBounds.lower[i]) { + localRegion.lower[i] -= 0.001; + } + if (localRegion.upper[i] == worldBounds.upper[i]) { + localRegion.upper[i] += 0.001; + } + } + + world.setParam("region", cpp::CopiedData(localRegion)); + } + + camera.commit(); + world.commit(); + renderer.commit(); + + framebuffer.resetAccumulation(); + + RenderFrame(); + + if (mpiRank == 0) { + auto *framebuffer_data = (uint32_t *)framebuffer.map(OSP_FB_COLOR); + + if (ospEnv->GetDumpImg()) { + EXPECT_EQ(imageTool->saveTestImage(framebuffer_data), OsprayStatus::Ok); + } else { + EXPECT_EQ(imageTool->compareImgWithBaseline(framebuffer_data), + OsprayStatus::Ok); + } + + framebuffer.unmap(framebuffer_data); + } +} + +MPIFromOsprayTesting::MPIFromOsprayTesting() +{ + auto params = GetParam(); + + sceneName = std::get<0>(params); + rendererType = "mpiRaycast"; + samplesPerPixel = std::get<1>(params); +} + +void MPIFromOsprayTesting::SetUp() +{ + MPIDistribBase::SetUp(); + + instances.clear(); + + auto builder = ospray::testing::newBuilder(sceneName); + ospray::testing::setParam(builder, "rendererType", rendererType); + ospray::testing::commit(builder); + + // Build the group to get the bounds + auto group = ospray::testing::buildGroup(builder); + worldBounds = group.getBounds(); + + cpp::Instance instance(group); + instance.commit(); + instances.push_back(instance); + + ospray::testing::release(builder); + + ArcballCamera arcballCamera(worldBounds, imgSize); + + camera.setParam("position", arcballCamera.eyePos()); + camera.setParam("direction", arcballCamera.lookDir()); + camera.setParam("up", arcballCamera.upDir()); +} + +} // namespace MPIDistribOSPRayTestScenes diff --git a/modules/mpi/testing/distributed_test_fixture.h b/modules/mpi/testing/distributed_test_fixture.h new file mode 100644 index 0000000000..2c7cd4ac25 --- /dev/null +++ b/modules/mpi/testing/distributed_test_fixture.h @@ -0,0 +1,45 @@ +// Copyright 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "test_fixture.h" + +namespace MPIDistribOSPRayTestScenes { + +// Base class for all distributed test fixtures +// The base class assumes the data is partitioned in a 3D +// grid with each rank assigned a cell in this grid that it owns. +// The base class will set the world region parameter to match this +class MPIDistribBase : public OSPRayTestScenes::Base +{ + public: + MPIDistribBase(); + + // We override these to get the bounds of objects as they're added + // so we can set the regions parameter on the world. + virtual void AddInstance(cpp::Instance instance) override; + + virtual void PerformRenderTest(); + + protected: + int mpiRank; + int mpiSize; + vec3i rankGridDims; + vec3i rankBrickId; + box3f worldBounds; +}; + +// Fixture class used for tests that uses 'ospray_testing' scenes +class MPIFromOsprayTesting + : public MPIDistribBase, + public ::testing::TestWithParam< + std::tuple> +{ + public: + MPIFromOsprayTesting(); + void SetUp() override; + + protected: + std::string sceneName; +}; + +} // namespace MPIDistribOSPRayTestScenes diff --git a/modules/mpi/testing/ospMPIDistribTestSuite.cpp b/modules/mpi/testing/ospMPIDistribTestSuite.cpp new file mode 100644 index 0000000000..3dd6368a00 --- /dev/null +++ b/modules/mpi/testing/ospMPIDistribTestSuite.cpp @@ -0,0 +1,72 @@ +// Copyright 2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include +#include "distributed_test_fixture.h" + +extern OSPRayEnvironment *ospEnv; +OSPRayEnvironment *ospEnv; + +namespace MPIDistribOSPRayTestScenes { +TEST_P(MPIFromOsprayTesting, test_scenes) +{ + PerformRenderTest(); +} + +INSTANTIATE_TEST_SUITE_P(MPIDistribTestScenesVolumes, + MPIFromOsprayTesting, + ::testing::Combine( + ::testing::Values( + "gravity_spheres_isosurface", "vdb_volume", "particle_volume"), + ::testing::Values(1))); + +INSTANTIATE_TEST_SUITE_P(MPIDistribTestScenesGeometry, + MPIFromOsprayTesting, + ::testing::Combine(::testing::Values("planes", "boxes", "random_spheres"), + ::testing::Values(1))); +} // namespace MPIDistribOSPRayTestScenes + +int main(int argc, char **argv) +{ + int mpiThreadCapability = 0; + MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &mpiThreadCapability); + if (mpiThreadCapability != MPI_THREAD_MULTIPLE + && mpiThreadCapability != MPI_THREAD_SERIALIZED) { + fprintf(stderr, + "OSPRay requires the MPI runtime to support thread " + "multiple or thread serialized.\n"); + return 1; + } + + int result = 0; + ospLoadModule("mpi"); + { + cpp::Device device("mpiDistributed"); + + device.setErrorCallback( + [](void *, OSPError error, const char *errorDetails) { + std::cerr << "OSPRay error: " << errorDetails << std::endl; + std::exit(EXIT_FAILURE); + }); + + device.setStatusCallback([](void *, const char *msg) { std::cout << msg; }); + + // First commit with INFO log Level to output device info string + device.setParam("warnAsError", true); + device.setParam("logLevel", OSP_LOG_INFO); + device.commit(); + + // Then use WARNING log level for tests execution + device.setParam("logLevel", OSP_LOG_WARNING); + device.commit(); + device.setCurrent(); + + ::testing::InitGoogleTest(&argc, argv); + ospEnv = new OSPRayEnvironment(argc, argv); + AddGlobalTestEnvironment(ospEnv); + result = RUN_ALL_TESTS(); + } + ospShutdown(); + MPI_Finalize(); + return result; +} diff --git a/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.cpp b/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.cpp index a84c53a22b..9846cd239e 100644 --- a/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.cpp +++ b/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.cpp @@ -23,7 +23,7 @@ BilinearPatches::BilinearPatches() /*! create the 'ispc equivalent': ie, the ispc-side class that implements all the ispc-side code for intersection, postintersect, etc. See BilinearPatches.ispc */ - ispcEquivalent = ispc::BilinearPatches_create(this); + ispcEquivalent = ispc::BilinearPatches_create(); } /*! commit - this is the function that parses all the parameters diff --git a/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.ispc b/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.ispc index 02b52f7326..2f80de6244 100644 --- a/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.ispc +++ b/modules/pluggableGeometryExample/ospray/geometry/BilinearPatches.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray @@ -36,13 +36,11 @@ static void BilinearPatches_postIntersect(const Geometry *uniform geometry, dg.Ng = dg.Ns = normalize(ray.Ng); } -/*! create a new ispc equivalent for the C++ class (cppEquivalent - points back, if we ever need this. this returns a void * that the - c++ side can use to call back to us when needed. Note this return - values _has_ to be a untyped 'void*' because ISPC cannot currently - export 'real' class types - with function pointers etcpp - to a c - header file */ -export void *uniform BilinearPatches_create(void *uniform cppEquivalent) +/*! create a new ispc equivalent for the C++ class (this returns a void * that + the c++ side can use to call back to us when needed. Note this return values + _has_ to be a untyped 'void*' because ISPC cannot currently export 'real' + class types - with function pointers etcpp - to a c header file */ +export void *uniform BilinearPatches_create() { BilinearPatches *uniform self = uniform new uniform BilinearPatches; @@ -51,8 +49,7 @@ export void *uniform BilinearPatches_create(void *uniform cppEquivalent) do not have to set the 'intersect' and 'occluded' functions because we use embree to do the traversal for us (see BilinearPatches_set()) below */ - Geometry_Constructor( - &self->super, cppEquivalent, BilinearPatches_postIntersect); + Geometry_Constructor(&self->super, BilinearPatches_postIntersect); return self; } diff --git a/ospray/CMakeLists.txt b/ospray/CMakeLists.txt index d90fb07978..6b7ea27f3f 100644 --- a/ospray/CMakeLists.txt +++ b/ospray/CMakeLists.txt @@ -130,6 +130,8 @@ set(OSPRAY_ISPC_DEVICE_SOURCES lights/SpotLight.ispc lights/QuadLight.cpp lights/QuadLight.ispc + lights/CylinderLight.cpp + lights/CylinderLight.ispc lights/HDRILight.cpp lights/HDRILight.ispc lights/SunSkyLight.cpp diff --git a/ospray/camera/Camera.cpp b/ospray/camera/Camera.cpp index e20d034e2a..791d44eca0 100644 --- a/ospray/camera/Camera.cpp +++ b/ospray/camera/Camera.cpp @@ -43,7 +43,7 @@ box3f Camera::projectBox(const box3f &) const void Camera::commit() { - MotionTransform::commit(); + motionTransform.readParams(*this); // "parse" the general expected parameters pos = getParam("position", vec3f(0.f)); @@ -57,37 +57,44 @@ void Camera::commit() clamp(shutter.upper); if (shutter.lower > shutter.upper) shutter.lower = shutter.upper; + shutterType = + (OSPShutterType)getParam("shutterType", OSP_SHUTTER_GLOBAL); + rollingShutterDuration = clamp( + getParam("rollingShutterDuration", 0.0f), 0.0f, shutter.size()); - affine3f single_xfm = (*motionTransforms)[0]; - if (motionBlur) { // create dummy RTCGeometry for transform interpolation + if (motionTransform.motionBlur || motionTransform.quaternion) { + // create dummy RTCGeometry for transform interpolation or conversion if (!embreeGeometry) embreeGeometry = rtcNewGeometry(embreeDevice, RTC_GEOMETRY_TYPE_INSTANCE); - auto &xfm = *motionTransforms; - rtcSetGeometryTimeStepCount(embreeGeometry, xfm.size()); - for (size_t i = 0; i < xfm.size(); i++) - rtcSetGeometryTransform( - embreeGeometry, i, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &xfm[i]); - rtcSetGeometryTimeRange(embreeGeometry, time.lower, time.upper); - rtcCommitGeometry(embreeGeometry); + motionTransform.setEmbreeTransform(embreeGeometry); - if (shutter.lower == shutter.upper) { + if (shutter.lower == shutter.upper || !motionTransform.motionBlur) { // directly interpolate to single shutter time rtcGetGeometryTransform(embreeGeometry, shutter.lower, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, - &single_xfm); - motionBlur = false; + &motionTransform.transform); + motionTransform.motionBlur = false; } - } else if (embreeGeometry) { - rtcReleaseGeometry(embreeGeometry); - embreeGeometry = nullptr; } - if (!motionBlur) { // apply transform right away - pos = xfmPoint(single_xfm, pos); - dir = normalize(xfmVector(single_xfm, dir)); - up = normalize(xfmVector(single_xfm, up)); + if (!motionTransform.motionBlur) { + if (embreeGeometry) { + rtcReleaseGeometry(embreeGeometry); + embreeGeometry = nullptr; + } + // apply transform right away + pos = xfmPoint(motionTransform.transform, pos); + dir = normalize(xfmVector(motionTransform.transform, dir)); + up = normalize(xfmVector(motionTransform.transform, up)); + } + + if (shutterType != OSP_SHUTTER_GLOBAL) { // rolling shutter + shutter.upper -= rollingShutterDuration; + if (shutterType == OSP_SHUTTER_ROLLING_LEFT + || shutterType == OSP_SHUTTER_ROLLING_DOWN) + std::swap(shutter.lower, shutter.upper); } ispc::Camera_set(getIE(), @@ -95,7 +102,11 @@ void Camera::commit() (const ispc::vec2f &)imageStart, (const ispc::vec2f &)imageEnd, (const ispc::box1f &)shutter, - motionBlur, + shutterType == OSP_SHUTTER_GLOBAL, + rollingShutterDuration, + shutterType == OSP_SHUTTER_ROLLING_RIGHT + || shutterType == OSP_SHUTTER_ROLLING_LEFT, + motionTransform.motionBlur, embreeGeometry); } diff --git a/ospray/camera/Camera.h b/ospray/camera/Camera.h index c69ff28b17..d422b3422d 100644 --- a/ospray/camera/Camera.h +++ b/ospray/camera/Camera.h @@ -11,7 +11,7 @@ namespace ospray { //! base camera class abstraction /*! the base class itself does not do anything useful; look into perspectivecamera etc for that */ -struct OSPRAY_SDK_INTERFACE Camera : public MotionTransform +struct OSPRAY_SDK_INTERFACE Camera : public ManagedObject { Camera(); ~Camera() override; @@ -43,6 +43,8 @@ struct OSPRAY_SDK_INTERFACE Camera : public MotionTransform vec2f imageStart; // lower left corner vec2f imageEnd; // upper right corner range1f shutter{0.5f, 0.5f}; // start and end time of camera shutter time + float rollingShutterDuration{0.0f}; + OSPShutterType shutterType{OSP_SHUTTER_GLOBAL}; void setDevice(RTCDevice embreeDevice); @@ -52,6 +54,7 @@ struct OSPRAY_SDK_INTERFACE Camera : public MotionTransform static void registerType(const char *type, FactoryFcn f); RTCDevice embreeDevice{nullptr}; RTCGeometry embreeGeometry{nullptr}; + MotionTransform motionTransform; }; OSPTYPEFOR_SPECIALIZATION(Camera *, OSP_CAMERA); diff --git a/ospray/camera/Camera.ih b/ospray/camera/Camera.ih index 1bc21f7489..3031eeb94d 100644 --- a/ospray/camera/Camera.ih +++ b/ospray/camera/Camera.ih @@ -28,13 +28,15 @@ typedef void (*Camera_initRay)(const Camera *uniform, struct Camera { Camera_initRay initRay; /*!< the 'virtual' initRay() method */ - void *cppEquivalent; - bool motionBlur; + bool motionBlur; // for the camera itself only, not in general float nearClip; box2f subImage; // viewable tile / subrange to compute, in [0..1]^2 x [0..1]^2 range1f shutter; // camera shutter open start and end time, in [0..1] + bool globalShutter; + bool rollingShutterHorizontal; + float rollingShutterDuration; RTCGeometry geom; // only to access rtcGetGeometryTransform }; @@ -43,7 +45,13 @@ inline vec2f Camera_subRegion(const Camera *uniform self, const vec2f &screen) return lerp(screen, self->subImage.lower, self->subImage.upper); } -inline float Camera_shutterTime(const Camera *uniform self, const float time) +inline float Camera_shutterTime( + const Camera *uniform self, const vec2f &screen, float time) { - return lerp(time, self->shutter.lower, self->shutter.upper); + if (self->globalShutter) + return lerp(time, self->shutter.lower, self->shutter.upper); + + time *= self->rollingShutterDuration; + const float pos = self->rollingShutterHorizontal ? screen.x : screen.y; + return clamp(time + lerp(pos, self->shutter.lower, self->shutter.upper)); } diff --git a/ospray/camera/Camera.ispc b/ospray/camera/Camera.ispc index a069fce0c8..dcc53c8424 100644 --- a/ospray/camera/Camera.ispc +++ b/ospray/camera/Camera.ispc @@ -8,6 +8,9 @@ export void Camera_set(void *uniform _self, const uniform vec2f &imageStart, const uniform vec2f &imageEnd, const uniform box1f &shutter, + const uniform bool globalShutter, + const uniform float rollingShutterDuration, + const uniform bool rollingShutterHorizontal, const uniform bool motionBlur, RTCGeometry geom) { @@ -18,4 +21,7 @@ export void Camera_set(void *uniform _self, self->shutter = shutter; self->motionBlur = motionBlur; self->geom = geom; + self->globalShutter = globalShutter; + self->rollingShutterHorizontal = rollingShutterHorizontal; + self->rollingShutterDuration = rollingShutterDuration; } diff --git a/ospray/camera/OrthographicCamera.cpp b/ospray/camera/OrthographicCamera.cpp index bb81ac9a7b..9862db087a 100644 --- a/ospray/camera/OrthographicCamera.cpp +++ b/ospray/camera/OrthographicCamera.cpp @@ -8,7 +8,7 @@ namespace ospray { OrthographicCamera::OrthographicCamera() { - ispcEquivalent = ispc::OrthographicCamera_create(this); + ispcEquivalent = ispc::OrthographicCamera_create(); } std::string OrthographicCamera::toString() const diff --git a/ospray/camera/OrthographicCamera.ispc b/ospray/camera/OrthographicCamera.ispc index d7819ac3de..2b3ef84bf5 100644 --- a/ospray/camera/OrthographicCamera.ispc +++ b/ospray/camera/OrthographicCamera.ispc @@ -26,7 +26,7 @@ void OrthographicCamera_initRay(const Camera *uniform _self, (const OrthographicCamera *uniform)_self; const vec2f screen = Camera_subRegion(_self, sample.screen); - const float time = Camera_shutterTime(_self, sample.time); + const float time = Camera_shutterTime(_self, screen, sample.time); vec3f dir; vec3f org; @@ -51,11 +51,10 @@ void OrthographicCamera_initRay(const Camera *uniform _self, setRay(ray, org, dir, self->super.nearClip, inf, time); } -export void *uniform OrthographicCamera_create(void *uniform cppE) +export void *uniform OrthographicCamera_create() { uniform OrthographicCamera *uniform cam = uniform new uniform OrthographicCamera; - cam->super.cppEquivalent = cppE; cam->super.initRay = OrthographicCamera_initRay; return cam; } diff --git a/ospray/camera/PanoramicCamera.cpp b/ospray/camera/PanoramicCamera.cpp index 4bc258c548..e007852fc3 100644 --- a/ospray/camera/PanoramicCamera.cpp +++ b/ospray/camera/PanoramicCamera.cpp @@ -8,7 +8,7 @@ namespace ospray { PanoramicCamera::PanoramicCamera() { - ispcEquivalent = ispc::PanoramicCamera_create(this); + ispcEquivalent = ispc::PanoramicCamera_create(); } std::string PanoramicCamera::toString() const diff --git a/ospray/camera/PanoramicCamera.ispc b/ospray/camera/PanoramicCamera.ispc index 563a29f3b5..97193f916a 100644 --- a/ospray/camera/PanoramicCamera.ispc +++ b/ospray/camera/PanoramicCamera.ispc @@ -55,7 +55,7 @@ void PanoramicCamera_initRay(const Camera *uniform _self, sincos(theta, &sinTheta, &cosTheta); const vec3f localDir = cartesian(phi, sinTheta, cosTheta); - const float time = Camera_shutterTime(_self, sample.time); + const float time = Camera_shutterTime(_self, screen, sample.time); // transform to camera- and then to world-space vec3f dir; @@ -80,10 +80,9 @@ void PanoramicCamera_initRay(const Camera *uniform _self, setRay(ray, org, dir, self->super.nearClip, inf, time); } -export void *uniform PanoramicCamera_create(void *uniform cppE) +export void *uniform PanoramicCamera_create() { PanoramicCamera *uniform self = uniform new PanoramicCamera; - self->super.cppEquivalent = cppE; self->super.initRay = PanoramicCamera_initRay; self->stereoMode = OSP_STEREO_NONE; self->ipd_offset = 0.f; diff --git a/ospray/camera/PerspectiveCamera.cpp b/ospray/camera/PerspectiveCamera.cpp index 1bc16ee616..f2c0973056 100644 --- a/ospray/camera/PerspectiveCamera.cpp +++ b/ospray/camera/PerspectiveCamera.cpp @@ -8,7 +8,7 @@ namespace ospray { PerspectiveCamera::PerspectiveCamera() { - ispcEquivalent = ispc::PerspectiveCamera_create(this); + ispcEquivalent = ispc::PerspectiveCamera_create(); } std::string PerspectiveCamera::toString() const diff --git a/ospray/camera/PerspectiveCamera.ispc b/ospray/camera/PerspectiveCamera.ispc index 32a594f46f..2dc848fa2d 100644 --- a/ospray/camera/PerspectiveCamera.ispc +++ b/ospray/camera/PerspectiveCamera.ispc @@ -65,7 +65,7 @@ void PerspectiveCamera_initRay(const Camera *uniform _self, dir = dir - lp; } - const float time = Camera_shutterTime(_self, sample.time); + const float time = Camera_shutterTime(_self, screen, sample.time); setRay(ray, org, normalize(dir), self->super.nearClip, inf, time); } @@ -76,7 +76,21 @@ void PerspectiveCamera_initRayMB(const Camera *uniform _self, const PerspectiveCamera *uniform self = (const PerspectiveCamera *uniform)_self; - const float time = Camera_shutterTime(_self, sample.time); + vec2f screen = sample.screen; + float ipd_offset1 = self->ipd_offset.x; + + const uniform bool sbs = self->stereoMode == OSP_STEREO_SIDE_BY_SIDE; + varying float *uniform split = sbs ? &screen.x : &screen.y; + if (or (sbs, self->stereoMode == OSP_STEREO_TOP_BOTTOM)) { + *split *= 2.f; + if (*split < 1.f) + ipd_offset1 = -ipd_offset1; + else + *split -= 1.f; + } + + screen = Camera_subRegion(_self, screen); + const float time = Camera_shutterTime(_self, screen, sample.time); const affine3f xfm = getInterpolatedTransform(self->super.geom, time); vec3f org = xfmPoint(xfm, self->org); @@ -89,19 +103,17 @@ void PerspectiveCamera_initRayMB(const Camera *uniform _self, else // rotate film to be perpendicular to 'dir' dv = cross(du, dir); - vec3f ipd_offset = self->ipd_offset.x * du; + vec3f ipd_offset = ipd_offset1 * du; switch (self->stereoMode) { case OSP_STEREO_LEFT: + case OSP_STEREO_TOP_BOTTOM: // flipped to have left eye at top org = org - ipd_offset; break; case OSP_STEREO_RIGHT: + case OSP_STEREO_SIDE_BY_SIDE: org = org + ipd_offset; break; - case OSP_STEREO_TOP_BOTTOM: - // flip offset to have left eye at top (image coord origin at lower left) - ipd_offset = neg(ipd_offset); - break; default: break; } @@ -117,22 +129,6 @@ void PerspectiveCamera_initRayMB(const Camera *uniform _self, dir = dir * self->ipd_offset.y; // focusDistance } - vec2f screen = sample.screen; - - const uniform bool sbs = self->stereoMode == OSP_STEREO_SIDE_BY_SIDE; - varying float *uniform split = sbs ? &screen.x : &screen.y; - if (or (sbs, self->stereoMode == OSP_STEREO_TOP_BOTTOM)) { - *split *= 2.f; - if (*split < 1.f) { - org = org - ipd_offset; - } else { - org = org + ipd_offset; - *split -= 1.f; - } - } - - screen = Camera_subRegion(_self, screen); - dir = dir + screen.x * du + screen.y * dv; if (self->scaledAperture > 0.f) { @@ -146,11 +142,10 @@ void PerspectiveCamera_initRayMB(const Camera *uniform _self, setRay(ray, org, normalize(dir), self->super.nearClip, inf, time); } -export void *uniform PerspectiveCamera_create(void *uniform cppE) +export void *uniform PerspectiveCamera_create() { uniform PerspectiveCamera *uniform self = uniform new uniform PerspectiveCamera; - self->super.cppEquivalent = cppE; self->super.initRay = PerspectiveCamera_initRay; return self; } diff --git a/ospray/common/Group.cpp b/ospray/common/Group.cpp index 948a5671e2..27b4286b99 100644 --- a/ospray/common/Group.cpp +++ b/ospray/common/Group.cpp @@ -3,6 +3,9 @@ // ospray #include "Group.h" +#include "geometry/GeometricModel.h" +#include "lights/Light.h" +#include "volume/VolumetricModel.h" // ispc exports #include "common/Group_ispc.h" @@ -45,7 +48,7 @@ static void freeAndNullifyEmbreeScene(RTCScene &scene) Group::Group() { managedObjectType = OSP_GROUP; - this->ispcEquivalent = ispc::Group_create(this); + this->ispcEquivalent = ispc::Group_create(); } Group::~Group() @@ -65,15 +68,18 @@ void Group::commit() geometricModels = getParamDataT("geometry"); volumetricModels = getParamDataT("volume"); clipModels = getParamDataT("clippingGeometry"); + lights = getParamDataT("light"); size_t numGeometries = geometricModels ? geometricModels->size() : 0; size_t numVolumes = volumetricModels ? volumetricModels->size() : 0; size_t numClippers = clipModels ? clipModels->size() : 0; + size_t numLights = lights ? lights->size() : 0; postStatusMsg(OSP_LOG_DEBUG) << "=======================================================\n" << "Finalizing instance, which has " << numGeometries << " geometries, " - << numVolumes << " volumes and " << numClippers << " clipping geometries"; + << numVolumes << " volumes, " << numClippers + << " clipping geometries and " << numLights << " lights"; int sceneFlags = RTC_SCENE_FLAG_NONE; sceneFlags |= @@ -129,6 +135,15 @@ void Group::commit() rtcCommitScene(sceneClippers); } + // Create empty scene for lights-only group, + // it is needed to have rtcGeometry created in Instance object + // which in turn is needed for motion blur matrices interpolation + if ((numLights > 0) && (numGeometries == 0) && (numVolumes == 0) + && (numClippers == 0)) { + sceneGeometries = rtcNewScene(embreeDevice); + rtcCommitScene(sceneGeometries); + } + ispc::Group_set(getIE(), geometricModels ? geometricModelIEs.data() : nullptr, numGeometries, diff --git a/ospray/common/Group.h b/ospray/common/Group.h index c743d84fcd..ff2e05504c 100644 --- a/ospray/common/Group.h +++ b/ospray/common/Group.h @@ -4,8 +4,6 @@ #pragma once // ospray stuff -#include "../geometry/GeometricModel.h" -#include "../volume/VolumetricModel.h" #include "./Data.h" #include "./Managed.h" // stl @@ -15,6 +13,10 @@ namespace ospray { +struct GeometricModel; +struct VolumetricModel; +struct Light; + struct OSPRAY_SDK_INTERFACE Group : public ManagedObject { Group(); @@ -37,6 +39,8 @@ struct OSPRAY_SDK_INTERFACE Group : public ManagedObject std::vector clipModelIEs; int numInvertedClippers{0}; + Ref> lights; + RTCScene sceneGeometries{nullptr}; RTCScene sceneVolumes{nullptr}; RTCScene sceneClippers{nullptr}; diff --git a/ospray/common/Group.ih b/ospray/common/Group.ih index 63bab08975..4d4e31b223 100644 --- a/ospray/common/Group.ih +++ b/ospray/common/Group.ih @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -10,8 +10,6 @@ struct Group { - void *cppEquivalent; - GeometricModel **geometricModels; int32 numGeometricModels; diff --git a/ospray/common/Group.ispc b/ospray/common/Group.ispc index 19ac5782e7..ace089b70a 100644 --- a/ospray/common/Group.ispc +++ b/ospray/common/Group.ispc @@ -1,14 +1,12 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Group.ih" -export void *uniform Group_create(void *uniform cppE) +export void *uniform Group_create() { Group *uniform group = uniform new Group; - group->cppEquivalent = cppE; - group->geometricModels = NULL; group->numGeometricModels = 0; diff --git a/ospray/common/Instance.cpp b/ospray/common/Instance.cpp index f951380421..88273f3924 100644 --- a/ospray/common/Instance.cpp +++ b/ospray/common/Instance.cpp @@ -14,7 +14,7 @@ namespace ospray { Instance::Instance(Group *_group) { managedObjectType = OSP_INSTANCE; - this->ispcEquivalent = ispc::Instance_create(this); + this->ispcEquivalent = ispc::Instance_create(); group = _group; } @@ -26,12 +26,12 @@ std::string Instance::toString() const void Instance::commit() { - MotionTransform::commit(); + motionTransform.readParams(*this); ispc::Instance_set(getIE(), group->getIE(), - (ispc::AffineSpace3f &)(*motionTransforms)[0], - motionBlur); + (ispc::AffineSpace3f &)motionTransform.transform[0], + motionTransform.motionBlur); } box3f Instance::getBounds() const @@ -39,16 +39,16 @@ box3f Instance::getBounds() const box3f bounds; const box3f groupBounds = group->getBounds(); // TODO get better bounds: - // - this is too big, because keys outside of time [0, 1] are included - // - yet is is also too small, because interpolated transformations can lead - // to leaving the bounds of keys - // alternatives: - // - use bounds at time 0.5, wrong if different shutter is used and does not + // - uses bounds at time 0.5, wrong if different shutter is used and does not // include motion at all + // alternatives: // - merge linear bounds from Embree (which is for time [0, 1]), but this // needs a temporary RTCScene just for this instance - for (auto &&xfm : *motionTransforms) - bounds.extend(xfmBounds(xfm, groupBounds)); + // - extend over all transformed bounds + // - this is too big, because keys outside of time [0, 1] are included + // - yet is is also too small, because interpolated transformations can + // lead to leaving the bounds of keys + bounds.extend(xfmBounds(motionTransform.transform, groupBounds)); return bounds; } diff --git a/ospray/common/Instance.h b/ospray/common/Instance.h index 8d61a3678e..62074e9cc4 100644 --- a/ospray/common/Instance.h +++ b/ospray/common/Instance.h @@ -11,7 +11,7 @@ namespace ospray { -struct OSPRAY_SDK_INTERFACE Instance : public MotionTransform +struct OSPRAY_SDK_INTERFACE Instance : public ManagedObject { Instance(Group *group); ~Instance() override = default; @@ -23,6 +23,7 @@ struct OSPRAY_SDK_INTERFACE Instance : public MotionTransform box3f getBounds() const override; Ref group; + MotionTransform motionTransform; }; OSPTYPEFOR_SPECIALIZATION(Instance *, OSP_INSTANCE); diff --git a/ospray/common/Instance.ih b/ospray/common/Instance.ih index 549690b452..bb3d49ea33 100644 --- a/ospray/common/Instance.ih +++ b/ospray/common/Instance.ih @@ -12,8 +12,6 @@ struct Renderer; struct Instance { - void *cppEquivalent; - Group *group; RTCGeometry geom; // only to access rtcGetGeometryTransform @@ -21,6 +19,8 @@ struct Instance AffineSpace3f rcp_xfm; bool motionBlur; }; +typedef Instance *uniform InstancePtr; +typedef InstancePtr *uniform InstanceArray; inline uniform AffineSpace3f Instance_getTransform( const Instance *uniform self, const uniform float time) diff --git a/ospray/common/Instance.ispc b/ospray/common/Instance.ispc index af811643ce..d5c870f063 100644 --- a/ospray/common/Instance.ispc +++ b/ospray/common/Instance.ispc @@ -3,11 +3,10 @@ #include "Instance.ih" -export void *uniform Instance_create(void *uniform cppE) +export void *uniform Instance_create() { Instance *uniform inst = uniform new Instance; - inst->cppEquivalent = cppE; inst->group = NULL; return (void *uniform)inst; diff --git a/ospray/common/Intersect.ih b/ospray/common/Intersect.ih index c666326ecb..353975bd10 100644 --- a/ospray/common/Intersect.ih +++ b/ospray/common/Intersect.ih @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -75,7 +75,6 @@ inline Intersections intersectSphere(const vec3f &rayOrg, return isect; } -// robust ray-cylinder intersection inline Intersections intersectCylinder(const vec3f &rayOrg, const vec3f &rayDir, const uniform vec3f &v0, @@ -88,52 +87,66 @@ inline Intersections intersectCylinder(const vec3f &rayOrg, isect.entry.t = inf; isect.exit.t = -inf; - const vec3f d = rayDir; - const uniform vec3f s = v1 - v0; // axis - const vec3f sxd = cross(s, d); - const float a = dot(sxd, sxd); // (s x d)^2 - if (a == 0.f) - return isect; - const vec3f f = v0 - rayOrg; - const vec3f sxf = cross(s, f); - const float ra = 1.0f / a; - const float ts = - dot(sxd, sxf) * ra; // (s x d)(s x f) / (s x d)^2, in ray-space - const vec3f fp = f - ts * d; // f' = v0 - closest point to axis - - const uniform float s2 = dot(s, s); // s^2 - const vec3f perp = cross(s, fp); // s x f' - const float c = sqr(radius) * s2 - dot(perp, perp); // r^2 s^2 - (s x f')^2 - if (c < 0.f) - return isect; + const uniform vec3f cZ = v1 - v0; + const vec3f q = rayOrg - v0; - float td = sqrt(c * ra); - const float tin = ts - td; - const float tout = ts + td; + const uniform float z2 = dot(cZ, cZ); + const float d = dot(cZ, rayDir); + const float c = dot(cZ, q); + + const float A = z2 - sqr(d); + const float B = z2 * dot(q, rayDir) - c * d; + const float C = z2 * dot(q, q) - sqr(c) - sqr(radius) * z2; + + float radical = B * B - A * C; + if (radical < 0.f) { + return isect; + } - // clip to cylinder caps - const float sf = dot(s, f); - const float sd = dot(s, d); - const float rsd = rcp(sd); - const float tA = sf * rsd; - const float tB = tA + s2 * rsd; + radical = sqrt(radical); - const float cap_tin = min(tA, tB); - const float cap_tout = max(tA, tB); + const float tin = (-B - radical) / A; + const float tout = (-B + radical) / A; - isect.entry.hit = and(tin > cap_tin, tin < cap_tout); - if (isect.entry.hit) + // first hit + const float yin = c + tin * d; + if (yin > 0.f && yin < z2) { + // body hit + isect.entry.hit = true; isect.entry.t = tin; - isect.exit.hit = and(tout > cap_tin, tout < cap_tout); - if (isect.exit.hit) - isect.exit.t = tout; + isect.entry.u = yin * rcp(z2); + isect.entry.N = (q + tin * rayDir - cZ * yin * rcp(z2)) * rcp(radius); + } else { + const float tcapin = (((yin < 0.f) ? 0.f : z2) - c) / d; + if (abs(B + A * tcapin) < radical) { + // cap hit + isect.entry.hit = false; + isect.entry.t = tin; + isect.entry.u = (yin < 0.f) ? 0.f : 1.f; + const float us = signbits(yin) ? -1. : 1.; + isect.entry.N = cZ * us / z2; + } + } - // cannot easily be moved to postIntersect - // we need hit in object-space, in postIntersect it is in world-space - isect.entry.u = (tin * sd - sf) * rcp(s2); - isect.entry.N = -td * d - fp - isect.entry.u * s; - isect.exit.u = (tout * sd - sf) * rcp(s2); - isect.exit.N = td * d - fp - isect.exit.u * s; + // second hit + const float yout = c + tout * d; + if (yout > 0.f && yout < z2) { + // body hit + isect.exit.hit = true; + isect.exit.t = tout; + isect.exit.u = yout * rcp(z2); + isect.exit.N = (q + tout * rayDir - cZ * yout * rcp(z2)) * rcp(radius); + } else { + const float tcapout = (((yout < 0.f) ? 0.f : z2) - c) / d; + if (abs(B + A * tcapout) < radical) { + // cap hit + isect.exit.hit = false; + isect.exit.t = tout; + isect.exit.u = (yout < 0.f) ? 0.f : 1.f; + const float us = signbits(yout) ? -1. : 1.; + isect.exit.N = cZ * us / z2; + } + } return isect; } diff --git a/ospray/common/MotionTransform.cpp b/ospray/common/MotionTransform.cpp index 62308e4f27..9673122623 100644 --- a/ospray/common/MotionTransform.cpp +++ b/ospray/common/MotionTransform.cpp @@ -6,20 +6,90 @@ namespace ospray { -void MotionTransform::commit() +void MotionTransform::readParams(ManagedObject &obj) { - motionTransforms = getParamDataT("motion.transform"); - if (!motionTransforms) { // add single transform - auto data = new Data(OSP_AFFINE3F, vec3ul(1)); - auto &dataA3f = data->as(); - *dataA3f.data() = getParam( - "transform", getParam("xfm", affine3f(one))); - motionTransforms = &dataA3f; - data->refDec(); + transforms = obj.getParamDataT("motion.transform"); + if (transforms) { + motionBlur = transforms->size() > 1; + quaternion = false; + transform = (*transforms)[0]; + } else { // look for SRT + auto shift = obj.getParamDataT("motion.pivot"); + auto scale = obj.getParamDataT("motion.scale"); + auto rotation = obj.getParamDataT("motion.rotation"); + auto translation = obj.getParamDataT("motion.translation"); + quaternion = shift || scale || rotation || translation; + if (quaternion) { + // determine (minimum) size + size_t size = std::numeric_limits::max(); + if (shift) + size = shift->size(); + if (scale) + size = std::min(size, scale->size()); + if (rotation) + size = std::min(size, rotation->size()); + if (translation) + size = std::min(size, translation->size()); + motionBlur = size > 1; + quaternions.resize(size); + for (size_t i = 0; i < size; i++) { + auto *qdecomp = &quaternions[i]; + rtcInitQuaternionDecomposition(qdecomp); + if (shift) { + const vec3f &s = (*shift)[i]; + rtcQuaternionDecompositionSetShift(qdecomp, s.x, s.y, s.z); + } + if (scale) { + const vec3f &s = (*scale)[i]; + rtcQuaternionDecompositionSetScale(qdecomp, s.x, s.y, s.z); + } + if (rotation) { + const quatf &q = (*rotation)[i]; + rtcQuaternionDecompositionSetQuaternion(qdecomp, q.r, q.i, q.j, q.k); + } + if (translation) { + const vec3f &t = (*translation)[i]; + rtcQuaternionDecompositionSetTranslation(qdecomp, t.x, t.y, t.z); + } + } + } else { // add single transform + quaternions.clear(); + motionBlur = false; + transform = obj.getParam( + "transform", obj.getParam("xfm", affine3f(one))); + } } - motionBlur = motionTransforms->size() > 1; - if (motionBlur) - time = getParam("time", range1f(0.0f, 1.0f)); + time = range1f(0.0f, 1.0f); + if (motionBlur) { + time = obj.getParam("time", range1f(0.0f, 1.0f)); + if (time.upper < time.lower) + time.upper = time.lower; + } +} + +void MotionTransform::setEmbreeTransform(RTCGeometry embreeGeometry) const +{ + if (quaternion) { + rtcSetGeometryTimeStepCount(embreeGeometry, quaternions.size()); + for (size_t i = 0; i < quaternions.size(); i++) + rtcSetGeometryTransformQuaternion(embreeGeometry, i, &quaternions[i]); + rtcSetGeometryTimeRange(embreeGeometry, time.lower, time.upper); + } else { + if (motionBlur) { + rtcSetGeometryTimeStepCount(embreeGeometry, transforms->size()); + for (size_t i = 0; i < transforms->size(); i++) + rtcSetGeometryTransform(embreeGeometry, + i, + RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, + &(*transforms)[i]); + rtcSetGeometryTimeRange(embreeGeometry, time.lower, time.upper); + } else { + rtcSetGeometryTimeStepCount(embreeGeometry, 1); + rtcSetGeometryTransform( + embreeGeometry, 0, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, transform); + } + } + rtcCommitGeometry(embreeGeometry); } } // namespace ospray diff --git a/ospray/common/MotionTransform.h b/ospray/common/MotionTransform.h index 4dcc387eeb..71641da896 100644 --- a/ospray/common/MotionTransform.h +++ b/ospray/common/MotionTransform.h @@ -10,13 +10,18 @@ namespace ospray { -struct OSPRAY_SDK_INTERFACE MotionTransform : public ManagedObject +struct OSPRAY_SDK_INTERFACE MotionTransform { - void commit() override; + void readParams(ManagedObject &); + void setEmbreeTransform(RTCGeometry) const; + affine3f transform{one}; + bool motionBlur{false}; + bool quaternion{false}; - Ref> motionTransforms; + private: + Ref> transforms; + std::vector quaternions; range1f time{0.0f, 1.0f}; - bool motionBlur{false}; }; } // namespace ospray diff --git a/ospray/common/OSPCommon.cpp b/ospray/common/OSPCommon.cpp index 3daf0cb85f..5f7cca6457 100644 --- a/ospray/common/OSPCommon.cpp +++ b/ospray/common/OSPCommon.cpp @@ -361,6 +361,8 @@ size_t sizeOf(OSPDataType type) return sizeof(affine2f); case OSP_AFFINE3F: return sizeof(affine3f); + case OSP_QUATF: + return sizeof(quatf); case OSP_UNKNOWN: return 0; } @@ -610,6 +612,8 @@ std::string stringFor(OSPDataType type) return "affine2f"; case OSP_AFFINE3F: return "affine3f"; + case OSP_QUATF: + return "quatf"; case OSP_UNKNOWN: return "unknown"; } diff --git a/ospray/common/World.cpp b/ospray/common/World.cpp index e8a7102a7c..aee42a4548 100644 --- a/ospray/common/World.cpp +++ b/ospray/common/World.cpp @@ -26,16 +26,8 @@ static void addGeometryInstance(RTCScene &scene, // Create geometry instance auto eInst = rtcNewGeometry(embreeDevice, RTC_GEOMETRY_TYPE_INSTANCE); rtcSetGeometryInstancedScene(eInst, instScene); + inst->motionTransform.setEmbreeTransform(eInst); - auto &xfm = *inst->motionTransforms; - rtcSetGeometryTimeStepCount(eInst, xfm.size()); - for (size_t i = 0; i < xfm.size(); i++) - rtcSetGeometryTransform( - eInst, i, RTC_FORMAT_FLOAT3X4_COLUMN_MAJOR, &xfm[i]); - if (xfm.size() > 1) - rtcSetGeometryTimeRange(eInst, inst->time.lower, inst->time.upper); - - rtcCommitGeometry(eInst); ispc::Instance_set_embreeGeom(inst->getIE(), eInst); rtcAttachGeometry(scene, eInst); @@ -64,7 +56,7 @@ World::~World() World::World() { managedObjectType = OSP_WORLD; - this->ispcEquivalent = ispc::World_create(this); + this->ispcEquivalent = ispc::World_create(); } std::string World::toString() const diff --git a/ospray/common/World.ih b/ospray/common/World.ih index f3be54e368..62588dc597 100644 --- a/ospray/common/World.ih +++ b/ospray/common/World.ih @@ -7,33 +7,34 @@ #include "common/Clipping.ih" #include "common/Ray.ih" #include "common/VolumeIntervals.ih" -#include "lights/Light.ih" struct Renderer; +struct Light; struct SciVisData { + // array containing the scene light sources + // the lights are sorted: first lights that are not sampled (visible only), + // then lights that are both sampled and visible + Light **lights; + uint32 numLights; // total number of light sources + uint32 numLightsVisibleOnly; // number of lights that are not sampled (visible + // only) vec3f aoColorPi; - Light *uniform *uniform lights; - Light *uniform *uniform lightsVisible; - uint32 numLights; - uint32 numLightsVisible; }; struct PathtracerData { // array containing the scene light sources // the lights are sorted: first geometric, then virtual lights - Light *uniform *uniform lights; + Light **lights; uint32 numLights; // total number of light sources (geometric + virtual) uint32 numGeoLights; // number of geometric light sources - float *uniform lightsCDF; // CDF used by NEE for randomly picking lights + float *lightsCDF; // CDF used by NEE for randomly picking lights }; struct World { - void *cppEquivalent; - Instance **geometriesInst; int32 numGeometriesInst; @@ -53,7 +54,7 @@ struct World PathtracerData pathtracerData; }; -void World_Constructor(World *uniform world, void *uniform cppE); +void World_Constructor(World *uniform world); inline void traceGeometryRay(const World *uniform world, varying Ray &ray) { diff --git a/ospray/common/World.ispc b/ospray/common/World.ispc index a823316347..838664aadd 100644 --- a/ospray/common/World.ispc +++ b/ospray/common/World.ispc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "World.ih" +#include "lights/Light.ih" #include "math/Distribution1D.ih" #include "render/pathtracer/GeometryLight.ih" @@ -97,9 +98,8 @@ unmasked void clippingIntersectionFilterV( context->hitsCount++; } -void World_Constructor(World *uniform world, void *uniform cppE) +void World_Constructor(World *uniform world) { - world->cppEquivalent = cppE; world->geometriesInst = NULL; world->numGeometriesInst = 0; world->volumesInst = NULL; @@ -114,9 +114,8 @@ void World_Constructor(World *uniform world, void *uniform cppE) world->numInvertedClippers = 0; world->scivisData.lights = NULL; - world->scivisData.lightsVisible = NULL; world->scivisData.numLights = 0; - world->scivisData.numLightsVisible = 0; + world->scivisData.numLightsVisibleOnly = 0; world->pathtracerData.numLights = 0; world->pathtracerData.numGeoLights = 0; @@ -124,18 +123,31 @@ void World_Constructor(World *uniform world, void *uniform cppE) world->pathtracerData.lightsCDF = NULL; } +inline void SciVisData_destroy(SciVisData *uniform self) +{ + // Delete all lights + for (uniform int i = 0; i < self->numLights; i++) + delete self->lights[i]; + + delete[] self->lights; +} + inline void PathtracerData_destroy(PathtracerData *uniform self) { for (uniform int i = 0; i < self->numGeoLights; i++) GeometryLight_destroy(self->lights[i]); + + for (uniform int i = self->numGeoLights; i < self->numLights; i++) + delete self->lights[i]; + delete[] self->lights; delete[] self->lightsCDF; } -export void *uniform World_create(void *uniform cppE) +export void *uniform World_create() { World *uniform world = uniform new World; - World_Constructor(world, cppE); + World_Constructor(world); return (void *uniform)world; } @@ -143,8 +155,7 @@ export void World_destroy(void *uniform _self) { World *uniform self = (World * uniform) _self; - delete[] self->scivisData.lights; - delete[] self->scivisData.lightsVisible; + SciVisData_destroy(&self->scivisData); PathtracerData_destroy(&self->pathtracerData); delete self; @@ -187,33 +198,22 @@ export void World_setSciVisData(void *uniform _self, const uniform vec3f &aoColor, void **uniform lights, const uniform uint32 numLights, - void **uniform lightsVisible, - const uniform uint32 numLightsVisible) + const uniform uint32 numLightsVisibleOnly) { World *uniform self = (World * uniform) _self; + SciVisData *uniform svData = &self->scivisData; - delete[] self->scivisData.lights; - self->scivisData.lights = NULL; - - delete[] self->scivisData.lightsVisible; - self->scivisData.lightsVisible = NULL; - - self->scivisData.aoColorPi = aoColor * pi; + SciVisData_destroy(svData); - self->scivisData.numLights = numLights; + svData->aoColorPi = aoColor * pi; + svData->lights = NULL; + svData->numLights = numLights; + svData->numLightsVisibleOnly = numLightsVisibleOnly; if (numLights) { - self->scivisData.lights = uniform new LightPtr[numLights]; + svData->lights = uniform new uniform LightPtr[numLights]; LightArray srcLights = (LightArray)lights; for (uniform int i = 0; i < numLights; i++) - self->scivisData.lights[i] = srcLights[i]; - } - - self->scivisData.numLightsVisible = numLightsVisible; - if (numLightsVisible) { - self->scivisData.lightsVisible = uniform new LightPtr[numLightsVisible]; - LightArray srcLights = (LightArray)lightsVisible; - for (uniform int i = 0; i < numLightsVisible; i++) - self->scivisData.lightsVisible[i] = srcLights[i]; + svData->lights[i] = srcLights[i]; } } @@ -232,17 +232,12 @@ export void World_setPathtracerData(void *uniform _self, ptData->numLights = numLights; ptData->numGeoLights = numGeoLights; if (numLights) { - ptData->lights = uniform new LightPtr[numLights]; - ptData->lightsCDF = uniform new float[numLights]; + ptData->lights = uniform new uniform LightPtr[numLights]; + ptData->lightsCDF = uniform new uniform float[numLights]; LightArray srcLights = (LightArray)lights; - uniform float uniformLightSelectionPDF = 1.0f / numLights; for (uniform int i = 0; i < numLights; i++) { ptData->lights[i] = srcLights[i]; - - // naive implementation of a stochastic light selection - // assigning each light source the same probability ptData->lightsCDF[i] = 1.0f; - ptData->lights[i]->selectionPDF = uniformLightSelectionPDF; } Distribution1D_create(numLights, ptData->lightsCDF); } diff --git a/ospray/fb/FrameBuffer.ih b/ospray/fb/FrameBuffer.ih index e7473b8112..c31602a61d 100644 --- a/ospray/fb/FrameBuffer.ih +++ b/ospray/fb/FrameBuffer.ih @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -31,12 +31,10 @@ struct FrameBuffer int32 frameID; FrameBuffer_ColorBufferFormat colorBufferFormat; - - void *cClassPtr; /*!< pointer back to c++-side of this class */ }; void FrameBuffer_Constructor( - FrameBuffer *uniform self, void *uniform cClassPtr); + FrameBuffer *uniform self); void FrameBuffer_set(FrameBuffer *uniform self, const uniform uint32 size_x, diff --git a/ospray/fb/FrameBuffer.ispc b/ospray/fb/FrameBuffer.ispc index f12884cf7d..3316a77872 100644 --- a/ospray/fb/FrameBuffer.ispc +++ b/ospray/fb/FrameBuffer.ispc @@ -1,11 +1,10 @@ -// Copyright 2009-2019 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "fb/FrameBuffer.ih" -void FrameBuffer_Constructor(FrameBuffer *uniform self, void *uniform cClassPtr) +void FrameBuffer_Constructor(FrameBuffer *uniform self) { - self->cClassPtr = cClassPtr; self->size.x = 0; self->size.y = 0; self->rcpSize.x = 0.f; diff --git a/ospray/fb/LocalFB.cpp b/ospray/fb/LocalFB.cpp index a150f72772..d8d7f330c4 100644 --- a/ospray/fb/LocalFB.cpp +++ b/ospray/fb/LocalFB.cpp @@ -48,8 +48,7 @@ LocalFrameBuffer::LocalFrameBuffer(const vec2i &_size, if (hasAlbedoBuffer) albedoBuffer.resize(numPixels); - ispcEquivalent = ispc::LocalFrameBuffer_create(this, - size.x, + ispcEquivalent = ispc::LocalFrameBuffer_create(size.x, size.y, colorBufferFormat, getDataSafe(colorBuffer), diff --git a/ospray/fb/LocalFB.ispc b/ospray/fb/LocalFB.ispc index eb381009cb..9c4a7e0fbe 100644 --- a/ospray/fb/LocalFB.ispc +++ b/ospray/fb/LocalFB.ispc @@ -223,8 +223,7 @@ export void LocalFrameBuffer_accumulateAuxTile(void *uniform _fb, } } -export void *uniform LocalFrameBuffer_create(void *uniform cClassPtr, - const uniform uint32 size_x, +export void *uniform LocalFrameBuffer_create(const uniform uint32 size_x, const uniform uint32 size_y, uniform int32 colorBufferFormat, void *uniform colorBuffer, @@ -236,7 +235,7 @@ export void *uniform LocalFrameBuffer_create(void *uniform cClassPtr, void *uniform tileAccumID) { uniform LocalFB *uniform self = uniform new uniform LocalFB; - FrameBuffer_Constructor(&self->super, cClassPtr); + FrameBuffer_Constructor(&self->super); FrameBuffer_set(&self->super, size_x, size_y, colorBufferFormat); self->colorBuffer = colorBuffer; diff --git a/ospray/geometry/Boxes.cpp b/ospray/geometry/Boxes.cpp index 9a9a452c42..dec64172fb 100644 --- a/ospray/geometry/Boxes.cpp +++ b/ospray/geometry/Boxes.cpp @@ -12,7 +12,7 @@ namespace ospray { Boxes::Boxes() { - ispcEquivalent = ispc::Boxes_create(this); + ispcEquivalent = ispc::Boxes_create(); } std::string Boxes::toString() const diff --git a/ospray/geometry/Boxes.ispc b/ospray/geometry/Boxes.ispc index 1eace7477c..d635984e26 100644 --- a/ospray/geometry/Boxes.ispc +++ b/ospray/geometry/Boxes.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray @@ -66,11 +66,11 @@ static void Boxes_postIntersect(const Geometry *uniform geometry, dg.Ng = dg.Ns = ray.Ng; } -export void *uniform Boxes_create(void *uniform cppEquivalent) +export void *uniform Boxes_create() { Boxes *uniform self = uniform new Boxes; - Geometry_Constructor(&self->super, cppEquivalent, Boxes_postIntersect); + Geometry_Constructor(&self->super, Boxes_postIntersect); Data1D_Constructor(&self->boxes); return self; diff --git a/ospray/geometry/Curves.cpp b/ospray/geometry/Curves.cpp index aab5dd306d..5adfcd934d 100644 --- a/ospray/geometry/Curves.cpp +++ b/ospray/geometry/Curves.cpp @@ -48,7 +48,7 @@ static std::map, RTCGeometryType> Curves::Curves() { - ispcEquivalent = ispc::Curves_create(this); + ispcEquivalent = ispc::Curves_create(); } std::string Curves::toString() const diff --git a/ospray/geometry/Curves.ispc b/ospray/geometry/Curves.ispc index 3bfef186f8..86c59771a7 100644 --- a/ospray/geometry/Curves.ispc +++ b/ospray/geometry/Curves.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray @@ -50,19 +50,19 @@ static void Curves_postIntersect(const Geometry *uniform _self, } } -void Curves_Constructor(Curves *uniform self, void *uniform cppEquivalent) +void Curves_Constructor(Curves *uniform self) { - Geometry_Constructor(&self->super, cppEquivalent, NULL); + Geometry_Constructor(&self->super, NULL); Data1D_Constructor(&self->index); Data1D_Constructor(&self->vertex); Data1D_Constructor(&self->color); Data1D_Constructor(&self->texcoord); } -export void *uniform Curves_create(void *uniform cppEquivalent) +export void *uniform Curves_create() { Curves *uniform self = uniform new Curves; - Curves_Constructor(self, cppEquivalent); + Curves_Constructor(self); return self; } diff --git a/ospray/geometry/GeometricModel.cpp b/ospray/geometry/GeometricModel.cpp index 4c14b91176..96dd8dbef4 100644 --- a/ospray/geometry/GeometricModel.cpp +++ b/ospray/geometry/GeometricModel.cpp @@ -14,7 +14,7 @@ GeometricModel::GeometricModel(Geometry *_geometry) { managedObjectType = OSP_GEOMETRIC_MODEL; geomAPI = _geometry; - this->ispcEquivalent = ispc::GeometricModel_create(this); + this->ispcEquivalent = ispc::GeometricModel_create(); } std::string GeometricModel::toString() const diff --git a/ospray/geometry/GeometricModel.ispc b/ospray/geometry/GeometricModel.ispc index 5097d484be..810cf89889 100644 --- a/ospray/geometry/GeometricModel.ispc +++ b/ospray/geometry/GeometricModel.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray @@ -7,7 +7,7 @@ #include "rkcommon/math/box.ih" #include "rkcommon/math/vec.ih" -export void *uniform GeometricModel_create(void *uniform cppE) +export void *uniform GeometricModel_create() { GeometricModel *uniform self = uniform new GeometricModel; diff --git a/ospray/geometry/Geometry.ih b/ospray/geometry/Geometry.ih index dece1679a6..375bcc8f12 100644 --- a/ospray/geometry/Geometry.ih +++ b/ospray/geometry/Geometry.ih @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -67,9 +67,6 @@ struct Geometry Geometry_GetAreasFct getAreas; Geometry_SampleAreaFct sampleArea; - //! pointer back to the C++-equivalent of this class - void *cppEquivalent; - //! number of primitives this geometry has int32 numPrimitives; }; @@ -90,5 +87,4 @@ inline void Geometry_setEmbreeUserGeometry(Geometry *uniform self, //! constructor for ispc-side Geometry object void Geometry_Constructor(Geometry *uniform geometry, - void *uniform cppEquivalent, uniform Geometry_postIntersectFct postIntersect); diff --git a/ospray/geometry/Geometry.ispc b/ospray/geometry/Geometry.ispc index 2c72f8ce96..26991dd721 100644 --- a/ospray/geometry/Geometry.ispc +++ b/ospray/geometry/Geometry.ispc @@ -1,13 +1,11 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "Geometry.ih" -void Geometry_Constructor(Geometry *uniform self, - void *uniform cppEquivalent, - uniform Geometry_postIntersectFct postIntersect) +void Geometry_Constructor( + Geometry *uniform self, uniform Geometry_postIntersectFct postIntersect) { - self->cppEquivalent = cppEquivalent; self->numPrimitives = 0; self->postIntersect = postIntersect; self->sampleArea = NULL; diff --git a/ospray/geometry/Isosurfaces.cpp b/ospray/geometry/Isosurfaces.cpp index e7d84a52fe..55a01fc353 100644 --- a/ospray/geometry/Isosurfaces.cpp +++ b/ospray/geometry/Isosurfaces.cpp @@ -14,7 +14,7 @@ namespace ospray { Isosurfaces::Isosurfaces() { - ispcEquivalent = ispc::Isosurfaces_create(this); + ispcEquivalent = ispc::Isosurfaces_create(); } Isosurfaces::~Isosurfaces() diff --git a/ospray/geometry/Isosurfaces.ispc b/ospray/geometry/Isosurfaces.ispc index 125c5081e4..a983b06032 100644 --- a/ospray/geometry/Isosurfaces.ispc +++ b/ospray/geometry/Isosurfaces.ispc @@ -132,11 +132,10 @@ static void Isosurfaces_postIntersect(const Geometry *uniform geometry, } } -export void *uniform Isosurfaces_create(void *uniform cppEquivalent) +export void *uniform Isosurfaces_create() { uniform Isosurfaces *uniform isosurfaces = uniform new uniform Isosurfaces; - Geometry_Constructor( - &isosurfaces->super, cppEquivalent, Isosurfaces_postIntersect); + Geometry_Constructor(&isosurfaces->super, Isosurfaces_postIntersect); return isosurfaces; } diff --git a/ospray/geometry/Mesh.cpp b/ospray/geometry/Mesh.cpp index 487e08df0c..21589a23b9 100644 --- a/ospray/geometry/Mesh.cpp +++ b/ospray/geometry/Mesh.cpp @@ -13,7 +13,7 @@ namespace ospray { Mesh::Mesh() { - ispcEquivalent = ispc::Mesh_create(this); + ispcEquivalent = ispc::Mesh_create(); } std::string Mesh::toString() const diff --git a/ospray/geometry/Mesh.ispc b/ospray/geometry/Mesh.ispc index 72197132b0..69d8e14613 100644 --- a/ospray/geometry/Mesh.ispc +++ b/ospray/geometry/Mesh.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2019 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray @@ -204,8 +204,8 @@ SampleAreaRes Mesh_sampleArea(const Geometry *uniform const _self, if (index.z != index.w) { const vec3f d = get_vec3f(self->vertex, index.w); // painfully slow: re-calculate areas to decide which triangle to sample - const vec3f e3 = xfmVector(xfm, d - b); - const vec3f m2 = cross(e3, e2); + const vec3f e3 = xfmVector(xfm, d - c); + const vec3f m2 = cross(e2, e3); const float a1 = length(m1); const float a2 = length(m2); const float p1 = a1 * rcp(a1 + a2); @@ -216,7 +216,7 @@ SampleAreaRes Mesh_sampleArea(const Geometry *uniform const _self, sp.x = (s.x - p1) * rcp(1.f - p1); // reproject v0 = d; v1 = c; - v2 = b; + v2 = a; res.normal = m2; } } @@ -247,15 +247,15 @@ void Mesh_getAreas(const Geometry *const uniform _self, areas[i] = 0.5f * length(cross(e1, e2)); if (!self->is_triangleMesh) { const uniform vec3f d = get_vec3f(self->vertex, index.w); - const uniform vec3f e3 = xfmVector(xfm, d - b); + const uniform vec3f e3 = xfmVector(xfm, d - c); areas[i] += 0.5f * length(cross(e2, e3)); } } } -void Mesh_Constructor(Mesh *uniform self, void *uniform cppEquivalent) +void Mesh_Constructor(Mesh *uniform self) { - Geometry_Constructor(&self->super, cppEquivalent, NULL); + Geometry_Constructor(&self->super, NULL); self->super.getAreas = Mesh_getAreas; self->super.sampleArea = Mesh_sampleArea; Data1D_Constructor(&self->index); @@ -265,10 +265,10 @@ void Mesh_Constructor(Mesh *uniform self, void *uniform cppEquivalent) Data1D_Constructor(&self->texcoord); } -export void *uniform Mesh_create(void *uniform cppEquivalent) +export void *uniform Mesh_create() { Mesh *uniform self = uniform new Mesh; - Mesh_Constructor(self, cppEquivalent); + Mesh_Constructor(self); return self; } diff --git a/ospray/geometry/Planes.cpp b/ospray/geometry/Planes.cpp index 9ad9d963c0..d329f3f1e7 100644 --- a/ospray/geometry/Planes.cpp +++ b/ospray/geometry/Planes.cpp @@ -14,7 +14,7 @@ namespace ospray { Planes::Planes() { - ispcEquivalent = ispc::Planes_create(this); + ispcEquivalent = ispc::Planes_create(); } std::string Planes::toString() const diff --git a/ospray/geometry/Planes.ispc b/ospray/geometry/Planes.ispc index 10c840fd7e..21595d0e0d 100644 --- a/ospray/geometry/Planes.ispc +++ b/ospray/geometry/Planes.ispc @@ -1,4 +1,4 @@ -// Copyright 2019-2020 Intel Corporation +// Copyright 2019-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray @@ -113,11 +113,11 @@ static void Planes_postIntersect(const Geometry *uniform geometry, dg.Ng = dg.Ns = ray.Ng; } -export void *uniform Planes_create(void *uniform cppEquivalent) +export void *uniform Planes_create() { Planes *uniform self = uniform new Planes; - Geometry_Constructor(&self->super, cppEquivalent, Planes_postIntersect); + Geometry_Constructor(&self->super, Planes_postIntersect); Data1D_Constructor(&self->coeffs); Data1D_Constructor(&self->bounds); diff --git a/ospray/geometry/Spheres.cpp b/ospray/geometry/Spheres.cpp index a64a9b54b9..e553c73563 100644 --- a/ospray/geometry/Spheres.cpp +++ b/ospray/geometry/Spheres.cpp @@ -12,7 +12,7 @@ namespace ospray { Spheres::Spheres() { - ispcEquivalent = ispc::Spheres_create(this); + ispcEquivalent = ispc::Spheres_create(); } std::string Spheres::toString() const diff --git a/ospray/geometry/Spheres.ispc b/ospray/geometry/Spheres.ispc index 37169b3955..06130d1ab0 100644 --- a/ospray/geometry/Spheres.ispc +++ b/ospray/geometry/Spheres.ispc @@ -143,9 +143,9 @@ void Spheres_getAreas(const Geometry *const uniform _self, } } -void Spheres_Constructor(Spheres *uniform self, void *uniform cppEquivalent) +void Spheres_Constructor(Spheres *uniform self) { - Geometry_Constructor(&self->super, cppEquivalent, Spheres_postIntersect); + Geometry_Constructor(&self->super, Spheres_postIntersect); self->super.getAreas = Spheres_getAreas; self->super.sampleArea = Spheres_sampleArea; Data1D_Constructor(&self->vertex); @@ -154,10 +154,10 @@ void Spheres_Constructor(Spheres *uniform self, void *uniform cppEquivalent) self->global_radius = 0.01; } -export void *uniform Spheres_create(void *uniform cppEquivalent) +export void *uniform Spheres_create() { Spheres *uniform self = uniform new Spheres; - Spheres_Constructor(self, cppEquivalent); + Spheres_Constructor(self); return self; } diff --git a/ospray/geometry/Subdivision.cpp b/ospray/geometry/Subdivision.cpp index e467f5c64c..46a9ec114e 100644 --- a/ospray/geometry/Subdivision.cpp +++ b/ospray/geometry/Subdivision.cpp @@ -13,7 +13,7 @@ namespace ospray { Subdivision::Subdivision() { - ispcEquivalent = ispc::Subdivision_create(this); + ispcEquivalent = ispc::Subdivision_create(); } std::string Subdivision::toString() const diff --git a/ospray/geometry/Subdivision.ispc b/ospray/geometry/Subdivision.ispc index 660789aef3..0cc381de74 100644 --- a/ospray/geometry/Subdivision.ispc +++ b/ospray/geometry/Subdivision.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2019 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray @@ -66,19 +66,18 @@ static void Subdivision_postIntersect(const Geometry *uniform _self, } } -void Subdivision_Constructor( - uniform Subdivision *uniform mesh, void *uniform cppEquivalent) +void Subdivision_Constructor(uniform Subdivision *uniform mesh) { - Geometry_Constructor(&mesh->super, cppEquivalent, Subdivision_postIntersect); + Geometry_Constructor(&mesh->super, Subdivision_postIntersect); mesh->geom = NULL; mesh->flagMask = 0; } -export void *uniform Subdivision_create(void *uniform cppEquivalent) +export void *uniform Subdivision_create() { Subdivision *uniform mesh = uniform new Subdivision; - Subdivision_Constructor(mesh, cppEquivalent); + Subdivision_Constructor(mesh); return mesh; } diff --git a/ospray/include/ospray/OSPEnums.h b/ospray/include/ospray/OSPEnums.h index 23943325d8..59cb65c71f 100644 --- a/ospray/include/ospray/OSPEnums.h +++ b/ospray/include/ospray/OSPEnums.h @@ -157,6 +157,8 @@ typedef enum OSP_AFFINE2F, OSP_AFFINE3F, + OSP_QUATF, + // Guard value. OSP_UNKNOWN = 9999999 } OSPDataType; @@ -283,6 +285,19 @@ typedef enum OSP_STEREO_UNKNOWN = 255 } OSPStereoMode; +typedef enum +#if __cplusplus >= 201103L + : uint8_t +#endif +{ + OSP_SHUTTER_GLOBAL, + OSP_SHUTTER_ROLLING_RIGHT, + OSP_SHUTTER_ROLLING_LEFT, + OSP_SHUTTER_ROLLING_DOWN, + OSP_SHUTTER_ROLLING_UP, + OSP_SHUTTER_UNKNOWN = 255 +} OSPShutterType; + typedef enum #if __cplusplus >= 201103L : uint8_t diff --git a/ospray/include/ospray/ospray_cpp/Traits.h b/ospray/include/ospray/ospray_cpp/Traits.h index 01d8c4084f..d6f81f28e7 100644 --- a/ospray/include/ospray/ospray_cpp/Traits.h +++ b/ospray/include/ospray/ospray_cpp/Traits.h @@ -71,6 +71,7 @@ OSPTYPEFOR_SPECIALIZATION(OSPFrameBufferChannel, OSP_INT); OSPTYPEFOR_SPECIALIZATION(OSPSyncEvent, OSP_INT); OSPTYPEFOR_SPECIALIZATION(OSPUnstructuredCellType, OSP_UCHAR); OSPTYPEFOR_SPECIALIZATION(OSPStereoMode, OSP_UCHAR); +OSPTYPEFOR_SPECIALIZATION(OSPShutterType, OSP_UCHAR); OSPTYPEFOR_SPECIALIZATION(OSPCurveType, OSP_UCHAR); OSPTYPEFOR_SPECIALIZATION(OSPCurveBasis, OSP_UCHAR); OSPTYPEFOR_SPECIALIZATION(OSPAMRMethod, OSP_UCHAR); diff --git a/ospray/include/ospray/ospray_cpp/ext/rkcommon.h b/ospray/include/ospray/ospray_cpp/ext/rkcommon.h index 6fe01ffbf1..fe41e44573 100644 --- a/ospray/include/ospray/ospray_cpp/ext/rkcommon.h +++ b/ospray/include/ospray/ospray_cpp/ext/rkcommon.h @@ -53,6 +53,7 @@ OSPTYPEFOR_SPECIALIZATION(rkcommon::math::linear2f, OSP_LINEAR2F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::linear3f, OSP_LINEAR3F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::affine2f, OSP_AFFINE2F); OSPTYPEFOR_SPECIALIZATION(rkcommon::math::affine3f, OSP_AFFINE3F); +OSPTYPEFOR_SPECIALIZATION(rkcommon::math::quatf, OSP_QUATF); #ifdef OSPRAY_RKCOMMON_DEFINITIONS OSPTYPEFOR_DEFINITION(rkcommon::math::vec2uc); @@ -97,6 +98,7 @@ OSPTYPEFOR_DEFINITION(rkcommon::math::linear2f); OSPTYPEFOR_DEFINITION(rkcommon::math::linear3f); OSPTYPEFOR_DEFINITION(rkcommon::math::affine2f); OSPTYPEFOR_DEFINITION(rkcommon::math::affine3f); +OSPTYPEFOR_DEFINITION(rkcommon::math::quatf); #endif } // namespace ospray diff --git a/ospray/ispc_symbols.txt b/ospray/ispc_symbols.txt index 945370f4f3..4355965eb0 100644 --- a/ospray/ispc_symbols.txt +++ b/ospray/ispc_symbols.txt @@ -2,15 +2,15 @@ Distribution2D_create___s_5B__c_unvec2i_5D_un_3C_unf_3E_, Distribution2D_destroy___un_3C_s_5B_unDistribution2D_5D__3E_, Distribution2D_pdf___un_3C_s_5B__c_unDistribution2D_5D__3E_REFs_5B__c_vyvec2f_5D_, Distribution2D_sample___un_3C_s_5B__c_unDistribution2D_5D__3E_REFs_5B__c_vyvec2f_5D_, -FrameBuffer_Constructor___un_3C_s_5B_unFrameBuffer_5D__3E_un_3C_unv_3E_, +FrameBuffer_Constructor___un_3C_s_5B_unFrameBuffer_5D__3E_, FrameBuffer_set___un_3C_s_5B_unFrameBuffer_5D__3E_CunuCunuuni, -Geometry_Constructor___un_3C_s_5B_unGeometry_5D__3E_un_3C_unv_3E_un_3C____un_3C_s_5B__c_unGeometry_5D__3E_REFs_5B_vyDifferentialGeometry_5D_REFs_5B__c_vyRay_5D_unI_3E_, -Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_CvyfCvyf, -Renderer_Constructor___un_3C_s_5B_unRenderer_5D__3E_un_3C_unv_3E_, +Geometry_Constructor___un_3C_s_5B_unGeometry_5D__3E_un_3C____un_3C_s_5B__c_unGeometry_5D__3E_REFs_5B_vyDifferentialGeometry_5D_REFs_5B__c_vyRay_5D_unI_3E_, +Light_eval___un_3C_s_5B__c_unLight_5D__3E_REFs_5B__c_vyDifferentialGeometry_5D_REFs_5B__c_vyvec3f_5D_CvyfCvyfCvyf, +Renderer_Constructor___un_3C_s_5B_unRenderer_5D__3E_, Renderer_getBackground___un_3C_s_5B__c_unRenderer_5D__3E_REFs_5B__c_vyvec2f_5D_, Renderer_getMaxDepth___un_3C_s_5B__c_unRenderer_5D__3E_REFs_5B__c_vyvec2f_5D_, -Volume_Constructor___un_3C_s_5B_unVolume_5D__3E_un_3C_unv_3E_, -World_Constructor___un_3C_s_5B_unWorld_5D__3E_un_3C_unv_3E_, +Volume_Constructor___un_3C_s_5B_unVolume_5D__3E_, +World_Constructor___un_3C_s_5B_unWorld_5D__3E_, clippingIntersectionFilterV___UM_un_3C_s_5B__c_unRTCFilterFunctionNArguments_5D__3E_, delete_uniform___un_3C_unv_3E_, delete_uniform_, diff --git a/ospray/lights/AmbientLight.cpp b/ospray/lights/AmbientLight.cpp index b6815ab357..2eea6e1a0e 100644 --- a/ospray/lights/AmbientLight.cpp +++ b/ospray/lights/AmbientLight.cpp @@ -3,12 +3,16 @@ #include "AmbientLight.h" #include "lights/AmbientLight_ispc.h" +#include "lights/Light_ispc.h" namespace ospray { -AmbientLight::AmbientLight() +void *AmbientLight::createIE(const void *instance) const { - ispcEquivalent = ispc::AmbientLight_create(); + void *ie = ispc::AmbientLight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::AmbientLight_set(ie, (ispc::vec3f &)radiance); + return ie; } std::string AmbientLight::toString() const @@ -21,7 +25,6 @@ void AmbientLight::commit() Light::commit(); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_RADIANCE); processIntensityQuantityType(); - ispc::AmbientLight_set(getIE(), (ispc::vec3f &)radiance); } void AmbientLight::processIntensityQuantityType() diff --git a/ospray/lights/AmbientLight.h b/ospray/lights/AmbientLight.h index 5bcd3e1ed4..e95f2b4712 100644 --- a/ospray/lights/AmbientLight.h +++ b/ospray/lights/AmbientLight.h @@ -10,12 +10,13 @@ namespace ospray { //! an AmbientLight is a constant light that is present everywhere struct OSPRAY_SDK_INTERFACE AmbientLight : public Light { - AmbientLight(); + AmbientLight() = default; virtual ~AmbientLight() override = default; + virtual void *createIE(const void *instance) const override; virtual std::string toString() const override; virtual void commit() override; - vec3f radiance{1.0f, 1.0f, 1.0f}; //!< emitted radiance of the AmbientLight + vec3f radiance{1.f}; //!< emitted radiance of the AmbientLight private: void processIntensityQuantityType(); diff --git a/ospray/lights/AmbientLight.ispc b/ospray/lights/AmbientLight.ispc index 3601151c4b..0acbbade66 100644 --- a/ospray/lights/AmbientLight.ispc +++ b/ospray/lights/AmbientLight.ispc @@ -16,7 +16,7 @@ struct AmbientLight // XXX importance sampling is only done into the positive hemisphere // ==> poor support for translucent materials -Light_SampleRes AmbientLight_sample(const uniform Light *uniform super, +Light_SampleRes AmbientLight_sample(const Light *uniform super, const DifferentialGeometry &dg, const vec2f &s, const float) @@ -38,11 +38,12 @@ Light_SampleRes AmbientLight_sample(const uniform Light *uniform super, return res; } -Light_EvalRes AmbientLight_eval(const uniform Light *uniform super, +Light_EvalRes AmbientLight_eval(const Light *uniform super, const DifferentialGeometry &dg, const vec3f &dir, const float, - const float maxDist) + const float maxDist, + const float) { uniform AmbientLight *uniform self = (uniform AmbientLight * uniform) super; Light_EvalRes res; diff --git a/ospray/lights/CylinderCapSolidAngleTable.ih b/ospray/lights/CylinderCapSolidAngleTable.ih new file mode 100644 index 0000000000..8a50fa9224 --- /dev/null +++ b/ospray/lights/CylinderCapSolidAngleTable.ih @@ -0,0 +1,1381 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +const uniform float CylCapSolidAngleTable[] = {0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 1.324344735105687941e-04, + 1.522660324370707656e-04, + 1.573041622823640709e-04, + 1.592206333250290138e-04, + 1.601378902436257539e-04, + 1.606445666452721154e-04, + 1.609530122796813971e-04, + 1.611544049267169627e-04, + 1.612930298554018850e-04, + 1.613924640850384403e-04, + 0.000000000000000000e+00, + 2.079389560425832215e-04, + 2.418569419427302593e-04, + 2.505750744399992008e-04, + 2.539021985766657676e-04, + 2.554967263084124691e-04, + 2.563780999808024769e-04, + 2.569148511271038141e-04, + 2.572653939717546990e-04, + 2.575067219119174088e-04, + 2.576798431415581146e-04, + 0.000000000000000000e+00, + 2.353557656252160569e-04, + 2.747346643900388640e-04, + 2.848935470945746515e-04, + 2.887745253091539743e-04, + 2.906352752629875590e-04, + 2.916640219201449709e-04, + 2.922905986733082559e-04, + 2.926998362668255336e-04, + 2.929815863886020013e-04, + 2.931837124451351423e-04, + 0.000000000000000000e+00, + 2.471449816382869638e-04, + 2.889245245841044274e-04, + 2.997188457314994055e-04, + 3.038443349008019688e-04, + 3.058226611542990336e-04, + 3.069165077355631341e-04, + 3.075827682434436705e-04, + 3.080179382636986712e-04, + 3.083175485132807580e-04, + 3.085324904882438043e-04, + 0.000000000000000000e+00, + 2.530989951023317479e-04, + 2.961026955154546559e-04, + 3.072215014833809088e-04, + 3.114719015023532499e-04, + 3.135103031200374511e-04, + 3.146374152658422646e-04, + 3.153239548826361808e-04, + 3.157723772518377043e-04, + 3.160811148227334185e-04, + 3.163026063990813071e-04, + 0.000000000000000000e+00, + 2.564809353247177529e-04, + 3.001834485672567800e-04, + 3.114876213887419424e-04, + 3.158093939369322942e-04, + 3.178821249299264469e-04, + 3.190282471529652577e-04, + 3.197263758519848921e-04, + 3.201823717808763401e-04, + 3.204963255635058170e-04, + 3.207215602277217921e-04, + 0.000000000000000000e+00, + 2.585734616717737873e-04, + 3.027096121304737692e-04, + 3.141288595804324390e-04, + 3.184949452806097050e-04, + 3.205889914938048245e-04, + 3.217469174426753568e-04, + 3.224522421353280457e-04, + 3.229129407487705650e-04, + 3.232301334775221466e-04, + 3.234576923788846708e-04, + 0.000000000000000000e+00, + 2.599538312189582433e-04, + 3.043765623677294522e-04, + 3.158718799923146523e-04, + 3.202672612340357614e-04, + 3.223753994528717292e-04, + 3.235411292573714057e-04, + 3.242512115177207201e-04, + 3.247150192879226017e-04, + 3.250343534384156656e-04, + 3.252634490080406069e-04, + 0.000000000000000000e+00, + 2.609105553783080608e-04, + 3.055321579139339515e-04, + 3.170802734117933344e-04, + 3.214959888194799482e-04, + 3.236139085749938256e-04, + 3.247850552478668976e-04, + 3.254984398861687973e-04, + 3.259644058287874437e-04, + 3.262852264175356508e-04, + 3.265153886461359851e-04, + 0.000000000000000000e+00, + 2.616001385399520417e-04, + 3.063652066180995947e-04, + 3.179514151471859074e-04, + 3.223818019526446471e-04, + 3.245067793375723542e-04, + 3.256818344500071673e-04, + 3.263976018676227695e-04, + 3.268651250102232240e-04, + 3.271870181202876562e-04, + 3.274179499846075663e-04, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 3.518709244702191308e-04, + 4.683165637320721247e-04, + 5.112354179907870229e-04, + 5.303183442801986426e-04, + 5.401600925084595840e-04, + 5.458213572572553993e-04, + 5.493521299147061847e-04, + 5.516935337888750988e-04, + 5.533222474443736652e-04, + 5.544992454144986914e-04, + 0.000000000000000000e+00, + 7.564274540073267963e-04, + 1.047422775041331137e-03, + 1.157895188902293045e-03, + 1.207568980015362057e-03, + 1.233320234019417332e-03, + 1.248173894431466383e-03, + 1.257452756424457408e-03, + 1.263612327455216049e-03, + 1.267900004232375925e-03, + 1.271000042202091859e-03, + 0.000000000000000000e+00, + 1.003462835547388327e-03, + 1.419131877800553724e-03, + 1.579135209145570828e-03, + 1.651485122984807079e-03, + 1.689091300932595669e-03, + 1.710813997450975378e-03, + 1.724395352762325738e-03, + 1.733415930831165271e-03, + 1.739697458797044528e-03, + 1.744240251854955927e-03, + 0.000000000000000000e+00, + 1.143834031312154515e-03, + 1.636939564350985447e-03, + 1.828099798065667934e-03, + 1.914790679706731419e-03, + 1.959913807652678436e-03, + 1.985998222441378788e-03, + 2.002313918709211060e-03, + 2.013153735013494244e-03, + 2.020703571863047363e-03, + 2.026164358059563773e-03, + 0.000000000000000000e+00, + 1.226309947336103739e-03, + 1.767333086735097024e-03, + 1.977908109642293084e-03, + 2.073560818586137576e-03, + 2.123387906682048902e-03, + 2.152203878442562283e-03, + 2.170232757489803758e-03, + 2.182212740185190698e-03, + 2.190557619589210761e-03, + 2.196593933475704443e-03, + 0.000000000000000000e+00, + 1.277461271335418244e-03, + 1.849154837636200191e-03, + 2.072208855142282369e-03, + 2.173631403692885631e-03, + 2.226489455102349368e-03, + 2.257066262878798871e-03, + 2.276199798626163916e-03, + 2.288915083509291803e-03, + 2.297772751394711651e-03, + 2.304180300992577507e-03, + 0.000000000000000000e+00, + 1.310886684522754274e-03, + 1.903030842774131731e-03, + 2.134428080685532754e-03, + 2.239712232707347355e-03, + 2.294599846438157443e-03, + 2.326356050655218645e-03, + 2.346229600079902024e-03, + 2.359437518863661924e-03, + 2.368638766816207920e-03, + 2.375295065567726085e-03, + 0.000000000000000000e+00, + 1.333742658498826388e-03, + 1.940061354761947118e-03, + 2.177251861166239286e-03, + 2.285219226091063632e-03, + 2.341517535968261950e-03, + 2.374093656364981327e-03, + 2.394481718982423898e-03, + 2.408032177838734678e-03, + 2.417472336517638778e-03, + 2.424301610494127707e-03, + 0.000000000000000000e+00, + 1.349981060688657973e-03, + 1.966465991084871863e-03, + 2.207816820003138340e-03, + 2.317711996277340217e-03, + 2.375024082451204169e-03, + 2.408189497312768039e-03, + 2.428947381262678857e-03, + 2.442744062634739140e-03, + 2.452355959253100376e-03, + 2.459309577158362136e-03, + 0.000000000000000000e+00, + 1.361894711241359206e-03, + 1.985889500491258477e-03, + 2.230316422217705225e-03, + 2.341637485555428909e-03, + 2.399699524599541254e-03, + 2.433300916004638680e-03, + 2.454332418834928586e-03, + 2.468311278606549232e-03, + 2.478050245966633217e-03, + 2.485095868809059950e-03, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 5.148143079474772456e-04, + 7.466963702743565669e-04, + 8.540924768223674864e-04, + 9.090308884320854026e-04, + 9.398167374470985059e-04, + 9.584482807966543567e-04, + 9.704531768272830951e-04, + 9.785903359863293554e-04, + 9.843379804579401558e-04, + 9.885378125159579969e-04, + 0.000000000000000000e+00, + 1.253514637562834185e-03, + 1.937381211125926810e-03, + 2.264953477267791799e-03, + 2.435076592709123963e-03, + 2.531146721947160651e-03, + 2.589542084462958128e-03, + 2.627268588474988235e-03, + 2.652884902384841648e-03, + 2.671000464765789419e-03, + 2.684248870354409826e-03, + 0.000000000000000000e+00, + 1.805645740500164045e-03, + 2.923239499370571155e-03, + 3.469880912448602625e-03, + 3.756492839361498873e-03, + 3.919162270565094107e-03, + 4.018327199393406657e-03, + 4.082508604594513660e-03, + 4.126139500491008902e-03, + 4.157019994337727252e-03, + 4.179616969615533410e-03, + 0.000000000000000000e+00, + 2.166031051752110529e-03, + 3.623367960760648290e-03, + 4.346786328097372240e-03, + 4.728425004110046147e-03, + 4.945730130634628727e-03, + 5.078450242993188049e-03, + 5.164449556490857511e-03, + 5.222957424495248274e-03, + 5.264389371789464193e-03, + 5.294719002811903302e-03, + 0.000000000000000000e+00, + 2.397429617633945256e-03, + 4.102067843197306288e-03, + 4.957450923063252100e-03, + 5.410593565507399588e-03, + 5.669169656332504782e-03, + 5.827292658623370661e-03, + 5.929831656028333210e-03, + 5.999627523881404835e-03, + 6.049070396274724981e-03, + 6.085273449131553547e-03, + 0.000000000000000000e+00, + 2.549368937648944372e-03, + 4.430824716323404980e-03, + 5.382479625796733787e-03, + 5.888099668579335061e-03, + 6.177049414622892871e-03, + 6.353896803602655276e-03, + 6.468638692124228234e-03, + 6.546767941194820209e-03, + 6.602127406276578521e-03, + 6.642669686120350990e-03, + 0.000000000000000000e+00, + 2.652478153375369910e-03, + 4.661169684101590209e-03, + 5.683180157940269719e-03, + 6.227324667582475638e-03, + 6.538617837456350834e-03, + 6.729254639632639874e-03, + 6.852989337057374501e-03, + 6.937262504145540881e-03, + 6.996985390082748058e-03, + 7.040728491883075507e-03, + 0.000000000000000000e+00, + 2.724833704580410364e-03, + 4.826576642897440102e-03, + 5.900647986915204257e-03, + 6.473397323717751048e-03, + 6.801306029919003925e-03, + 7.002205690658911200e-03, + 7.132636668749612469e-03, + 7.221486230823217362e-03, + 7.284459995566929316e-03, + 7.330588179434545208e-03, + 0.000000000000000000e+00, + 2.777193121512918500e-03, + 4.948313722212235519e-03, + 6.061549571150137879e-03, + 6.655874317352564358e-03, + 6.996329873173594109e-03, + 7.204984098087410804e-03, + 7.340476631155143199e-03, + 7.432786208671369500e-03, + 7.498218225694946310e-03, + 7.546150173259567884e-03, + 0.000000000000000000e+00, + 2.816127041162471301e-03, + 5.039991504078758511e-03, + 6.183207539771379095e-03, + 6.794081629995274256e-03, + 7.144169726016271968e-03, + 7.358780144991966012e-03, + 7.498161501484510751e-03, + 7.593129914869260755e-03, + 7.660451201529748164e-03, + 7.709769539512028799e-03, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 6.330630758403497406e-04, + 9.689183242194677158e-04, + 1.147393727860851259e-03, + 1.248824337567151690e-03, + 1.310016946721651813e-03, + 1.348979419893589016e-03, + 1.374985660749956928e-03, + 1.393060169151647334e-03, + 1.406061569536036938e-03, + 1.415691385285003075e-03, + 0.000000000000000000e+00, + 1.622982320300010717e-03, + 2.701938518079526844e-03, + 3.294702983947319502e-03, + 3.636918114345742345e-03, + 3.845154685284924660e-03, + 3.978419795121803000e-03, + 4.067657530720846307e-03, + 4.129812091727653317e-03, + 4.174588465907964896e-03, + 4.207789226664360865e-03, + 0.000000000000000000e+00, + 2.414795568233982399e-03, + 4.318654218803607940e-03, + 5.395581270951582339e-03, + 6.024765956700464144e-03, + 6.410139085803693605e-03, + 6.657744753022374652e-03, + 6.823970299633269967e-03, + 6.939946223429980035e-03, + 7.023596514313117274e-03, + 7.085675836419507052e-03, + 0.000000000000000000e+00, + 2.954155122638248490e-03, + 5.585884539816199715e-03, + 7.117112432957192758e-03, + 8.020644828942680507e-03, + 8.576903781303987090e-03, + 8.935395883314885268e-03, + 9.176532167816170080e-03, + 9.344994335701675356e-03, + 9.466613516980450227e-03, + 9.556931087201311556e-03, + 0.000000000000000000e+00, + 3.309622812366178578e-03, + 6.519673311726707082e-03, + 8.434770609219766069e-03, + 9.574480857880865101e-03, + 1.027907845340537626e-02, + 1.073426714901062028e-02, + 1.104091172683628087e-02, + 1.125535734483322503e-02, + 1.141028395754554135e-02, + 1.152539586104889095e-02, + 0.000000000000000000e+00, + 3.546872447411592976e-03, + 7.197122743859855031e-03, + 9.420419469569327187e-03, + 1.075305604061065762e-02, + 1.157974188162016853e-02, + 1.211483561693207055e-02, + 1.247574371943477312e-02, + 1.272833935428445591e-02, + 1.291092914697953946e-02, + 1.304664963401448372e-02, + 0.000000000000000000e+00, + 3.709598889376596823e-03, + 7.691126070511996801e-03, + 1.015658152587857292e-02, + 1.164308907444725101e-02, + 1.256778608267826794e-02, + 1.316724812456793008e-02, + 1.357195842639335667e-02, + 1.385538992174475091e-02, + 1.406035943214321848e-02, + 1.421276311649024952e-02, + 0.000000000000000000e+00, + 3.824618653025676183e-03, + 8.056429142161470464e-03, + 1.071114747813457953e-02, + 1.231942132085871340e-02, + 1.332210697903568782e-02, + 1.397293583788518541e-02, + 1.441266073211551826e-02, + 1.472076883805627061e-02, + 1.494366122753849543e-02, + 1.510943278865536921e-02, + 0.000000000000000000e+00, + 3.908276579859369312e-03, + 8.331238865437462504e-03, + 1.113438477823026213e-02, + 1.283912775213246968e-02, + 1.390388080150351847e-02, + 1.459568779448104647e-02, + 1.506338519389619802e-02, + 1.539122479106847657e-02, + 1.562845714833507524e-02, + 1.580492889957122241e-02, + 0.000000000000000000e+00, + 3.970714592225201359e-03, + 8.541660185314235709e-03, + 1.146212511353233467e-02, + 1.324374946206734009e-02, + 1.435815175165684396e-02, + 1.508280258434187455e-02, + 1.557294585420195346e-02, + 1.591663025057328193e-02, + 1.616538368357876149e-02, + 1.635045528411100887e-02, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 7.212811140121224915e-04, + 1.145742417107076683e-03, + 1.391883272944551518e-03, + 1.542798871459532314e-03, + 1.639473665637473324e-03, + 1.703890684308947186e-03, + 1.748374322168447757e-03, + 1.780089635894296744e-03, + 1.803348655089967922e-03, + 1.820833937754083587e-03, + 0.000000000000000000e+00, + 1.887340452230905439e-03, + 3.320212172265470454e-03, + 4.179485837867540250e-03, + 4.714296490400989546e-03, + 5.059805189507511798e-03, + 5.291228737426888033e-03, + 5.451582859600462815e-03, + 5.566174678315898364e-03, + 5.650350614937620086e-03, + 5.713706941678609041e-03, + 0.000000000000000000e+00, + 2.834448186751709845e-03, + 5.468555396175245331e-03, + 7.113650880673496810e-03, + 8.152108432206669683e-03, + 8.828034936984537062e-03, + 9.282851385270190700e-03, + 9.598942269980353242e-03, + 9.825292590586972782e-03, + 9.991807914818658445e-03, + 1.011727386957128084e-02, + 0.000000000000000000e+00, + 3.482562777897965905e-03, + 7.230836955609326079e-03, + 9.680161174012684097e-03, + 1.124972903795233570e-02, + 1.227878066863242502e-02, + 1.297412787946376073e-02, + 1.345868672328128825e-02, + 1.380631017143750527e-02, + 1.406237157233477565e-02, + 1.425549161837616485e-02, + 0.000000000000000000e+00, + 3.910125450455917764e-03, + 8.573986045328902544e-03, + 1.175344402795287270e-02, + 1.382224323503398154e-02, + 1.518830623356486054e-02, + 1.611506977648453215e-02, + 1.676250277269603420e-02, + 1.722774511293859862e-02, + 1.757084466358614303e-02, + 1.782982762043219122e-02, + 0.000000000000000000e+00, + 4.195478113700949578e-03, + 9.572553801176924421e-03, + 1.337208257744917743e-02, + 1.587981542579631339e-02, + 1.754687578908758691e-02, + 1.868205174785504685e-02, + 1.947689490705743071e-02, + 2.004892814257227054e-02, + 2.047122494349440380e-02, + 2.079023041572572797e-02, + 0.000000000000000000e+00, + 4.391139168102254839e-03, + 1.031374719492394315e-02, + 1.462190656340965102e-02, + 1.750115447916205519e-02, + 1.942679519129223223e-02, + 2.074244707635598123e-02, + 2.166554766725809281e-02, + 2.233078004469190095e-02, + 2.282233761806777214e-02, + 2.319391222302685795e-02, + 0.000000000000000000e+00, + 4.529394042038001507e-03, + 1.086901209427927791e-02, + 1.558799715383739869e-02, + 1.877549102780820545e-02, + 2.091854264573917224e-02, + 2.238703945070888088e-02, + 2.341923306400309213e-02, + 2.416396003589227695e-02, + 2.471470604294914372e-02, + 2.513126542062316809e-02, + 0.000000000000000000e+00, + 4.629923660528266829e-03, + 1.129079130639894755e-02, + 1.634022180551901460e-02, + 1.978126845756981306e-02, + 2.210521617926395482e-02, + 2.370169823405501863e-02, + 2.482559216036049274e-02, + 2.563730547928672401e-02, + 2.623801094619798019e-02, + 2.669258636203961088e-02, + 0.000000000000000000e+00, + 4.704936553889154868e-03, + 1.161612790425591360e-02, + 1.693193703735837441e-02, + 2.058118757044315530e-02, + 2.305512780417269536e-02, + 2.475831255654708379e-02, + 2.595891243272585233e-02, + 2.682677959716530183e-02, + 2.746942706560224698e-02, + 2.795595112510076627e-02, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 7.886277541261281585e-04, + 1.288083776318236454e-03, + 1.595231749729407802e-03, + 1.794205293561702830e-03, + 1.927825702307663612e-03, + 2.020359060251305031e-03, + 2.086251153426085976e-03, + 2.134382573814292295e-03, + 2.170362532143429047e-03, + 2.197824765211205296e-03, + 0.000000000000000000e+00, + 2.075871817031091186e-03, + 3.813224858676668438e-03, + 4.920759008805931922e-03, + 5.648430922382662728e-03, + 6.140991888636010421e-03, + 6.483794346710756648e-03, + 6.728708363724023034e-03, + 6.908018590856198314e-03, + 7.042280562632280763e-03, + 7.144883080190312166e-03, + 0.000000000000000000e+00, + 3.117381304854234102e-03, + 6.375259184681209869e-03, + 8.566777219774319649e-03, + 1.003128508041885303e-02, + 1.103089239346197181e-02, + 1.173004494238572525e-02, + 1.223118215498218871e-02, + 1.259891109331477341e-02, + 1.287470254726895934e-02, + 1.308571527942264771e-02, + 0.000000000000000000e+00, + 3.825717120065501992e-03, + 8.514634789312950161e-03, + 1.186896531448872714e-02, + 1.415911630965160581e-02, + 1.573767876663084361e-02, + 1.684782962166546383e-02, + 1.764629906813101543e-02, + 1.823356497228816389e-02, + 1.867472804716201196e-02, + 1.901267522803663790e-02, + 0.000000000000000000e+00, + 4.290824483525533355e-03, + 1.016390003634775122e-02, + 1.461213065387898837e-02, + 1.772098796640041857e-02, + 1.988756547327948099e-02, + 2.142046605735105358e-02, + 2.252707718259811323e-02, + 2.334296722288513662e-02, + 2.395691971003124227e-02, + 2.442781050823393529e-02, + 0.000000000000000000e+00, + 4.600251514432151904e-03, + 1.139909612452231005e-02, + 1.680079008919013392e-02, + 2.066199309645985402e-02, + 2.338320775886965769e-02, + 2.532056302592006203e-02, + 2.672449224496529011e-02, + 2.776218338397702309e-02, + 2.854439294144339029e-02, + 2.914508316732965232e-02, + 0.000000000000000000e+00, + 4.811966833600228761e-03, + 1.232039591725546043e-02, + 1.851919219488658980e-02, + 2.304017738419015388e-02, + 2.626031209934483884e-02, + 2.856675316168256346e-02, + 3.024437998247574491e-02, + 3.148741075694074659e-02, + 3.242599367838468888e-02, + 3.314764878185472857e-02, + 0.000000000000000000e+00, + 4.961345092670534258e-03, + 1.301288388128898389e-02, + 1.986461845266174545e-02, + 2.494866092839396338e-02, + 2.860454189137067935e-02, + 3.123772859020323631e-02, + 3.315969831138976254e-02, + 3.458705750859270012e-02, + 3.566654530130984602e-02, + 3.649749476986991620e-02, + 0.000000000000000000e+00, + 5.069848982399235808e-03, + 1.354013275348193990e-02, + 2.092263441641366295e-02, + 2.648029178931736449e-02, + 3.051020421836446103e-02, + 3.342730774392779075e-02, + 3.556323727608656782e-02, + 3.715283217135611354e-02, + 3.835677661573724112e-02, + 3.928450805609219609e-02, + 0.000000000000000000e+00, + 5.150749986807798275e-03, + 1.394751711739385114e-02, + 2.176135386663251986e-02, + 2.771490302859902846e-02, + 3.206294610534261846e-02, + 3.522414215931390230e-02, + 3.754529218616584757e-02, + 3.927598085625663704e-02, + 4.058851195179079274e-02, + 4.160088044039742666e-02, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 8.409049105883540254e-04, + 1.404128719459686852e-03, + 1.765188368639016882e-03, + 2.008796995337924253e-03, + 2.178544808847337338e-03, + 2.299906117061264327e-03, + 2.388668553265759636e-03, + 2.454952271330086699e-03, + 2.505405544133496552e-03, + 2.544488663735909248e-03, + 0.000000000000000000e+00, + 2.211276794768384218e-03, + 4.205942891278083295e-03, + 5.537393703907753963e-03, + 6.447998830919157189e-03, + 7.087164739749489059e-03, + 7.546231432481296901e-03, + 7.883021429449974318e-03, + 8.135064537221082734e-03, + 8.327214095147432785e-03, + 8.476235642834154330e-03, + 0.000000000000000000e+00, + 3.309415263687501968e-03, + 7.078555395920566561e-03, + 9.768119993488632094e-03, + 1.164596828840228429e-02, + 1.297644774436901641e-02, + 1.393714345522122089e-02, + 1.464436793760017820e-02, + 1.517488254254313260e-02, + 1.558001732315511534e-02, + 1.589461677611720899e-02, + 0.000000000000000000e+00, + 4.050730286239253436e-03, + 9.487235508271726903e-03, + 1.366709854910849904e-02, + 1.666953051899764879e-02, + 1.882431979081320220e-02, + 2.039106305104328165e-02, + 2.154933675325849257e-02, + 2.242064567410862255e-02, + 2.308734523799175001e-02, + 2.360580292793293400e-02, + 0.000000000000000000e+00, + 4.535286937466600360e-03, + 1.134611476159541089e-02, + 1.694721425714761781e-02, + 2.109867955125385372e-02, + 2.412438914252086272e-02, + 2.634309090146036078e-02, + 2.799179615553328698e-02, + 2.923620194935939651e-02, + 3.019059610352927900e-02, + 3.093402180179632283e-02, + 0.000000000000000000e+00, + 4.856764952963409966e-03, + 1.273813200608200392e-02, + 1.958802920526525604e-02, + 2.481999190609950404e-02, + 2.869531045468254674e-02, + 3.156345647461759885e-02, + 3.370696880367917564e-02, + 3.533092542090644078e-02, + 3.657964832387837484e-02, + 3.755415734009321521e-02, + 0.000000000000000000e+00, + 5.076341487001670601e-03, + 1.377588337266780205e-02, + 2.167490906914956716e-02, + 2.787110986356607437e-02, + 3.253221801062159552e-02, + 3.601408854351095812e-02, + 3.863157383647888854e-02, + 4.062237364604340262e-02, + 4.215733831870509957e-02, + 4.335758190036979182e-02, + 0.000000000000000000e+00, + 5.231086483603165568e-03, + 1.455546358066520454e-02, + 2.331654516634287452e-02, + 3.034659890518537698e-02, + 3.570968046632597148e-02, + 3.975117471924284607e-02, + 4.280664993000107138e-02, + 4.513950503188909891e-02, + 4.694305546941619778e-02, + 4.835607691153816223e-02, + 0.000000000000000000e+00, + 5.343398176252857866e-03, + 1.514871634855200627e-02, + 2.461199808645184520e-02, + 3.235060518899594145e-02, + 3.832736202473158160e-02, + 4.286730310131266902e-02, + 4.631777880203825914e-02, + 4.896176865226951197e-02, + 5.101111340104958619e-02, + 5.261972191992605324e-02, + 0.000000000000000000e+00, + 5.427089881340583372e-03, + 1.560689566768099813e-02, + 2.564164045356884594e-02, + 3.397721033727196110e-02, + 4.048372286997169167e-02, + 4.546111243969969823e-02, + 4.926218276911005500e-02, + 5.218451437880067267e-02, + 5.445499338070784040e-02, + 5.624029962279188805e-02, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 8.819928697035788563e-04, + 1.499808675898415189e-03, + 1.908225105418749840e-03, + 2.192393595377619547e-03, + 2.396239154598805640e-03, + 2.545843228278368321e-03, + 2.657792261706820678e-03, + 2.743043405345950078e-03, + 2.809018628625797181e-03, + 2.860843823986314143e-03, + 0.000000000000000000e+00, + 2.309604703834023005e-03, + 4.519723640833095586e-03, + 6.050185724869521636e-03, + 7.129594126592466927e-03, + 7.909145032571158682e-03, + 8.483635400819646358e-03, + 8.914722305197662205e-03, + 9.243647113839898247e-03, + 9.498565711386340940e-03, + 9.699027573244036263e-03, + 0.000000000000000000e+00, + 3.441993626605958489e-03, + 7.621663068032521332e-03, + 1.075187088001746533e-02, + 1.301549353337524799e-02, + 1.466792515089303424e-02, + 1.589275460458437761e-02, + 1.681515189784345277e-02, + 1.752066328498773709e-02, + 1.806838645729005530e-02, + 1.849965608010141135e-02, + 0.000000000000000000e+00, + 4.201738591611474220e-03, + 1.021713787947973323e-02, + 1.511696034060911083e-02, + 1.878711774109946553e-02, + 2.151020004638156888e-02, + 2.354613908580450304e-02, + 2.508729736790969028e-02, + 2.627003716202713779e-02, + 2.719038558162066924e-02, + 2.791626932314798457e-02, + 0.000000000000000000e+00, + 4.696687057928286904e-03, + 1.221429317381030229e-02, + 1.880444680860411319e-02, + 2.393282904286624796e-02, + 2.781434330205767233e-02, + 3.074895459913826179e-02, + 3.298548417575247749e-02, + 3.470945032645365858e-02, + 3.605501455116834342e-02, + 3.711856949032635994e-02, + 0.000000000000000000e+00, + 5.024435445393716539e-03, + 1.370594897871207744e-02, + 2.177985357316791770e-02, + 2.829246297011497879e-02, + 3.332552982113546475e-02, + 3.717851557333125279e-02, + 4.013808584602007734e-02, + 4.243127373289958676e-02, + 4.422757557670908835e-02, + 4.565108540542069104e-02, + 0.000000000000000000e+00, + 5.248035000733364611e-03, + 1.481567994456567047e-02, + 2.413389556736813407e-02, + 3.188929233515737371e-02, + 3.800301313475547976e-02, + 4.274262540563071588e-02, + 4.641334665795533027e-02, + 4.927350398863060421e-02, + 5.152275429342469820e-02, + 5.331031390248602841e-02, + 0.000000000000000000e+00, + 5.405496525820404664e-03, + 1.564801264267183870e-02, + 2.598681309218115604e-02, + 3.482120856979355195e-02, + 4.191118616424213683e-02, + 4.747363860785879658e-02, + 5.181659128966996375e-02, + 5.521960355379183089e-02, + 5.790653639116814105e-02, + 6.004825723819562366e-02, + 0.000000000000000000e+00, + 5.519721114539997281e-03, + 1.628064506019030397e-02, + 2.744943573409894255e-02, + 3.720313374981960158e-02, + 4.515400169935586405e-02, + 5.145999443455393646e-02, + 5.642095558640027736e-02, + 6.032922389709499678e-02, + 6.342720140861805855e-02, + 6.590376215915122460e-02, + 0.000000000000000000e+00, + 5.604807172925481938e-03, + 1.676878494454391022e-02, + 2.861211162654109935e-02, + 3.914175575307056454e-02, + 4.784084480994308525e-02, + 5.480714130841123771e-02, + 6.032558356131666188e-02, + 6.469486252637586532e-02, + 6.817107846412569228e-02, + 7.095772783148365792e-02, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 9.146083830287583642e-04, + 1.579466856061922161e-03, + 2.029488185763906292e-03, + 2.350141314220413613e-03, + 2.585532485783417593e-03, + 2.762039714184235176e-03, + 2.896705517765219007e-03, + 3.001026726814950626e-03, + 3.082973043715643222e-03, + 3.148178209924899686e-03, + 0.000000000000000000e+00, + 2.381923649558957169e-03, + 4.771564976138984587e-03, + 6.477660849154662052e-03, + 7.710637905019568188e-03, + 8.621560397996115566e-03, + 9.307164465156857192e-03, + 9.831533372309179952e-03, + 1.023844968121729107e-02, + 1.055849739339442817e-02, + 1.081340653973560974e-02, + 0.000000000000000000e+00, + 3.535394475345355822e-03, + 8.041696433516517042e-03, + 1.155489757345273122e-02, + 1.417049695167621123e-02, + 1.612711144661847784e-02, + 1.760921674056959568e-02, + 1.874710505678665179e-02, + 1.963233381291838026e-02, + 2.032980615371487304e-02, + 2.088603811178604483e-02, + 0.000000000000000000e+00, + 4.305761889290633283e-03, + 1.076538989099030258e-02, + 1.627663864269695074e-02, + 2.055251087807164270e-02, + 2.381497047720437799e-02, + 2.631238608553041619e-02, + 2.824170594523811931e-02, + 2.974859390027098302e-02, + 3.093907698776395335e-02, + 3.189031186244749294e-02, + 0.000000000000000000e+00, + 4.806493448779084431e-03, + 1.285280603117577684e-02, + 2.026429933233919040e-02, + 2.626995208535578760e-02, + 3.096391948219001308e-02, + 3.460749201784794199e-02, + 3.744638174270890907e-02, + 3.967603736834866834e-02, + 4.144423551014510959e-02, + 4.286092010174952921e-02, + 0.000000000000000000e+00, + 5.137662194585928405e-03, + 1.440720060696200518e-02, + 2.347862141063761232e-02, + 3.112856878432999561e-02, + 3.725816810538268992e-02, + 4.209069272126627487e-02, + 4.589397915749048040e-02, + 4.890130600633454949e-02, + 5.129749328254108037e-02, + 5.322387085040267835e-02, + 0.000000000000000000e+00, + 5.363429462624667160e-03, + 1.556110912888218796e-02, + 2.601869761382172297e-02, + 3.514450605321959437e-02, + 4.262920439588310795e-02, + 4.862302407365758777e-02, + 5.339053744130816542e-02, + 5.718817021170410214e-02, + 6.023003236992537784e-02, + 6.268496109512571024e-02, + 0.000000000000000000e+00, + 5.522343068669122342e-03, + 1.642522820790207408e-02, + 2.801586174906607260e-02, + 3.842179910921796060e-02, + 4.713538023233512786e-02, + 5.421668062745129552e-02, + 5.990809922566721346e-02, + 6.447563789424214098e-02, + 6.815420154092251270e-02, + 7.113509806267460933e-02, + 0.000000000000000000e+00, + 5.637584583779466779e-03, + 1.708127107996294802e-02, + 2.959086256581842239e-02, + 4.108621225472355171e-02, + 5.088622500212632016e-02, + 5.895706762814859753e-02, + 6.550738910549069871e-02, + 7.080215473675173510e-02, + 7.508935702281148428e-02, + 7.857763544664297939e-02, + 0.000000000000000000e+00, + 5.723409014370593739e-03, + 1.758704298274597899e-02, + 3.084188567563100197e-02, + 4.325572603690309298e-02, + 5.400162213255688126e-02, + 6.295602341423879589e-02, + 7.028825445802376615e-02, + 7.625490487763730840e-02, + 8.111082141276432234e-02, + 8.507736160994681940e-02, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 0.000000000000000000e+00, + 9.407175649717369140e-04, + 1.646344177610784259e-03, + 2.133022545851611784e-03, + 2.486368129260723737e-03, + 2.750626368692035174e-03, + 2.952322151141739161e-03, + 3.108750693981697597e-03, + 3.231745439960234754e-03, + 3.329650157514978896e-03, + 3.408471310692032588e-03, + 0.000000000000000000e+00, + 2.435828950196621163e-03, + 4.974727915303407688e-03, + 6.835291369405445752e-03, + 8.206972502698303001e-03, + 9.239229846344653926e-03, + 1.002978347962796626e-02, + 1.064423803298986983e-02, + 1.112808885472833624e-02, + 1.151365936870699970e-02, + 1.182433136920202181e-02, + 0.000000000000000000e+00, + 3.602555256674739963e-03, + 8.368077737178299114e-03, + 1.221054718799924679e-02, + 1.514283600888060091e-02, + 1.738166808092690349e-02, + 1.910867140094551359e-02, + 2.045652908204030271e-02, + 2.152068013770556260e-02, + 2.237019693720150235e-02, + 2.305557241678675082e-02, + 0.000000000000000000e+00, + 4.379251827572607468e-03, + 1.117978193107454360e-02, + 1.720234016040313521e-02, + 2.201620195010858469e-02, + 2.577798151457473541e-02, + 2.871637658705877144e-02, + 3.102661519549590463e-02, + 3.285907988714027728e-02, + 3.432651952566168757e-02, + 3.551303224345320891e-02, + 0.000000000000000000e+00, + 4.883336402690426417e-03, + 1.332632627032051542e-02, + 2.140812375876842075e-02, + 2.818059142001937828e-02, + 3.362163715849737083e-02, + 3.794276055337758580e-02, + 4.137547846997025047e-02, + 4.411681001711743877e-02, + 4.632228985032173924e-02, + 4.811145835127387388e-02, + 0.000000000000000000e+00, + 5.216458452347733261e-03, + 1.492052170740058165e-02, + 2.479039304084246567e-02, + 3.341922235530064150e-02, + 4.054846000436074238e-02, + 4.631490055836424286e-02, + 5.095191227795443922e-02, + 5.468596768919504331e-02, + 5.770784088044408899e-02, + 6.016979812822989548e-02, + 0.000000000000000000e+00, + 5.443452390953965048e-03, + 1.610184242266437388e-02, + 2.745791860035587395e-02, + 3.774735773987216575e-02, + 4.647087682887238863e-02, + 5.365611441928514608e-02, + 5.950828411399150530e-02, + 6.426398211234400637e-02, + 6.813822608265847347e-02, + 7.131020298760183673e-02, + 0.000000000000000000e+00, + 5.603182869318606638e-03, + 1.698537988167880472e-02, + 2.955196761958390692e-02, + 4.127727827674304573e-02, + 5.144592380528976300e-02, + 5.996410190786041067e-02, + 6.698880813872078177e-02, + 7.275015724326128197e-02, + 7.747610674357763294e-02, + 8.136570783515832683e-02, + 0.000000000000000000e+00, + 5.718994165839363757e-03, + 1.765556418075154080e-02, + 3.120130665078258217e-02, + 4.414527445525694149e-02, + 5.559042754703297923e-02, + 6.532404806963165722e-02, + 7.344467067117703418e-02, + 8.016402447511272733e-02, + 8.571334926782668562e-02, + 9.030469447376583692e-02, + 0.000000000000000000e+00, + 5.805231126591313059e-03, + 1.817189858907889560e-02, + 3.251008336421949002e-02, + 4.647919386144636761e-02, + 5.903462270333981188e-02, + 6.985498102082771110e-02, + 7.897742990674293251e-02, + 8.658805699566379799e-02, + 9.291411037656233107e-02, + 9.817477042468102100e-02}; + +float sampleCylSolidAngleTable(float u, float v, float w) +{ + if (u > 1.f) + u = 1.f; + if (v > 1.f) + v = 1.f; + if (w > 1.f) + w = 1.f; + if (u <= 0.f || v <= 0.f || w <= 0.f) + return 0.f; + + u *= 10.f; + v *= 10.f; + w *= 10.f; + + const int U0 = (int)u; + const int V0 = (int)v; + const int W0 = (int)w; + + const int U1 = U0 == 10 ? 10 : U0 + 1; + const int V1 = V0 == 10 ? 10 : V0 + 1; + const int W1 = W0 == 10 ? 10 : W0 + 1; + + u -= (float)U0; + v -= (float)V0; + w -= (float)W0; + + const float p00 = lerp(u, + CylCapSolidAngleTable[121 * U0 + 11 * V0 + W0], + CylCapSolidAngleTable[121 * U1 + 11 * V0 + W0]); + const float p10 = lerp(u, + CylCapSolidAngleTable[121 * U0 + 11 * V0 + W1], + CylCapSolidAngleTable[121 * U1 + 11 * V0 + W1]); + const float p01 = lerp(u, + CylCapSolidAngleTable[121 * U0 + 11 * V1 + W0], + CylCapSolidAngleTable[121 * U1 + 11 * V1 + W0]); + const float p11 = lerp(u, + CylCapSolidAngleTable[121 * U0 + 11 * V1 + W1], + CylCapSolidAngleTable[121 * U1 + 11 * V1 + W1]); + const float p0 = (1. - w) * p00 + w * p10; + const float p1 = (1. - w) * p10 + w * p11; + + return (1. - v) * p0 + v * p1; +} \ No newline at end of file diff --git a/ospray/lights/CylinderLight.cpp b/ospray/lights/CylinderLight.cpp new file mode 100644 index 0000000000..f049fb5eb6 --- /dev/null +++ b/ospray/lights/CylinderLight.cpp @@ -0,0 +1,62 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "CylinderLight.h" +#include "lights/CylinderLight_ispc.h" +#include "lights/Light_ispc.h" + +namespace ospray { + +CylinderLight::CylinderLight() +{ + ispcEquivalent = ispc::CylinderLight_create(); +} + +void *CylinderLight::createIE(const void *instance) const +{ + void *ie = ispc::CylinderLight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::CylinderLight_set(ie, + (ispc::vec3f &)radiance, + (ispc::vec3f &)position0, + (ispc::vec3f &)position1, + radius); + return ie; +} + +std::string CylinderLight::toString() const +{ + return "ospray::CylinderLight"; +} + +void CylinderLight::commit() +{ + Light::commit(); + position0 = getParam("position0", vec3f(0.f)); + position1 = getParam("position1", vec3f(0.f, 0.f, 1.f)); + radius = getParam("radius", 1.f); + + queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_RADIANCE); + processIntensityQuantityType(); +} + +void CylinderLight::processIntensityQuantityType() +{ + float cylinderArea = 2.f * M_PI * length(position1 - position0) * radius; + radiance = vec3f(0.0f); + /// converting from the chosen intensity quantity type to radiance + if (intensityQuantity == OSP_INTENSITY_QUANTITY_POWER) { + if (cylinderArea > 0.f) + radiance = coloredIntensity / (M_PI * cylinderArea); + } else if (intensityQuantity == OSP_INTENSITY_QUANTITY_INTENSITY) { + if (cylinderArea > 0.f) + radiance = M_PI * coloredIntensity / cylinderArea; + } else if (intensityQuantity == OSP_INTENSITY_QUANTITY_RADIANCE) { + radiance = coloredIntensity; + } else { + static WarnOnce warning( + "Unsupported intensityQuantity type for a 'cylinder' light source"); + } +} + +} // namespace ospray diff --git a/ospray/lights/CylinderLight.h b/ospray/lights/CylinderLight.h new file mode 100644 index 0000000000..671abe7b0e --- /dev/null +++ b/ospray/lights/CylinderLight.h @@ -0,0 +1,29 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "Light.h" + +namespace ospray { + +/*! a CylinderLight is a virtual area light uniformly emitting from a + * cylindrical area into outward space */ +struct OSPRAY_SDK_INTERFACE CylinderLight : public Light +{ + CylinderLight(); + virtual ~CylinderLight() override = default; + virtual void *createIE(const void *instance) const override; + virtual std::string toString() const override; + virtual void commit() override; + + private: + void processIntensityQuantityType(); + + vec3f position0{0.f}; //!< world-space bottom position of the light + vec3f position1{0.f, 0.f, 1.f}; //!< world-space top position of the light + vec3f radiance{1.0f, 1.0f, 1.0f}; //!< emitted radiance of the CylinderLight + float radius{1.f}; //!< vector along the radius of the cylinder +}; + +} // namespace ospray diff --git a/ospray/lights/CylinderLight.ispc b/ospray/lights/CylinderLight.ispc new file mode 100644 index 0000000000..1e43a63c98 --- /dev/null +++ b/ospray/lights/CylinderLight.ispc @@ -0,0 +1,330 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#include "../math/AffineSpace.ih" +#include "CylinderCapSolidAngleTable.ih" +#include "Light.ih" +#include "SphericalQuadSampling.ih" +#include "common/Instance.ih" +#include "common/Intersect.ih" + +struct CylinderLight +{ + Light super; + + vec3f position0; + vec3f position1; + vec3f radiance; + float radius; +}; + +// Implementation +////////////////////////////////////////////////////////////////////////////// +inline float cylinderAxialSolidAngle( + float c, float b, float h0, float h1, float b2c2) +{ + return 2.f * atan(c * h1 / (b * sqrt(b2c2 + sqr(h1)))) + - 2.f * atan(c * h0 / (b * sqrt(b2c2 + sqr(h0)))); +} + +inline float cylinderCapSolidAngle(float d, float R, float h) +{ + const float dmR = d - R; + const float dpR = d + R; + const float dmR2 = dmR * dmR; + const float R2 = R * R; + const float h2 = h * h; + + const float u = sqrt(dmR / dpR); + const float v = sqrt((dmR2 + h2) / (d * d - R2 + h2)); + const float w = sqrt((dmR2 + h2) / (dpR * dpR + h2)); + + const float integral = sampleCylSolidAngleTable(u, v, w); + + const float recip = sqrt(dmR2 + h2); + return (16.f * R2 * h / (recip * recip * recip)) * integral; +} + +inline void cylinderComputeRectBounds(const uniform vec3f &position0, + const uniform vec3f &position1, + const uniform float radius, + const vec3f &P, + vec3f &q0, + vec3f &e0, + vec3f &e1, + float &S) +{ + // construct geometry of cylinder from sample point + vec3f O = position0; + vec3f Z = position1 - position0; + const float H = length(Z); + Z = Z / H; + vec3f Dp = P - O; + float h0 = -dot(Dp, Z); + + // flip origin if end of cylinder is closer to sample point + if (h0 < -H) { + O = position1; + Z = -1.f * Z; + Dp = P - O; + h0 = -dot(Dp, Z); + } + const vec3f D = -h0 * Z - Dp; + const float d = length(D); + const float srad = min(radius / d, 1.f); + const float q = max(1.f - sqr(srad), 4.e-6f); + const float b = d * q; + const float c = radius * sqrt(q); + const float b2c2 = sqr(b) + sqr(c); + const vec3f X = normalize(cross(D, Z)); + + const float h1 = (1.f + srad) * (h0 + H); + + // compute the bounding rectangle of the cylinder + const float hO = h0 < 0.f ? (1.f + srad) * h0 : h0; + q0 = P + D * q - c * X + hO * Z; + e0 = 2.f * c * X; + e1 = (h1 - hO) * Z; + + // compute solid angle of cylinder at sample point + S = cylinderAxialSolidAngle(c, b, hO, h1, b2c2); +} + +inline void cylinderSampleSolidAngle(const DifferentialGeometry &dg, + const vec2f &sp, + const uniform vec3f &position0, + const uniform vec3f &position1, + const uniform float radius, + vec3f &dir, + float &pdf, + float &S) +{ + // compute spherical quad bounding cylinder + vec3f q0, e0, e1; + cylinderComputeRectBounds(position0, position1, radius, dg.P, q0, e0, e1, S); + const float e0l = length(e0); + const float e1l = length(e1); + const vec3f e0n = e0 / e0l; + const vec3f e1n = e1 / e1l; + const vec3f n = normalize(cross(e0n, e1n)); + SphericalQuad quad = SphericalQuad_create(q0, e0n, e0l, e1n, e1l, n, dg.P); + + // warped samples in solid angle space + const vec3f cosW = computeCosineWeightedRNG(q0, e0, e1, dg.P, dg.Ng, sp); + + // sample spherical quad bounding cylinder + dir = sampleSphericalQuad(quad, make_vec2f(cosW.x, cosW.y)); + pdf = cosW.z; +} + +inline Light_SampleRes Sample(const DifferentialGeometry &dg, + const vec2f &sp, + const uniform vec3f &position0, + const uniform vec3f &position1, + const uniform float radius, + const uniform vec3f &radiance) +{ + Light_SampleRes res; + res.weight = make_vec3f(0.f); + res.pdf = 0.f; + + float S, pdf; + vec3f dir; + if (sp.x == 0.0f && sp.y == 0.0f) { // XXX SciVis + dir = 0.5f * (position0 + position1) - dg.P; // to center + + vec3f q0, e0, e1; + cylinderComputeRectBounds( + position0, position1, radius, dg.P, q0, e0, e1, S); + if (S > 0.f) { + pdf = 1.f; + } + } else { + cylinderSampleSolidAngle(dg, sp, position0, position1, radius, dir, pdf, S); + } + + if (S <= 0.f || pdf == 0.f) { + return res; + } + + res.dir = normalize(dir); + + // rejection sampling of the cylinder sample direction (through out cap hits + // and rare misses) + Intersections isect = + intersectCylinder(dg.P, res.dir, position0, position1, radius); + if (isect.entry.hit) { + res.pdf = pdf / S; + res.weight = radiance * rcp(res.pdf); + res.dist = isect.entry.t; + } + + return res; +} + +Light_SampleRes CylinderLight_sample(const uniform Light *uniform super, + const DifferentialGeometry &dg, + const vec2f &sp, + const float) +{ + const CylinderLight *uniform self = (CylinderLight * uniform) super; + assert(self); + return Sample( + dg, sp, self->position0, self->position1, self->radius, self->radiance); +} + +Light_SampleRes CylinderLight_sample_instanced(const Light *uniform super, + const DifferentialGeometry &dg, + const vec2f &sp, + const float time) +{ + const CylinderLight *uniform self = (CylinderLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_SampleRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + + // transform light into the world space + const uniform vec3f position0 = xfmPoint(xfm, self->position0); + const uniform vec3f position1 = xfmPoint(xfm, self->position1); + + // sample light + res = Sample(dg, sp, position0, position1, self->radius, self->radiance); + } + return res; +} + +inline Light_EvalRes Eval(const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const uniform vec3f &position0, + const uniform vec3f &position1, + const uniform float radius, + const uniform vec3f &radiance) +{ + Light_EvalRes res; + res.radiance = make_vec3f(0.f); + + // check if intersecting cylinder + Intersections isect = + intersectCylinder(dg.P, dir, position0, position1, radius); + if (isect.entry.hit) { + if ((minDist < isect.entry.t && isect.entry.t <= maxDist)) { + // compute bounding rectangle solid angle + vec3f q0, e0, e1; + float S; + cylinderComputeRectBounds( + position0, position1, radius, dg.P, q0, e0, e1, S); + if (S > 0.f) { + res.radiance = radiance; + res.pdf = rcp(S); + } + } + } + + return res; +} + +Light_EvalRes CylinderLight_eval(const uniform Light *uniform super, + const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const float) +{ + uniform CylinderLight *uniform self = (uniform CylinderLight * uniform) super; + assert(self); + return Eval(dg, + dir, + minDist, + maxDist, + self->position0, + self->position1, + self->radius, + self->radiance); +} + +Light_EvalRes CylinderLight_eval_instanced(const Light *uniform super, + const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const float time) +{ + const CylinderLight *uniform self = (CylinderLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_EvalRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + + // transform light into the world space + const uniform vec3f position0 = xfmPoint(xfm, self->position0); + const uniform vec3f position1 = xfmPoint(xfm, self->position1); + + // evaluate light + res = Eval(dg, + dir, + minDist, + maxDist, + position0, + position1, + self->radius, + self->radiance); + } + return res; +} + +// Exports (called from C++) +////////////////////////////////////////////////////////////////////////////// + +export void CylinderLight_set(void *uniform super, + const uniform vec3f &radiance, + const uniform vec3f &position0, + const uniform vec3f &position1, + const uniform float radius) +{ + uniform CylinderLight *uniform self = (uniform CylinderLight * uniform) super; + self->radiance = make_vec3f(0.f); + uniform float zMax = length(position1 - position0); + if (and(zMax > 0.f, radius > 0.f)) { + self->radiance = radiance; + self->radius = radius; + self->position0 = position0; + self->position1 = position1; + } + + // Enable dynamic runtime instancing or apply static transformation + const Instance *uniform instance = self->super.instance; + if (instance) { + if (instance->motionBlur) { + self->super.sample = CylinderLight_sample_instanced; + self->super.eval = CylinderLight_eval_instanced; + } else { + self->position0 = xfmPoint(instance->xfm, position0); + self->position1 = xfmPoint(instance->xfm, position1); + } + } +} + +export void *uniform CylinderLight_create() +{ + uniform CylinderLight *uniform self = uniform new uniform CylinderLight; + + Light_Constructor(&self->super); + self->super.sample = CylinderLight_sample; + self->super.eval = CylinderLight_eval; + + CylinderLight_set( + self, make_vec3f(0.f), make_vec3f(0.f), make_vec3f(0.f, 0.f, 1.f), 1.f); + + return self; +} diff --git a/ospray/lights/DirectionalLight.cpp b/ospray/lights/DirectionalLight.cpp index 1c648f3b02..156b77ef7f 100644 --- a/ospray/lights/DirectionalLight.cpp +++ b/ospray/lights/DirectionalLight.cpp @@ -3,12 +3,17 @@ #include "DirectionalLight.h" #include "lights/DirectionalLight_ispc.h" +#include "lights/Light_ispc.h" namespace ospray { -DirectionalLight::DirectionalLight() +void *DirectionalLight::createIE(const void *instance) const { - ispcEquivalent = ispc::DirectionalLight_create(); + void *ie = ispc::DirectionalLight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::DirectionalLight_set( + ie, (ispc::vec3f &)irradiance, (ispc::vec3f &)direction, cosAngle); + return ie; } std::string DirectionalLight::toString() const @@ -25,16 +30,13 @@ void DirectionalLight::commit() // the ispc::DirLight expects direction towards light source direction = -normalize(direction); angularDiameter = clamp(angularDiameter, 0.f, 180.f); - const float cosAngle = std::cos(deg2rad(0.5f * angularDiameter)); + cosAngle = std::cos(deg2rad(0.5f * angularDiameter)); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_IRRADIANCE); - processIntensityQuantityType(cosAngle); - - ispc::DirectionalLight_set( - getIE(), (ispc::vec3f &)irradiance, (ispc::vec3f &)direction, cosAngle); + processIntensityQuantityType(); } -void DirectionalLight::processIntensityQuantityType(const float &cosAngle) +void DirectionalLight::processIntensityQuantityType() { // validate the correctness of the light quantity type if (intensityQuantity == OSP_INTENSITY_QUANTITY_RADIANCE) { diff --git a/ospray/lights/DirectionalLight.h b/ospray/lights/DirectionalLight.h index 9d538441bc..7826803cc4 100644 --- a/ospray/lights/DirectionalLight.h +++ b/ospray/lights/DirectionalLight.h @@ -11,18 +11,20 @@ namespace ospray { * thus projects parallel rays of light across the entire scene */ struct OSPRAY_SDK_INTERFACE DirectionalLight : public Light { - DirectionalLight(); + DirectionalLight() = default; virtual ~DirectionalLight() override = default; + virtual void *createIE(const void *instance) const override; virtual std::string toString() const override; virtual void commit() override; private: - void processIntensityQuantityType(const float &cosAngle); + void processIntensityQuantityType(); - vec3f irradiance{1.0f, 1.0f, 1.0f}; + vec3f irradiance{1.f}; vec3f direction{0.f, 0.f, 1.f}; //!< Direction of the emitted rays float angularDiameter{0.f}; //!< Apparent size of the distant light, in degree //!< (e.g. 0.53 for the sun) + float cosAngle{1.f}; }; } // namespace ospray diff --git a/ospray/lights/DirectionalLight.ispc b/ospray/lights/DirectionalLight.ispc index 10ed40b025..89501dd927 100644 --- a/ospray/lights/DirectionalLight.ispc +++ b/ospray/lights/DirectionalLight.ispc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "Light.ih" +#include "common/Instance.ih" #include "math/LinearSpace.ih" #include "math/sampling.ih" @@ -24,39 +25,63 @@ struct DirectionalLight // Implementation ////////////////////////////////////////////////////////////////////////////// -Light_SampleRes DirectionalLight_sample(const uniform Light *uniform super, - const DifferentialGeometry &dg, - const vec2f &s, - const float) +inline Light_SampleRes Sample(const DirectionalLight *uniform self, + const uniform linear3f &frame, + const vec2f &s) { - const DirectionalLight *uniform self = (DirectionalLight * uniform) super; Light_SampleRes res; - res.dir = self->frame.vz; + res.dir = frame.vz; res.dist = inf; res.pdf = self->pdf; if (self->cosAngle < COS_ANGLE_MAX) - res.dir = self->frame * uniformSampleCone(self->cosAngle, s); + res.dir = frame * uniformSampleCone(self->cosAngle, s); res.weight = self->irradiance; // *pdf/pdf cancel return res; } -Light_EvalRes DirectionalLight_eval(const uniform Light *uniform super, +Light_SampleRes DirectionalLight_sample(const Light *uniform super, const DifferentialGeometry &, + const vec2f &s, + const float) +{ + const DirectionalLight *uniform self = (DirectionalLight * uniform) super; + assert(self); + return Sample(self, self->frame, s); +} + +Light_SampleRes DirectionalLight_sample_instanced(const Light *uniform super, + const DifferentialGeometry &, + const vec2f &s, + const float time) +{ + const DirectionalLight *uniform self = (DirectionalLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_SampleRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + res = Sample(self, xfm.l * self->frame, s); + } + return res; +} + +inline Light_EvalRes Eval(const DirectionalLight *uniform self, + const uniform linear3f &frame, const vec3f &dir, - const float, const float maxDist) { - uniform DirectionalLight *uniform self = - (uniform DirectionalLight * uniform) super; Light_EvalRes res; res.radiance = make_vec3f(0.f); if (inf <= maxDist && self->cosAngle < COS_ANGLE_MAX - && dot(self->frame.vz, dir) > self->cosAngle) { + && dot(frame.vz, dir) > self->cosAngle) { res.radiance = self->irradiance * self->pdf; res.pdf = self->pdf; } @@ -64,6 +89,39 @@ Light_EvalRes DirectionalLight_eval(const uniform Light *uniform super, return res; } +Light_EvalRes DirectionalLight_eval(const Light *uniform super, + const DifferentialGeometry &, + const vec3f &dir, + const float, + const float maxDist, + const float) +{ + const DirectionalLight *uniform self = (DirectionalLight * uniform) super; + assert(self); + return Eval(self, self->frame, dir, maxDist); +} + +Light_EvalRes DirectionalLight_eval_instanced(const Light *uniform super, + const DifferentialGeometry &, + const vec3f &dir, + const float, + const float maxDist, + const float time) +{ + const DirectionalLight *uniform self = (DirectionalLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_EvalRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + res = Eval(self, xfm.l * self->frame, dir, maxDist); + } + return res; +} + // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// @@ -73,18 +131,28 @@ export void DirectionalLight_set(void *uniform super, const uniform vec3f &direction, uniform float cosAngle) { - uniform DirectionalLight *uniform self = - (uniform DirectionalLight * uniform) super; + DirectionalLight *uniform self = (DirectionalLight * uniform) super; self->frame = frame(direction); self->irradiance = irradiance; self->cosAngle = cosAngle; self->pdf = cosAngle < COS_ANGLE_MAX ? uniformSampleConePDF(cosAngle) : inf; + + // Enable dynamic runtime instancing or apply static transformation + const Instance *uniform instance = self->super.instance; + if (instance) { + if (instance->motionBlur) { + self->super.sample = DirectionalLight_sample_instanced; + self->super.eval = DirectionalLight_eval_instanced; + } else { + self->frame = instance->xfm.l * self->frame; + } + } } //! Create an ispc-side DirectionalLight object export void *uniform DirectionalLight_create() { - uniform DirectionalLight *uniform self = uniform new uniform DirectionalLight; + DirectionalLight *uniform self = uniform new uniform DirectionalLight; Light_Constructor(&self->super); self->super.sample = DirectionalLight_sample; self->super.eval = DirectionalLight_eval; diff --git a/ospray/lights/HDRILight.cpp b/ospray/lights/HDRILight.cpp index b2dc58ee73..a5f5be44be 100644 --- a/ospray/lights/HDRILight.cpp +++ b/ospray/lights/HDRILight.cpp @@ -3,18 +3,25 @@ #include "HDRILight.h" #include "lights/HDRILight_ispc.h" +#include "lights/Light_ispc.h" namespace ospray { -HDRILight::HDRILight() +HDRILight::~HDRILight() { - ispcEquivalent = ispc::HDRILight_create(); + ispc::HDRILight_destroyDistribution(distributionIE); } -HDRILight::~HDRILight() +void *HDRILight::createIE(const void *instance) const { - ispc::HDRILight_destroy(getIE()); - ispcEquivalent = nullptr; + void *ie = ispc::HDRILight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::HDRILight_set(ie, + (ispc::vec3f &)coloredIntensity, + (const ispc::LinearSpace3f &)frame, + map ? map->getIE() : nullptr, + distributionIE); + return ie; } std::string HDRILight::toString() const @@ -25,33 +32,32 @@ std::string HDRILight::toString() const void HDRILight::commit() { Light::commit(); - up = getParam("up", vec3f(0.f, 1.f, 0.f)); - dir = getParam("direction", vec3f(0.f, 0.f, 1.f)); + const vec3f up = getParam("up", vec3f(0.f, 1.f, 0.f)); + const vec3f dir = getParam("direction", vec3f(0.f, 0.f, 1.f)); map = (Texture2D *)getParamObject("map", nullptr); - linear3f frame; + // recreate distribution + ispc::HDRILight_destroyDistribution(distributionIE); + distributionIE = nullptr; + if (map) + distributionIE = ispc::HDRILight_createDistribution(map->getIE()); + frame.vx = normalize(-dir); frame.vy = normalize(cross(frame.vx, up)); frame.vz = cross(frame.vx, frame.vy); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_SCALE); processIntensityQuantityType(); - - ispc::HDRILight_set(getIE(), - (ispc::vec3f &)radianceScale, - (const ispc::LinearSpace3f &)frame, - map ? map->getIE() : nullptr); } void HDRILight::processIntensityQuantityType() { - radianceScale = coloredIntensity; // validate the correctness of the light quantity type if (intensityQuantity != OSP_INTENSITY_QUANTITY_SCALE && intensityQuantity != OSP_INTENSITY_QUANTITY_RADIANCE) { static WarnOnce warning( "Unsupported intensityQuantity type for a 'hdri' light source"); - radianceScale = vec3f(0.0f); + coloredIntensity = vec3f(0.0f); } } diff --git a/ospray/lights/HDRILight.h b/ospray/lights/HDRILight.h index fb2b6f7571..7919528e83 100644 --- a/ospray/lights/HDRILight.h +++ b/ospray/lights/HDRILight.h @@ -12,19 +12,18 @@ namespace ospray { * cone of directions bounded by halfAngle */ struct OSPRAY_SDK_INTERFACE HDRILight : public Light { - HDRILight(); + HDRILight() = default; virtual ~HDRILight() override; + virtual void *createIE(const void *instance) const override; virtual std::string toString() const override; virtual void commit() override; private: void processIntensityQuantityType(); - vec3f up{0.f, 1.f, 0.f}; //!< up direction of the light in world-space - vec3f dir{0.f, 0.f, 1.f}; //!< direction to which the center of the envmap - // will be mapped to (analog to panoramic camera) + linear3f frame{one}; // light orientation Texture2D *map{nullptr}; //!< environment map in latitude / longitude format - vec3f radianceScale{1.0f, 1.0f, 1.0f}; //!< scaling factor of emitted radiance + void *distributionIE{nullptr}; }; } // namespace ospray diff --git a/ospray/lights/HDRILight.ispc b/ospray/lights/HDRILight.ispc index 109ff16cc0..6d7d444f8b 100644 --- a/ospray/lights/HDRILight.ispc +++ b/ospray/lights/HDRILight.ispc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "Light.ih" +#include "common/Instance.ih" #include "math/Distribution2D.ih" #include "math/LinearSpace.ih" #include "math/sampling.ih" @@ -13,8 +14,9 @@ struct HDRILight linear3f light2world; linear3f world2light; - Texture2D *uniform map; // Environment map in latitude / longitude format - Distribution2D *uniform + const Texture2D *uniform + map; // Environment map in latitude / longitude format + const Distribution2D *uniform distribution; // The 2D distribution used to importance sample vec2f rcpSize; // precomputed 1/map.size vec3f radianceScale; // scaling factor of emmitted RGB radiance @@ -24,7 +26,7 @@ struct HDRILight ////////////////////////////////////////////////////////////////////////////// // sample function used when no environment map is given: black -Light_SampleRes HDRILight_sample_dummy(const uniform Light *uniform, +Light_SampleRes HDRILight_sample_dummy(const Light *uniform, const DifferentialGeometry &, const vec2f &, const float) @@ -34,12 +36,10 @@ Light_SampleRes HDRILight_sample_dummy(const uniform Light *uniform, return res; } -Light_SampleRes HDRILight_sample(const uniform Light *uniform super, - const DifferentialGeometry &, - const vec2f &s, - const float) +inline Light_SampleRes Sample(const HDRILight *uniform self, + const uniform linear3f &light2world, + const vec2f &s) { - uniform HDRILight *uniform self = (uniform HDRILight * uniform) super; Light_SampleRes res; Sample2D sample2d = Distribution2D_sample(self->distribution, s); @@ -54,7 +54,7 @@ Light_SampleRes HDRILight_sample(const uniform Light *uniform super, sincos(theta, &sinTheta, &cosTheta); const vec3f localDir = cartesian(phi, sinTheta, cosTheta); - res.dir = self->light2world * localDir; + res.dir = light2world * localDir; res.pdf = sample2d.pdf * one_over_two_pi_sqr * rcp(sinTheta); @@ -70,20 +70,47 @@ Light_SampleRes HDRILight_sample(const uniform Light *uniform super, return res; } -Light_EvalRes HDRILight_eval(const uniform Light *uniform super, +Light_SampleRes HDRILight_sample(const Light *uniform super, const DifferentialGeometry &, + const vec2f &s, + const float) +{ + const HDRILight *uniform self = (HDRILight * uniform) super; + assert(self); + return Sample(self, self->light2world, s); +} + +Light_SampleRes HDRILight_sample_instanced(const Light *uniform super, + const DifferentialGeometry &, + const vec2f &s, + const float time) +{ + const HDRILight *uniform self = (HDRILight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_SampleRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + res = Sample(self, xfm.l * self->light2world, s); + } + return res; +} + +inline Light_EvalRes Eval(HDRILight *uniform self, + const uniform linear3f &world2light, const vec3f &dir, - const float, const float maxDist) { - uniform HDRILight *uniform self = (uniform HDRILight * uniform) super; Light_EvalRes res; res.radiance = make_vec3f(0.f); if (inf > maxDist) return res; - const vec3f localDir = self->world2light * dir; + const vec3f localDir = world2light * dir; const float u = atan2(localDir.y, localDir.x) * one_over_two_pi; const float v = acos(localDir.z) * one_over_pi; @@ -105,6 +132,39 @@ Light_EvalRes HDRILight_eval(const uniform Light *uniform super, return res; } +Light_EvalRes HDRILight_eval(const Light *uniform super, + const DifferentialGeometry &, + const vec3f &dir, + const float, + const float maxDist, + const float) +{ + const HDRILight *uniform self = (HDRILight * uniform) super; + assert(self); + return Eval(self, self->world2light, dir, maxDist); +} + +Light_EvalRes HDRILight_eval_instanced(const Light *uniform super, + const DifferentialGeometry &, + const vec3f &dir, + const float, + const float maxDist, + const float time) +{ + const HDRILight *uniform self = (HDRILight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_EvalRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + res = Eval(self, self->world2light * rcp(xfm.l), dir, maxDist); + } + return res; +} + // bin i represents the average contribution of (i-0.5, i+0.5) when we sample // the texture bilinearly at i // for i==0 we have a wrap-around, which is wanted for x (phi), but actually @@ -112,20 +172,21 @@ Light_EvalRes HDRILight_eval(const uniform Light *uniform super, // leaking to the north-pole // however, sin(theta) is zero then, thus we will never sample there task unmasked void HDRILight_calcRowImportance( - const HDRILight *uniform const self, + const Texture2D *uniform const map, float *uniform const importance, float *uniform const row_importance) { const uniform int y = taskIndex; - const uniform float fy = y * self->rcpSize.y; - const uniform int width = self->map->size.x; + const uniform vec2f rcpSize = 1.f / map->sizef; + const uniform float fy = y * rcpSize.y; + const uniform int width = map->size.x; const uniform float sinTheta = sin(fy * M_PI); foreach (x = 0 ... width) { - const vec2f coord = make_vec2f(x * self->rcpSize.x, fy); + const vec2f coord = make_vec2f(x * rcpSize.x, fy); // using bilinear filtering is indeed what we want DifferentialGeometry lookup; initDgFromTexCoord(lookup, coord); - const vec3f col = get3f(self->map, lookup); + const vec3f col = get3f(map, lookup); importance[y * width + x] = sinTheta * luminance(col); } row_importance[y] = Distribution1D_create(width, importance + y * width); @@ -138,35 +199,32 @@ task unmasked void HDRILight_calcRowImportance( export void HDRILight_set(void *uniform super, const uniform vec3f &radianceScale, const uniform linear3f &light2world, - void *uniform map) + const void *uniform map, + const void *uniform distribution) { HDRILight *uniform self = (HDRILight * uniform) super; self->radianceScale = radianceScale; - Distribution2D_destroy(self->distribution); - self->distribution = NULL; if (map) { - self->light2world = light2world; - self->world2light = rcp(light2world); - self->map = (uniform Texture2D * uniform) map; + self->distribution = (const uniform Distribution2D *uniform)distribution; self->rcpSize = 1.f / self->map->sizef; - const uniform int height = self->map->size.y; - - // calculate importance in parallel - float *uniform cdf_x = uniform new float[self->map->size.x * height]; - float *uniform row_importance = uniform new float[height]; - launch[height] HDRILight_calcRowImportance(self, cdf_x, row_importance); - sync; - - // create distribution - self->distribution = - Distribution2D_create(self->map->size, cdf_x, row_importance); - // no delete[] (row_)importance: ownership was transferred to Distribution2D - + self->light2world = light2world; self->super.sample = HDRILight_sample; self->super.eval = HDRILight_eval; + + // Enable dynamic runtime instancing or apply static transformation + const Instance *uniform instance = self->super.instance; + if (instance) { + if (instance->motionBlur) { + self->super.sample = HDRILight_sample_instanced; + self->super.eval = HDRILight_eval_instanced; + } else { + self->light2world = instance->xfm.l * self->light2world; + } + } + self->world2light = rcp(self->light2world); } else { self->super.sample = HDRILight_sample_dummy; self->super.eval = Light_eval; @@ -180,17 +238,27 @@ export void *uniform HDRILight_create() Light_Constructor(&self->super); self->super.sample = HDRILight_sample_dummy; - self->distribution = NULL; - - HDRILight_set(self, make_vec3f(1.0f), make_LinearSpace3f_identity(), NULL); - + HDRILight_set( + self, make_vec3f(1.0f), make_LinearSpace3f_identity(), NULL, NULL); return self; } -//! Destroy an ispc-side HDRILight object -export void HDRILight_destroy(void *uniform super) +export void *uniform HDRILight_createDistribution(const void *uniform map) { - HDRILight *uniform self = (HDRILight * uniform) super; - Distribution2D_destroy(self->distribution); - delete self; + // calculate importance in parallel + const Texture2D *uniform m = (const Texture2D *uniform)map; + const uniform int height = m->size.y; + float *uniform cdf_x = uniform new float[m->size.x * height]; + float *uniform row_importance = uniform new float[height]; + launch[height] HDRILight_calcRowImportance(m, cdf_x, row_importance); + sync; + + // create distribution + return Distribution2D_create(m->size, cdf_x, row_importance); + // no delete[] (row_)importance: ownership was transferred to Distribution2D +} + +export void HDRILight_destroyDistribution(void *uniform distribution) +{ + Distribution2D_destroy((Distribution2D * uniform) distribution); } diff --git a/ospray/lights/Light.cpp b/ospray/lights/Light.cpp index 5e11e2a9b3..f0101ca2f0 100644 --- a/ospray/lights/Light.cpp +++ b/ospray/lights/Light.cpp @@ -17,11 +17,16 @@ Light::Light() managedObjectType = OSP_LIGHT; } +void *Light::createSecondIE(const void *) const +{ + return nullptr; +} + void Light::commit() { + visible = getParam("visible", true); coloredIntensity = getParam("color", vec3f(1.f)) * getParam("intensity", 1.f); - ispc::Light_set(getIE(), getParam("visible", true)); } std::string Light::toString() const @@ -45,12 +50,6 @@ void Light::queryIntensityQuantityType(const OSPIntensityQuantity &defaultIQ) (OSPIntensityQuantity)getParam("intensityQuantity", defaultIQ); } -utility::Optional Light::getSecondIE() -{ - utility::Optional emptyOptional; - return emptyOptional; -} - OSPTYPEFOR_DEFINITION(Light *); } // namespace ospray diff --git a/ospray/lights/Light.h b/ospray/lights/Light.h index b3906a81d6..eae6741175 100644 --- a/ospray/lights/Light.h +++ b/ospray/lights/Light.h @@ -18,12 +18,12 @@ struct OSPRAY_SDK_INTERFACE Light : public ManagedObject template static void registerType(const char *type); + virtual void *createIE(const void *instance = nullptr) const = 0; + virtual void *createSecondIE(const void *instance = nullptr) const; virtual void commit() override; virtual std::string toString() const override; - //! get IE of a second light associated with the light type(if available) - virtual utility::Optional getSecondIE(); - + bool visible{true}; vec3f coloredIntensity{1.0f, 1.0f, 1.0f}; OSPIntensityQuantity intensityQuantity = OSP_INTENSITY_QUANTITY_UNKNOWN; diff --git a/ospray/lights/Light.ih b/ospray/lights/Light.ih index bfcb0d321b..ebd1ae9765 100644 --- a/ospray/lights/Light.ih +++ b/ospray/lights/Light.ih @@ -4,8 +4,10 @@ #pragma once #include "common/DifferentialGeometry.ih" +#include "math/AffineSpace.ih" struct Light; +struct Instance; struct Light_SampleRes { @@ -21,8 +23,8 @@ struct Light_SampleRes // by convention, giving (0, 0) as "random" numbers should sample the "center" // of the light source (used by the raytracing renderers such as the SciVis // renderer) -typedef Light_SampleRes (*Light_SampleFunc)(const uniform Light *uniform, - const DifferentialGeometry &, // point (&normal) to generate the sample +typedef Light_SampleRes (*Light_SampleFunc)(const Light *uniform self, + const DifferentialGeometry &dg, // point (&normal) to generate the sample const vec2f &s, // random numbers to generate the sample const float time = 0.5f); // generate the sample at time (motion blur) @@ -35,12 +37,12 @@ struct Light_EvalRes //! compute the radiance and pdf caused by the light source (pointed to by the //! given direction up until maxDist) -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 >*/ +typedef Light_EvalRes (*Light_EvalFunc)(const Light *uniform self, + const DifferentialGeometry &dg, // 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 + const float time = 0.5f); // evaluate at time (motion blur) struct Light { @@ -48,21 +50,22 @@ struct Light Light_EvalFunc eval; bool isVisible; // either directly in camera, or via a straight path (i.e. // through ThinGlass) - float selectionPDF; // the PDF of selecting the light from the renderers light - // list + const Instance *instance; }; typedef Light *uniform LightPtr; typedef LightPtr *uniform LightArray; -Light_EvalRes Light_eval(const uniform Light *uniform, +Light_EvalRes Light_eval(const Light *uniform, const DifferentialGeometry &, const vec3f &, const float, + const float, const float); -inline void Light_Constructor(uniform Light *uniform self) +inline void Light_Constructor(Light *uniform self) { + assert(self); self->eval = Light_eval; self->isVisible = true; - self->selectionPDF = 0.f; + self->instance = NULL; } diff --git a/ospray/lights/Light.ispc b/ospray/lights/Light.ispc index 6af0c1392a..0ac7d60789 100644 --- a/ospray/lights/Light.ispc +++ b/ospray/lights/Light.ispc @@ -3,10 +3,11 @@ #include "Light.ih" -Light_EvalRes Light_eval(const uniform Light *uniform, +Light_EvalRes Light_eval(const Light *uniform, const DifferentialGeometry &, const vec3f &, const float, + const float, const float) { Light_EvalRes res; @@ -19,8 +20,10 @@ Light_EvalRes Light_eval(const uniform Light *uniform, //! Set the parameters of an ispc-side Light object export void Light_set(void *uniform _self, - const uniform bool isVisible) + const uniform bool isVisible, + const Instance *uniform instance) { Light *uniform self = (Light * uniform) _self; self->isVisible = isVisible; + self->instance = instance; } diff --git a/ospray/lights/PointLight.cpp b/ospray/lights/PointLight.cpp index c802590d83..870e8bb313 100644 --- a/ospray/lights/PointLight.cpp +++ b/ospray/lights/PointLight.cpp @@ -2,12 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 #include "PointLight.h" +#include "lights/Light_ispc.h" #include "lights/PointLight_ispc.h" namespace ospray { -PointLight::PointLight() + +void *PointLight::createIE(const void *instance) const { - ispcEquivalent = ispc::PointLight_create(); + void *ie = ispc::PointLight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::PointLight_set(ie, + (ispc::vec3f &)position, + (ispc::vec3f &)radiance, + (ispc::vec3f &)radIntensity, + radius); + return ie; } std::string PointLight::toString() const @@ -22,17 +31,10 @@ void PointLight::commit() radius = getParam("radius", 0.f); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_INTENSITY); - vec3f radIntensity = 0.0f; - processIntensityQuantityType(radIntensity); - - ispc::PointLight_set(getIE(), - (ispc::vec3f &)position, - (ispc::vec3f &)radiance, - (ispc::vec3f &)radIntensity, - radius); + processIntensityQuantityType(); } -void PointLight::processIntensityQuantityType(vec3f &radIntensity) +void PointLight::processIntensityQuantityType() { radIntensity = 0.0f; radiance = 0.0f; diff --git a/ospray/lights/PointLight.h b/ospray/lights/PointLight.h index c437335317..d262dfd06d 100644 --- a/ospray/lights/PointLight.h +++ b/ospray/lights/PointLight.h @@ -11,17 +11,19 @@ namespace ospray { //! directions struct OSPRAY_SDK_INTERFACE PointLight : public Light { - PointLight(); + PointLight() = default; virtual ~PointLight() override = default; + virtual void *createIE(const void *instance) const override; virtual std::string toString() const override; virtual void commit() override; private: - void processIntensityQuantityType(vec3f &radIntensity); + void processIntensityQuantityType(); vec3f position{0.f}; //!< world-space position of the light float radius{0.f}; //!< Radius of SphereLight - vec3f radiance{1.0f, 1.0f, 1.0f}; //!< emitted radiance of the SphereLight + vec3f radiance{1.f}; //!< emitted radiance of the SphereLight + vec3f radIntensity{0.f}; }; } // namespace ospray diff --git a/ospray/lights/PointLight.ispc b/ospray/lights/PointLight.ispc index 7c3202096c..b27cbb337b 100644 --- a/ospray/lights/PointLight.ispc +++ b/ospray/lights/PointLight.ispc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "Light.ih" +#include "common/Instance.ih" #include "common/Intersect.ih" #include "common/Ray.ih" #include "math/LinearSpace.ih" @@ -20,16 +21,15 @@ struct PointLight // Implementation ////////////////////////////////////////////////////////////////////////////// -Light_SampleRes PointLight_sample(const uniform Light *uniform super, +inline Light_SampleRes Sample(const PointLight *uniform self, + const uniform vec3f &pos, const DifferentialGeometry &dg, - const vec2f &s, - const float) + const vec2f &s) { - const PointLight *uniform self = (PointLight * uniform) super; Light_SampleRes res; // extant light vector from the hit point - const vec3f dir = self->position - dg.P; + const vec3f dir = pos - dg.P; const float dist2 = dot(dir, dir); const float invdist = rsqrt(dist2); @@ -66,23 +66,51 @@ Light_SampleRes PointLight_sample(const uniform Light *uniform super, return res; } -Light_EvalRes PointLight_eval(const uniform Light *uniform super, +Light_SampleRes PointLight_sample(const Light *uniform super, + const DifferentialGeometry &dg, + const vec2f &s, + const float) +{ + const PointLight *uniform self = (PointLight * uniform) super; + assert(self); + return Sample(self, self->position, dg, s); +} + +Light_SampleRes PointLight_sample_instanced(const Light *uniform super, + const DifferentialGeometry &dg, + const vec2f &s, + const float time) +{ + const PointLight *uniform self = (PointLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_SampleRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + res = Sample(self, xfmPoint(xfm, self->position), dg, s); + } + return res; +} + +inline Light_EvalRes Eval(const PointLight *uniform self, + const uniform vec3f &pos, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist) { - const PointLight *uniform self = (PointLight * uniform) super; Light_EvalRes res; res.radiance = make_vec3f(0.f); - const vec3f A = self->position - dg.P; + const vec3f A = pos - dg.P; const float centerDist2 = dot(A, A); const float sinTheta2 = sqr(self->radius) * rcp(centerDist2); if (and(self->radius > 0.f, sqrt(sinTheta2) > 0.005f)) { - const Intersections isect = - intersectSphere(dg.P, dir, self->position, self->radius); + const Intersections isect = intersectSphere(dg.P, dir, pos, self->radius); if (and(and(isect.entry.t > minDist, isect.entry.t < maxDist), isect.entry.hit)) { const float cosTheta = sqrt(1.f - sinTheta2); @@ -93,6 +121,39 @@ Light_EvalRes PointLight_eval(const uniform Light *uniform super, return res; } +Light_EvalRes PointLight_eval(const Light *uniform super, + const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const float) +{ + const PointLight *uniform self = (PointLight * uniform) super; + assert(self); + return Eval(self, self->position, dg, dir, minDist, maxDist); +} + +Light_EvalRes PointLight_eval_instanced(const Light *uniform super, + const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const float time) +{ + const PointLight *uniform self = (PointLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_EvalRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + res = Eval(self, xfmPoint(xfm, self->position), dg, dir, minDist, maxDist); + } + return res; +} + // Exports (called from C++) ////////////////////////////////////////////////////////////////////////////// @@ -108,6 +169,17 @@ export void PointLight_set(void *uniform super, self->radiance = radiance; self->intensity = intensity; self->radius = radius; + + // Enable dynamic runtime instancing or apply static transformation + const Instance *uniform instance = self->super.instance; + if (instance) { + if (instance->motionBlur) { + self->super.sample = PointLight_sample_instanced; + self->super.eval = PointLight_eval_instanced; + } else { + self->position = xfmPoint(instance->xfm, self->position); + } + } } //! Create an ispc-side PointLight object diff --git a/ospray/lights/QuadLight.cpp b/ospray/lights/QuadLight.cpp index 3180b54b0d..45d9560f97 100644 --- a/ospray/lights/QuadLight.cpp +++ b/ospray/lights/QuadLight.cpp @@ -2,13 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 #include "QuadLight.h" +#include "lights/Light_ispc.h" #include "lights/QuadLight_ispc.h" namespace ospray { -QuadLight::QuadLight() +void *QuadLight::createIE(const void *instance) const { - ispcEquivalent = ispc::QuadLight_create(); + void *ie = ispc::QuadLight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::QuadLight_set(ie, + (ispc::vec3f &)radiance, + (ispc::vec3f &)position, + (ispc::vec3f &)edge1, + (ispc::vec3f &)edge2); + return ie; } std::string QuadLight::toString() const @@ -25,12 +33,6 @@ void QuadLight::commit() queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_RADIANCE); processIntensityQuantityType(); - - ispc::QuadLight_set(getIE(), - (ispc::vec3f &)radiance, - (ispc::vec3f &)position, - (ispc::vec3f &)edge1, - (ispc::vec3f &)edge2); } void QuadLight::processIntensityQuantityType() diff --git a/ospray/lights/QuadLight.h b/ospray/lights/QuadLight.h index c1fb6eeb93..f702b68691 100644 --- a/ospray/lights/QuadLight.h +++ b/ospray/lights/QuadLight.h @@ -11,8 +11,9 @@ namespace ospray { * area into the positive half space */ struct OSPRAY_SDK_INTERFACE QuadLight : public Light { - QuadLight(); + QuadLight() = default; virtual ~QuadLight() override = default; + virtual void *createIE(const void *instance) const override; virtual std::string toString() const override; virtual void commit() override; @@ -22,7 +23,7 @@ struct OSPRAY_SDK_INTERFACE QuadLight : public Light vec3f position{0.f}; //!< world-space corner position of the light vec3f edge1{1.f, 0.f, 0.f}; //!< vectors to adjacent corners vec3f edge2{0.f, 1.f, 0.f}; //!< vectors to adjacent corners - vec3f radiance{1.0f, 1.0f, 1.0f}; //!< emitted radiance of the QuadLight + vec3f radiance{1.f}; //!< emitted radiance of the QuadLight }; } // namespace ospray diff --git a/ospray/lights/QuadLight.ispc b/ospray/lights/QuadLight.ispc index d6fb8e26c5..852290b12e 100644 --- a/ospray/lights/QuadLight.ispc +++ b/ospray/lights/QuadLight.ispc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "Light.ih" +#include "common/Instance.ih" struct QuadLight { @@ -20,12 +21,15 @@ struct QuadLight // Implementation ////////////////////////////////////////////////////////////////////////////// -Light_SampleRes QuadLight_sample(const uniform Light *uniform super, +inline Light_SampleRes Sample(const QuadLight *uniform self, + const uniform vec3f &pos, + const uniform vec3f &edge1, + const uniform vec3f &edge2, + const uniform float ppdf, + const uniform vec3f &nnormal, const DifferentialGeometry &dg, - const vec2f &sp, - const float) + const vec2f &sp) { - const QuadLight *uniform self = (QuadLight * uniform) super; Light_SampleRes res; // (0, 0) should sample center --> add 0.5 CranleyPatterson rotation @@ -35,10 +39,10 @@ Light_SampleRes QuadLight_sample(const uniform Light *uniform super, // sample position on light with density ppdf = 1/area // TODO: use solid angle sampling - const vec3f pos = self->position + self->edge1 * s.x + self->edge2 * s.y; + const vec3f p = pos + edge1 * s.x + edge2 * s.y; // extant light vector from the hit point - const vec3f dir = pos - dg.P; + const vec3f dir = p - dg.P; const float dist = length(dir); // normalized light vector @@ -46,8 +50,8 @@ Light_SampleRes QuadLight_sample(const uniform Light *uniform super, res.dist = dist; // convert to pdf wrt. solid angle - const float cosd = dot(self->nnormal, res.dir); - res.pdf = self->ppdf * sqr(dist) / abs(cosd); + const float cosd = dot(nnormal, res.dir); + res.pdf = ppdf * sqr(dist) / abs(cosd); // emit only to one side res.weight = cosd > 0.f ? self->radiance * rcp(res.pdf) : make_vec3f(0.f); @@ -55,39 +59,146 @@ Light_SampleRes QuadLight_sample(const uniform Light *uniform super, return res; } -Light_EvalRes QuadLight_eval(const uniform Light *uniform super, +Light_SampleRes QuadLight_sample(const Light *uniform super, + const DifferentialGeometry &dg, + const vec2f &sp, + const float) +{ + const QuadLight *uniform self = (QuadLight * uniform) super; + assert(self); + return Sample(self, + self->position, + self->edge1, + self->edge2, + self->ppdf, + self->nnormal, + dg, + sp); +} + +Light_SampleRes QuadLight_sample_instanced(const Light *uniform super, + const DifferentialGeometry &dg, + const vec2f &sp, + const float time) +{ + const QuadLight *uniform self = (QuadLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_SampleRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + + // transform light into the world space + const uniform vec3f pos = xfmPoint(xfm, self->position); + const uniform vec3f edge1 = xfmVector(xfm, self->edge1); + const uniform vec3f edge2 = xfmVector(xfm, self->edge2); + + // calculate quad normal vector + const uniform vec3f ndirection = cross(edge2, edge1); + const uniform float ppdf = rcp(length(ndirection)); // 1/area + const uniform vec3f nnormal = ndirection * ppdf; // normalize + + // sample light + res = Sample(self, pos, edge1, edge2, ppdf, nnormal, dg, sp); + } + return res; +} + +inline Light_EvalRes Eval(const QuadLight *uniform self, + const uniform vec3f &pos, + const uniform vec3f &edge1, + const uniform vec3f &edge2, + const uniform float ppdf, + const uniform vec3f &nnormal, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist) { - uniform QuadLight *uniform self = (uniform QuadLight * uniform) super; Light_EvalRes res; res.radiance = make_vec3f(0.f); // backfacing? - const float cosd = dot(self->nnormal, dir); + const float cosd = dot(nnormal, dir); // denominator = dot(cross(edge1, edge2), dir) == cosd/ppdf if (cosd <= 0.f) return res; - const vec3f c = self->position - dg.P; + const vec3f c = pos - dg.P; const vec3f r = cross(c, dir); - const float u = dot(r, self->edge1); - const float v = -dot(r, self->edge2); + const float u = dot(r, edge1); + const float v = -dot(r, edge2); // u/denominator > 1? - if (min(u, v) < 0.f | max(u, v) * self->ppdf > cosd) + if (min(u, v) < 0.f | max(u, v) * ppdf > cosd) return res; const float rcosd = rcp(cosd); - const float dist = dot(self->nnormal, c) * rcosd; + const float dist = dot(nnormal, c) * rcosd; if (dist <= minDist | dist > maxDist) return res; res.radiance = self->radiance; - res.pdf = self->ppdf * sqr(dist) * rcosd; + res.pdf = ppdf * sqr(dist) * rcosd; + + return res; +} +Light_EvalRes QuadLight_eval(const Light *uniform super, + const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const float) +{ + const QuadLight *uniform self = (QuadLight * uniform) super; + assert(self); + return Eval(self, + self->position, + self->edge1, + self->edge2, + self->ppdf, + self->nnormal, + dg, + dir, + minDist, + maxDist); +} + +Light_EvalRes QuadLight_eval_instanced(const Light *uniform super, + const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const float time) +{ + const QuadLight *uniform self = (QuadLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_EvalRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + + // transform light into the world space + const uniform vec3f pos = xfmPoint(xfm, self->position); + const uniform vec3f edge1 = xfmVector(xfm, self->edge1); + const uniform vec3f edge2 = xfmVector(xfm, self->edge2); + + // calculate quad normal vector + const uniform vec3f ndirection = cross(edge2, edge1); + const uniform float ppdf = rcp(length(ndirection)); // 1/area + const uniform vec3f nnormal = ndirection * ppdf; // normalize + + // evaluate light + res = + Eval(self, pos, edge1, edge2, ppdf, nnormal, dg, dir, minDist, maxDist); + } return res; } @@ -107,7 +218,20 @@ export void QuadLight_set(void *uniform super, self->edge1 = edge1; self->edge2 = edge2; - const uniform vec3f ndirection = cross(edge2, edge1); + // Enable dynamic runtime instancing or apply static transformation + const Instance *uniform instance = self->super.instance; + if (instance) { + if (instance->motionBlur) { + self->super.sample = QuadLight_sample_instanced; + self->super.eval = QuadLight_eval_instanced; + } else { + self->position = xfmPoint(instance->xfm, self->position); + self->edge1 = xfmVector(instance->xfm, self->edge1); + self->edge2 = xfmVector(instance->xfm, self->edge2); + } + } + + const uniform vec3f ndirection = cross(self->edge2, self->edge1); self->ppdf = rcp(length(ndirection)); // 1/area self->nnormal = ndirection * self->ppdf; // normalize } diff --git a/ospray/lights/SphericalQuadSampling.ih b/ospray/lights/SphericalQuadSampling.ih new file mode 100644 index 0000000000..b5720a5dd5 --- /dev/null +++ b/ospray/lights/SphericalQuadSampling.ih @@ -0,0 +1,222 @@ +// Copyright 2009-2021 Intel Corporation +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "Light.ih" + +struct SphericalQuad +{ + vec3f e0, e1, z; + float S, k, n0z, n0z2, n2z, x0, x1, y0, y02, y1, y12, z0, z02; +}; + +SphericalQuad SphericalQuad_create(const vec3f &q0, + const vec3f &e0, + const float e0l, + const vec3f &e1, + const float e1l, + const vec3f &n, + const vec3f &P) +{ + SphericalQuad quad; + quad.e0 = e0; + quad.e1 = e1; + quad.z = n; + + // compute rectangle coords in local reference system + vec3f d = q0 - P; + quad.z0 = dot(d, quad.z); + + // flip ’z’ to make it point against ’Q’ + quad.z = quad.z0 > 0.f ? neg(quad.z) : quad.z; + quad.z0 = -abs(quad.z0); + + quad.z02 = sqr(quad.z0); + + quad.x0 = dot(d, quad.e0); + quad.y0 = dot(d, quad.e1); + quad.y02 = sqr(quad.y0); + quad.x1 = quad.x0 + e0l; + quad.y1 = quad.y0 + e1l; + quad.y12 = sqr(quad.y1) * quad.y1; + + // create vectors to four vertices + vec3f v00 = make_vec3f(quad.x0, quad.y0, quad.z0); + vec3f v01 = make_vec3f(quad.x0, quad.y1, quad.z0); + vec3f v10 = make_vec3f(quad.x1, quad.y0, quad.z0); + vec3f v11 = make_vec3f(quad.x1, quad.y1, quad.z0); + + // compute normals to edges + vec3f n0 = normalize(cross(v00, v10)); + quad.n0z = n0.z; + quad.n0z2 = n0.z * n0.z; + vec3f n1 = normalize(cross(v10, v11)); + vec3f n2 = normalize(cross(v11, v01)); + quad.n2z = n2.z; + vec3f n3 = normalize(cross(v01, v00)); + + // compute internal angles (gamma_i) + float g0 = acos(clamp(-dot(n0, n1), -1.f, 1.f)); + float g1 = acos(clamp(-dot(n1, n2), -1.f, 1.f)); + float g2 = acos(clamp(-dot(n2, n3), -1.f, 1.f)); + float g3 = acos(clamp(-dot(n3, n0), -1.f, 1.f)); + + // compute predefined constants + quad.k = (float)two_pi - g2 - g3; + + // compute solid angle from internal angles + quad.S = max(0.f, g0 + g1 - quad.k); + + return quad; +} + +inline float sign(float x) +{ + return ((float)(0.f < x) - (float)(x < 0.f)); +} + +vec3f sampleSphericalQuad(const SphericalQuad &quad, const vec2f &s) +{ + // 1. compute ’cu’ + const float au = s.x * quad.S + quad.k; + float cosau, sinau; + sincos(au, &sinau, &cosau); + const float fu = (cosau * quad.n0z - quad.n2z) * rcp(sinau); + const float cu = clamp(rsqrt(fu * fu + sqr(quad.n0z)) * sign(fu), -1.f, 1.f); + + // 2. compute ’xu’ + const float x0 = -(cu * quad.z0) * rsqrt(1.f - cu * cu); + const float xu = clamp(x0, quad.x0, quad.x1); + + // 3. compute ’yv’ + const float ds = sqrt(sqr(xu) + sqr(quad.z0)); + const float ds2 = sqr(ds); + const float h0 = quad.y0 * rsqrt(ds2 + sqr(quad.y0)); + const float h1 = quad.y1 * rsqrt(ds2 + sqr(quad.y1)); + const float hv = s.y * (h1 - h0) + h0; + const float hv2 = sqr(hv); + const float yv = (hv2 < 1.f - 1e-4f) ? (hv * ds) * rsqrt(1.f - hv2) : quad.y1; + + // 4. transform (xu,yv,z0) to world coords + return (xu * quad.e0 + yv * quad.e1 + quad.z0 * quad.z); +} + +float solve_quadratic(float A, float B, float C) +{ + // see https://people.csail.mit.edu/bkph/articles/Quadratics.pdf + if (A == 0.f) + return -C / B; + + float rad = B * B - 4.f * A * C; + if (rad < 0.f) + return 0.f; + + rad = sqrt(rad); + float root; + if (B >= 0.f) { + root = (-B - rad) / (2.f * A); + if (root < 0.f || root > 1.f) + root = 2.f * C / (-B - rad); + } else { + root = 2.f * C / (-B + rad); + if (root < 0.f || root > 1.f) + root = (-B + rad) / (2.f * A); + } + return root; +} + +// These functions correspond to the bilinear row of table 3 in the paper +// https://diglib.eg.org/bitstream/handle/10.1111/cgf14060/v39i4pp149-158.pdf + +inline float fu(float r, float W00, float W01, float W10, float W11) +{ + const float A = W10 + W11 - W01 - W00; + const float B = 2.f * (W01 + W00); + if (A + B == 0.f) + return r; + const float C = -(W00 + W01 + W10 + W11) * r; + return solve_quadratic(A, B, C); +} + +inline float fv(float r, float u, float W00, float W01, float W10, float W11) +{ + const float A = (1.f - u) * W01 + u * W11 - (1.f - u) * W00 - u * W10; + const float B = 2.f * (1.f - u) * W00 + 2.f * u * W10; + if (A + B == 0.f) + return r; + const float C = -((1.f - u) * W01 + u * W11 + (1.f - u) * W00 + u * W10) * r; + return solve_quadratic(A, B, C); +} + +vec3f computeCosineWeightedRNG(const vec3f &q0, + const vec3f &e0, + const vec3f e1, + const vec3f &P, + const vec3f &Ng, + const vec2f &s) +{ + // code from + // https://casual-effects.com/research/Hart2020Sampling/Hart2020Sampling.pdf + vec3f wpn[4], wp[4]; + float prob[4]; + wp[0] = q0; + wp[1] = q0 + e0; + wp[2] = q0 + e1; + wp[3] = wp[1] + e1; + for (int i = 0; i < 4; i++) { + wpn[i] = normalize(wp[i] - P); + // cosine term of ray with illuminated surface + prob[i] = max(0.f, dot(wpn[i], Ng)); + } + + if ((prob[0] + prob[2]) == 0.f) { + return make_vec3f(s.x, s.y, 1.f); + } + + const float totProb = prob[0] + prob[2] + prob[1] + prob[3]; + const float u = fu(s.x, prob[0], prob[2], prob[1], prob[3]); + const float v = fv(s.y, u, prob[0], prob[2], prob[1], prob[3]); + + const float pdf = 4.f + * ((1.f - u) * (1.f - v) * prob[0] + u * (1.f - v) * prob[1] + + u * v * prob[3] + (1.f - u) * v * prob[2]) + / totProb; + + return make_vec3f(u, v, pdf); +} + +float computeCosineWeightedPDF(const vec3f &q0, + const vec3f &e0, + const vec3f e1, + const vec3f &P, + const vec3f &Ng, + const vec2f &uv) +{ + // code from + // https://casual-effects.com/research/Hart2020Sampling/Hart2020Sampling.pdf + vec3f wpn[4], wp[4]; + float prob[4]; + wp[0] = q0; + wp[1] = q0 + e0; + wp[2] = q0 + e1; + wp[3] = wp[1] + e1; + for (int i = 0; i < 4; i++) { + wpn[i] = normalize(wp[i] - P); + // cosine term of ray with illuminated surface + prob[i] = max(0.f, dot(wpn[i], Ng)); + } + + if ((prob[0] + prob[2]) == 0.f) { + return 1.f; + } + + const float totProb = prob[0] + prob[2] + prob[1] + prob[3]; + + const float pdf = 4.f + * ((1.f - uv.x) * (1.f - uv.y) * prob[0] + uv.x * (1.f - uv.y) * prob[1] + + uv.x * uv.y * prob[3] + (1.f - uv.x) * uv.y * prob[2]) + / totProb; + + return pdf; +} diff --git a/ospray/lights/SpotLight.cpp b/ospray/lights/SpotLight.cpp index 1274c0f8ff..6c3f13c74e 100644 --- a/ospray/lights/SpotLight.cpp +++ b/ospray/lights/SpotLight.cpp @@ -2,13 +2,28 @@ // SPDX-License-Identifier: Apache-2.0 #include "SpotLight.h" +#include "lights/Light_ispc.h" #include "lights/SpotLight_ispc.h" namespace ospray { -SpotLight::SpotLight() +void *SpotLight::createIE(const void *instance) const { - ispcEquivalent = ispc::SpotLight_create(); + void *ie = ispc::SpotLight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::SpotLight_set(ie, + (const ispc::vec3f &)position, + (const ispc::vec3f &)direction, + (const ispc::vec3f &)c0, + (const ispc::vec3f &)radiance, + (const ispc::vec3f &)radIntensity, + cosAngleMax, + cosAngleScale, + radius, + innerRadius, + (const ispc::vec2i &)size, + lid ? lid->data() : nullptr); + return ie; } std::string SpotLight::toString() const @@ -19,21 +34,20 @@ std::string SpotLight::toString() const void SpotLight::commit() { Light::commit(); - auto position = getParam("position", vec3f(0.f)); - auto direction = getParam("direction", vec3f(0.f, 0.f, 1.f)); - auto openingAngle = getParam("openingAngle", 180.f); - auto penumbraAngle = getParam("penumbraAngle", 5.f); - auto radius = max(0.0f, getParam("radius", 0.f)); - auto innerRadius = + position = getParam("position", vec3f(0.f)); + direction = getParam("direction", vec3f(0.f, 0.f, 1.f)); + float openingAngle = getParam("openingAngle", 180.f); + float penumbraAngle = getParam("penumbraAngle", 5.f); + radius = max(0.0f, getParam("radius", 0.f)); + innerRadius = clamp(getParam("innerRadius", 0.f), 0.0f, 0.999f * radius); // per default perpendicular to direction - vec3f c0 = std::abs(direction.x) < std::abs(direction.y) + c0 = std::abs(direction.x) < std::abs(direction.y) ? vec3f(0.0f, direction.z, direction.y) : vec3f(direction.z, 0.0f, direction.x); c0 = getParam("c0", c0); lid = getParamDataT("intensityDistribution"); - vec2i size; if (lid) { if (lid->numItems.z > 1) throw std::runtime_error(toString() @@ -58,37 +72,16 @@ void SpotLight::commit() openingAngle = clamp(openingAngle, 0.f, 360.f); penumbraAngle = clamp(penumbraAngle, 0.f, 0.5f * openingAngle); - const float cosAngleMax = std::cos(deg2rad(0.5f * openingAngle)); + cosAngleMax = std::cos(deg2rad(0.5f * openingAngle)); const float cosAngleMin = std::cos(deg2rad(0.5f * openingAngle - penumbraAngle)); - const float cosAngleScale = 1.0f / (cosAngleMin - cosAngleMax); - - linear3f frame; - frame.vz = normalize(direction); - frame.vy = normalize(cross(c0, frame.vz)); - frame.vx = cross(frame.vz, frame.vy); + cosAngleScale = 1.0f / (cosAngleMin - cosAngleMax); queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_INTENSITY); - vec3f radIntensity = 0.0f; - processIntensityQuantityType(radius, innerRadius, openingAngle, radIntensity); - - ispc::SpotLight_set(getIE(), - (const ispc::vec3f &)position, - (const ispc::LinearSpace3f &)frame, - (const ispc::vec3f &)radiance, - (const ispc::vec3f &)radIntensity, - cosAngleMax, - cosAngleScale, - radius, - innerRadius, - (const ispc::vec2i &)size, - lid ? lid->data() : nullptr); + processIntensityQuantityType(openingAngle); } -void SpotLight::processIntensityQuantityType(const float &radius, - const float &innerRadius, - const float &openingAngle, - vec3f &radIntensity) +void SpotLight::processIntensityQuantityType(const float openingAngle) { radIntensity = 0.0f; radiance = 0.0f; diff --git a/ospray/lights/SpotLight.h b/ospray/lights/SpotLight.h index d954af32c3..107b736d0a 100644 --- a/ospray/lights/SpotLight.h +++ b/ospray/lights/SpotLight.h @@ -12,19 +12,26 @@ namespace ospray { * cone of directions bounded by halfAngle */ struct OSPRAY_SDK_INTERFACE SpotLight : public Light { - SpotLight(); + SpotLight() = default; virtual ~SpotLight() override = default; + virtual void *createIE(const void *instance) const override; virtual std::string toString() const override; virtual void commit() override; private: - void processIntensityQuantityType(const float &radius, - const float &innerRadius, - const float &openingAngle, - vec3f &radIntensity); + void processIntensityQuantityType(const float openingAngle); Ref> lid; // luminous intensity distribution - vec3f radiance{1.0f, 1.0f, 1.0f}; + vec2i size{0}; + vec3f position{0.f}; + vec3f direction{0.f, 0.f, 1.f}; + vec3f c0{1.f, 0.f, 0.f}; + vec3f radiance{1.f}; + vec3f radIntensity{0.f}; + float radius{0.f}; + float innerRadius{0.f}; + float cosAngleMax{1.f}; + float cosAngleScale{1.f}; }; } // namespace ospray diff --git a/ospray/lights/SpotLight.ispc b/ospray/lights/SpotLight.ispc index 0654ffdbcc..19d3cf6374 100644 --- a/ospray/lights/SpotLight.ispc +++ b/ospray/lights/SpotLight.ispc @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "Light.ih" -#include "math/LinearSpace.ih" +#include "common/Instance.ih" #include "math/sampling.ih" struct SpotLight @@ -10,6 +10,8 @@ struct SpotLight Light super; vec3f position; // Position of the SpotLight + vec3f direction; + vec3f c0; linear3f light2world; // coordinate frame, with vz == direction that the // SpotLight is emitting linear3f world2light; @@ -31,52 +33,51 @@ struct SpotLight // Implementation ////////////////////////////////////////////////////////////////////////////// -static float SpotLight_angularAttenuation( - const SpotLight *uniform self, float cosAngle, const vec3f &dir) +inline float AngularAttenuation(const SpotLight *uniform self, float cosAngle) { - float angularAttenuation = - clamp((cosAngle - self->cosAngleMax) * self->cosAngleScale); + return clamp((cosAngle - self->cosAngleMax) * self->cosAngleScale); +} - if (self->lid) { - const vec3f localDir = self->world2light * dir; - const float u = acos(cosAngle) * self->scale.x; - const float u_frac = frac(u); - const int u0 = u; - const int u1 = (u0 + 2 >= self->size.x) ? self->size.x - 1 : u0 + 1; - - if (self->size.y == 1) { // 1D - angularAttenuation *= lerp(u_frac, self->lid[u0], self->lid[u1]); - } else { // 2D - const float v = (atan2(localDir.y, localDir.x) + pi) * self->scale.y; - const float v_frac = frac(v); - const int v0 = v; - const int v1 = (v0 + 1 >= self->size.y) ? 0 : v0 + 1; - const int r0 = v0 * self->size.x; - const int r1 = v1 * self->size.x; - const float li0 = lerp(u_frac, self->lid[r0 + u0], self->lid[r0 + u1]); - const float li1 = lerp(u_frac, self->lid[r1 + u0], self->lid[r1 + u1]); - angularAttenuation *= lerp(v_frac, li0, li1); - } - } +inline float IntensityDistr( + const SpotLight *uniform self, float cosAngle, const vec3f &localDir) +{ + const float u = acos(cosAngle) * self->scale.x; + const float u_frac = frac(u); + const int u0 = u; + const int u1 = (u0 + 2 >= self->size.x) ? self->size.x - 1 : u0 + 1; - return angularAttenuation; + float intensity; + if (self->size.y == 1) { // 1D + intensity = lerp(u_frac, self->lid[u0], self->lid[u1]); + } else { // 2D + const float v = (atan2(localDir.y, localDir.x) + pi) * self->scale.y; + const float v_frac = frac(v); + const int v0 = v; + const int v1 = (v0 + 1 >= self->size.y) ? 0 : v0 + 1; + const int r0 = v0 * self->size.x; + const int r1 = v1 * self->size.x; + const float li0 = lerp(u_frac, self->lid[r0 + u0], self->lid[r0 + u1]); + const float li1 = lerp(u_frac, self->lid[r1 + u0], self->lid[r1 + u1]); + intensity = lerp(v_frac, li0, li1); + } + return intensity; } -Light_SampleRes SpotLight_sample(const Light *uniform super, +inline Light_SampleRes Sample(const SpotLight *uniform self, + const uniform vec3f &pos, + const uniform linear3f &l2w, + const uniform linear3f &w2l, const DifferentialGeometry &dg, - const vec2f &s, - const float) + const vec2f &s) { - const SpotLight *uniform self = (SpotLight * uniform) super; Light_SampleRes res; // extant light vector from the hit point - res.dir = self->position - dg.P; + res.dir = pos - dg.P; if (self->radius > 0.) - res.dir = self->light2world - * uniformSampleRing(self->radius, self->innerRadius, s) - + res.dir; + res.dir = + l2w * uniformSampleRing(self->radius, self->innerRadius, s) + res.dir; const float dist2 = dot(res.dir, res.dir); const float invdist = rsqrt(dist2); @@ -86,76 +87,185 @@ Light_SampleRes SpotLight_sample(const Light *uniform super, res.dist = dist2 * invdist; // cosine of the negated light direction and light vector. - const float cosAngle = -dot(self->light2world.vz, res.dir); + const float cosAngle = -dot(l2w.vz, res.dir); if (self->radius > 0.) { // convert area PDF to solid angle PDF res.pdf = self->areaPdf * (dist2 / abs(cosAngle)); // calculate the attenuated emitted radiance - res.weight = - self->radiance * SpotLight_angularAttenuation(self, cosAngle, res.dir); + float attenuation = AngularAttenuation(self, cosAngle); if (!self->lid) { - res.weight = res.weight / res.pdf; + res.weight = (self->radiance * attenuation) / res.pdf; } else { // when an light distribution function is used we want to // remove the cosine term. To avoid numerical issues // at cosineAngle = 0 we use the fact that the division // of radiance with the cosine cancels out. - res.weight = res.weight / (self->areaPdf * dist2); + attenuation *= IntensityDistr(self, cosAngle, w2l * res.dir); + res.weight = (self->radiance * attenuation) / (self->areaPdf * dist2); } } else { res.pdf = inf; // we always take this sample + float attenuation = AngularAttenuation(self, cosAngle); + if (self->lid) { + attenuation *= IntensityDistr(self, cosAngle, w2l * res.dir); + } else { + // if the spotlight does not use a measured LDF we + // simulate Lambertian behavior by multiplication with cosineAngle + attenuation *= abs(cosAngle); + } // convert from intensity to radiance by attenuating by distance^2; // attenuate by angle - res.weight = self->intensity - * (sqr(invdist) - * SpotLight_angularAttenuation(self, cosAngle, res.dir)); - // if the spotlight does not use a measured LDF we - // simulate Lambertian behavior by multiplication with cosineAngle - if (!self->lid) { - res.weight = res.weight * abs(cosAngle); - } + res.weight = self->intensity * (sqr(invdist) * attenuation); } return res; } -Light_EvalRes SpotLight_eval(const uniform Light *uniform super, +Light_SampleRes SpotLight_sample(const Light *uniform super, + const DifferentialGeometry &dg, + const vec2f &s, + const float) +{ + const SpotLight *uniform self = (SpotLight * uniform) super; + assert(self); + return Sample( + self, self->position, self->light2world, self->world2light, dg, s); +} + +Light_SampleRes SpotLight_sample_instanced(const Light *uniform super, + const DifferentialGeometry &dg, + const vec2f &s, + const float time) +{ + const SpotLight *uniform self = (SpotLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_SampleRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + + // transform light into the world space + const uniform vec3f pos = xfmPoint(xfm, self->position); + const uniform vec3f dir = normalize(xfmVector(xfm, self->direction)); + const uniform vec3f c0 = normalize(xfmVector(xfm, self->c0)); + + // prepare spotlight to world transformation matrix + uniform linear3f l2w; + l2w.vz = dir; + l2w.vy = normalize(cross(c0, l2w.vz)); + l2w.vx = cross(l2w.vz, l2w.vy); + + // prepare world to spotlight transformation matrix, + // this is orthonormal transformation so transposing is enough + const uniform linear3f w2l = transposed(l2w); + + // sample light + res = Sample(self, pos, l2w, w2l, dg, s); + } + return res; +} + +inline Light_EvalRes Eval(const SpotLight *uniform self, + const uniform vec3f &position, + const uniform vec3f &direction, + const uniform linear3f &w2l, const DifferentialGeometry &dg, const vec3f &dir, const float minDist, const float maxDist) { - const SpotLight *uniform self = (SpotLight * uniform) super; Light_EvalRes res; res.radiance = make_vec3f(0.f); if (self->radius > 0.f) { // intersect ring - const float cosAngle = -dot(dir, self->light2world.vz); + const float cosAngle = -dot(dir, direction); if (cosAngle > self->cosAngleMax) { // inside illuminated cone? - const vec3f vp = dg.P - self->position; - const float t = dot(vp, self->light2world.vz) * rcp(cosAngle); + const vec3f vp = dg.P - position; + const float t = dot(vp, direction) * rcp(cosAngle); if (t > minDist & t <= maxDist) { const vec3f vd = vp + t * dir; const float d2 = dot(vd, vd); // inside ring? - if (and(d2 < sqr(self->radius), d2 > sqr(self->innerRadius))) { - // calculate the attenuated emitted radiance - res.radiance = self->radiance - * SpotLight_angularAttenuation(self, cosAngle, dir); - // since the light distribution function already includes - // the cosine term we remove it from the Lambertian area - // light + if (and(d2radius), d2> sqr(self->innerRadius))) { + float attenuation = AngularAttenuation(self, cosAngle); if (self->lid) { - res.radiance = res.radiance / abs(cosAngle); + attenuation *= IntensityDistr(self, cosAngle, w2l * dir); + + // since the light distribution function already includes + // the cosine term we remove it from the Lambertian area + // light + attenuation /= abs(cosAngle); } + + // calculate the attenuated emitted radiance + res.radiance = self->radiance * attenuation; + // convert area PDF to solid angle PDF res.pdf = self->areaPdf * (sqr(t) / abs(cosAngle)); } } } } + return res; +} + +Light_EvalRes SpotLight_eval(const Light *uniform super, + const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const float) +{ + const SpotLight *uniform self = (SpotLight * uniform) super; + assert(self); + return Eval(self, + self->position, + self->direction, + self->world2light, + dg, + dir, + minDist, + maxDist); +} + +Light_EvalRes SpotLight_eval_instanced(const Light *uniform super, + const DifferentialGeometry &dg, + const vec3f &dir, + const float minDist, + const float maxDist, + const float time) +{ + const SpotLight *uniform self = (SpotLight * uniform) super; + assert(self); + + const Instance *uniform instance = self->super.instance; + assert(instance); + + Light_EvalRes res; + foreach_unique (utime in time) { + const uniform affine3f xfm = Instance_getTransform(instance, utime); + + // transform light into the world space + const uniform vec3f position = xfmPoint(xfm, self->position); + const uniform vec3f direction = normalize(xfmVector(xfm, self->direction)); + // prepare world to spotlight transformation matrix, + // this is orthonormal transformation so transposing is enough + const uniform vec3f c0 = normalize(xfmVector(xfm, self->c0)); + const uniform vec3f vy = normalize(cross(c0, direction)); + const uniform vec3f vx = cross(direction, vy); + uniform linear3f w2l; + w2l.vx = make_vec3f(vx.x, vy.x, direction.x); + w2l.vy = make_vec3f(vx.y, vy.y, direction.y); + w2l.vz = make_vec3f(vx.z, vy.z, direction.z); + + // evaluate light + res = Eval(self, position, direction, w2l, dg, dir, minDist, maxDist); + } return res; } @@ -164,7 +274,8 @@ Light_EvalRes SpotLight_eval(const uniform Light *uniform super, export void SpotLight_set(void *uniform super, const uniform vec3f &position, - const uniform linear3f &frame, + const uniform vec3f &direction, + const uniform vec3f &c0, const uniform vec3f &radiance, const uniform vec3f &intensity, uniform float cosAngleMax, @@ -175,8 +286,28 @@ export void SpotLight_set(void *uniform super, float *uniform lid) { SpotLight *uniform self = (SpotLight * uniform) super; + self->position = position; - self->light2world = frame; + self->direction = normalize(direction); + self->c0 = normalize(c0); + + // Enable dynamic runtime instancing or apply static transformation + const Instance *uniform instance = self->super.instance; + if (instance) { + if (instance->motionBlur) { + self->super.sample = SpotLight_sample_instanced; + self->super.eval = SpotLight_eval_instanced; + } else { + self->position = xfmPoint(instance->xfm, self->position); + self->direction = normalize(xfmVector(instance->xfm, self->direction)); + self->c0 = normalize(xfmVector(instance->xfm, self->c0)); + } + } + + self->light2world.vz = self->direction; + self->light2world.vy = normalize(cross(self->c0, self->light2world.vz)); + self->light2world.vx = cross(self->light2world.vz, self->light2world.vy); + self->radiance = radiance; self->intensity = intensity; self->cosAngleMax = cosAngleMax; @@ -186,7 +317,7 @@ export void SpotLight_set(void *uniform super, self->areaPdf = uniformSampleRingPDF(radius, innerRadius); self->lid = lid; if (self->lid) { - self->world2light = rcp(frame); + self->world2light = rcp(self->light2world); self->size = size; self->scale = make_vec2f(nextafter((size.x - 1) * one_over_pi, -1.0f), nextafter(self->size.y * one_over_two_pi, -1.0f)); @@ -203,7 +334,8 @@ export void *uniform SpotLight_create() SpotLight_set(self, make_vec3f(0.f), - make_LinearSpace3f_identity(), + make_vec3f(0.f, 0.f, 1.f), + make_vec3f(0.f, 1.f, 0.f), make_vec3f(1.f), make_vec3f(1.f), 0.f, diff --git a/ospray/lights/SunSkyLight.cpp b/ospray/lights/SunSkyLight.cpp index 2499731a9a..ee12622403 100644 --- a/ospray/lights/SunSkyLight.cpp +++ b/ospray/lights/SunSkyLight.cpp @@ -11,36 +11,49 @@ #include "texture/Texture2D_ispc.h" namespace ospray { + SunSkyLight::SunSkyLight() { - ispcEquivalent = ispc::HDRILight_create(); - secondLightIE = ispc::DirectionalLight_create(); static const int skyResolution = 512; skySize = vec2i(skyResolution, skyResolution / 2); skyImage.resize(skySize.product()); static auto format = static_cast(OSP_TEXTURE_RGB32F); static auto filter = static_cast(OSP_TEXTURE_FILTER_BILINEAR); - map = (Texture2D *)ispc::Texture2D_create( + mapIE = ispc::Texture2D_create( (ispc::vec2i &)skySize, skyImage.data(), format, filter); } -std::string SunSkyLight::toString() const +SunSkyLight::~SunSkyLight() { - return "ospray::SunSkyLight"; + ispc::delete_uniform(mapIE); + ispc::HDRILight_destroyDistribution(distributionIE); } -SunSkyLight::~SunSkyLight() +void *SunSkyLight::createIE(const void *instance) const +{ + void *ie = ispc::HDRILight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::HDRILight_set(ie, + (ispc::vec3f &)coloredIntensity, + (const ispc::LinearSpace3f &)frame, + mapIE, + distributionIE); + return ie; +} + +void *SunSkyLight::createSecondIE(const void *instance) const { - ispc::HDRILight_destroy(getIE()); - ispcEquivalent = nullptr; - ispc::delete_uniform(secondLightIE); - ispc::delete_uniform(map); + void *ie = ispc::DirectionalLight_create(); + ispc::Light_set(ie, visible, (const ispc::Instance *)instance); + ispc::DirectionalLight_set( + ie, (ispc::vec3f &)solarIrradiance, (ispc::vec3f &)direction, cosAngle); + return ie; } -utility::Optional SunSkyLight::getSecondIE() +std::string SunSkyLight::toString() const { - return secondLightIE; + return "ospray::SunSkyLight"; } void SunSkyLight::commit() @@ -51,8 +64,7 @@ void SunSkyLight::commit() const float lambdaMax = 720.0f; const vec3f up = normalize(getParam("up", vec3f(0.f, 1.f, 0.f))); - vec3f direction = - -normalize(getParam("direction", vec3f(0.f, -1.f, 0.f))); + direction = -normalize(getParam("direction", vec3f(0.f, -1.f, 0.f))); const float albedo = clamp(getParam("albedo", 0.3f), 0.1f, 1.f); const float turbidity = clamp(getParam("turbidity", 3.f), 1.f, 10.f); const float horizon = @@ -62,7 +74,6 @@ void SunSkyLight::commit() queryIntensityQuantityType(OSP_INTENSITY_QUANTITY_RADIANCE); processIntensityQuantityType(); - linear3f frame; frame.vz = up; if (std::abs(sunTheta) > 0.99f) { const vec3f dx0 = vec3f(0.0f, up.z, -up.y); @@ -90,7 +101,7 @@ void SunSkyLight::commit() // using this value produces matching solar irradiance results from the model // and directional light const float angularDiameter = 0.53; - vec3f solarIrradiance = zero; + solarIrradiance = zero; // calculate solar radiance for (int i = 0; i < cieSize; ++i) { @@ -103,20 +114,13 @@ void SunSkyLight::commit() arhosekskymodelstate_free(spectralModel); - const float cosAngle = std::cos(deg2rad(0.5f * angularDiameter)); + cosAngle = std::cos(deg2rad(0.5f * angularDiameter)); const float rcpPdf = 2 * (float)pi * (1 - cosAngle); // convert solar radiance to solar irradiance solarIrradiance = xyzToRgb(solarIrradiance) * rcpPdf * intensityScale * coloredIntensity; - ispc::Light_set(getSecondIE().value(), getParam("visible", true)); - - ispc::DirectionalLight_set(getSecondIE().value(), - (ispc::vec3f &)solarIrradiance, - (ispc::vec3f &)direction, - cosAngle); - ArHosekSkyModelState *rgbModel = arhosek_rgb_skymodelstate_alloc_init(turbidity, albedo, sunElevation); @@ -157,12 +161,11 @@ void SunSkyLight::commit() skyImage[index] = max(skyRadiance, vec3f(0.0f)); } }); - - ispc::HDRILight_set(getIE(), - (ispc::vec3f &)coloredIntensity, - (const ispc::LinearSpace3f &)frame, - map); arhosekskymodelstate_free(rgbModel); + + // recreate distribution + ispc::HDRILight_destroyDistribution(distributionIE); + distributionIE = ispc::HDRILight_createDistribution(mapIE); } void SunSkyLight::processIntensityQuantityType() diff --git a/ospray/lights/SunSkyLight.h b/ospray/lights/SunSkyLight.h index 7a8ca0e59c..4e7cf4f842 100644 --- a/ospray/lights/SunSkyLight.h +++ b/ospray/lights/SunSkyLight.h @@ -8,7 +8,6 @@ #include "rkcommon/tasking/parallel_for.h" #include "sky_model/color_info.h" #include "sky_model/sky_model.h" -#include "texture/Texture2D.h" // Sun and sky environment lights // [Hosek and Wilkie 2012, "An Analytic Model for Full Spectral Sky-Dome @@ -37,17 +36,22 @@ struct OSPRAY_SDK_INTERFACE SunSkyLight : public Light { SunSkyLight(); virtual ~SunSkyLight() override; + virtual void *createIE(const void *instance = nullptr) const override; + virtual void *createSecondIE(const void *instance = nullptr) const override; virtual std::string toString() const override; virtual void commit() override; - virtual utility::Optional getSecondIE() override; private: void processIntensityQuantityType(); std::vector skyImage; - Texture2D *map{nullptr}; - void *secondLightIE; + void *mapIE{nullptr}; + void *distributionIE{nullptr}; vec2i skySize; + linear3f frame{one}; // sky orientation + vec3f direction{0.f, 0.f, 1.f}; + vec3f solarIrradiance{0.f}; + float cosAngle{1.f}; // scaling factor for values provided from model for both sun and sky to be <1 float intensityScale{0.025f}; }; diff --git a/ospray/lights/registration.cpp b/ospray/lights/registration.cpp index d0953ac907..122c19787c 100644 --- a/ospray/lights/registration.cpp +++ b/ospray/lights/registration.cpp @@ -1,7 +1,8 @@ -// Copyright 2020 Intel Corporation +// Copyright 2020-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "AmbientLight.h" +#include "CylinderLight.h" #include "DirectionalLight.h" #include "HDRILight.h" #include "PointLight.h" @@ -14,6 +15,7 @@ namespace ospray { void registerAllLights() { Light::registerType("ambient"); + Light::registerType("cylinder"); Light::registerType("distant"); Light::registerType("hdri"); Light::registerType("sphere"); diff --git a/ospray/render/Material.ih b/ospray/render/Material.ih index a3df26b2df..aea0187e40 100644 --- a/ospray/render/Material.ih +++ b/ospray/render/Material.ih @@ -8,7 +8,5 @@ /*! ISPC-side abstraction for a material. */ struct Material { - //! pointer back to the C++-equivalent of this class - void *uniform cppEquivalent; uniform MaterialType type; }; diff --git a/ospray/render/Renderer.ih b/ospray/render/Renderer.ih index 89c7eb985f..ca75c5ffb3 100644 --- a/ospray/render/Renderer.ih +++ b/ospray/render/Renderer.ih @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -69,8 +69,6 @@ struct Renderer Renderer_RenderSampleFct renderSample; Renderer_RenderTileFct renderTile; - void *cppEquivalent; - int32 spp; vec4f bgColor; // background color and alpha Texture2D *backplate; @@ -90,4 +88,4 @@ vec4f Renderer_getBackground( float Renderer_getMaxDepth( const Renderer *uniform self, const vec2f &screenPos); -void Renderer_Constructor(Renderer *uniform self, void *uniform cppE); +void Renderer_Constructor(Renderer *uniform self); diff --git a/ospray/render/Renderer.ispc b/ospray/render/Renderer.ispc index 6b98b6d05f..9989958e2c 100644 --- a/ospray/render/Renderer.ispc +++ b/ospray/render/Renderer.ispc @@ -91,9 +91,9 @@ unmasked void Renderer_default_renderTile(Renderer *uniform self, const vec2f pixelSample = make_vec2f(pixel_du, pixel_dv); vec2f pfSample = pixelSample; - if (self->pixelFilter) - { - pfSample = self->pixelFilter->sample(self->pixelFilter, pixelSample) + make_vec2f(0.5f); + if (self->pixelFilter) { + pfSample = self->pixelFilter->sample(self->pixelFilter, pixelSample) + + make_vec2f(0.5f); } screenSample.sampleID.z = startSampleID + s; @@ -146,9 +146,8 @@ export void Renderer_set(void *uniform _self, void *uniform _maxDepthTexture, void *uniform pixelFilter); -void Renderer_Constructor(Renderer *uniform self, void *uniform cppE) +void Renderer_Constructor(Renderer *uniform self) { - self->cppEquivalent = cppE; self->renderSample = Renderer_default_renderSample; self->renderTile = Renderer_default_renderTile; Renderer_set(self, 1, 20, 0.001f, make_vec4f(0.f), NULL, 0, NULL, NULL, NULL); diff --git a/ospray/render/ao/AORenderer.cpp b/ospray/render/ao/AORenderer.cpp index a8a000748c..942e9590a5 100644 --- a/ospray/render/ao/AORenderer.cpp +++ b/ospray/render/ao/AORenderer.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "AORenderer.h" @@ -8,7 +8,7 @@ namespace ospray { AORenderer::AORenderer(int defaultNumSamples) : aoSamples(defaultNumSamples) { - ispcEquivalent = ispc::AORenderer_create(this); + ispcEquivalent = ispc::AORenderer_create(); } std::string AORenderer::toString() const diff --git a/ospray/render/ao/AORenderer.ispc b/ospray/render/ao/AORenderer.ispc index 7a26c2495e..f89ad6cb70 100644 --- a/ospray/render/ao/AORenderer.ispc +++ b/ospray/render/ao/AORenderer.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "math/random.ih" @@ -108,10 +108,10 @@ void AORenderer_renderSample(Renderer *uniform _self, // AORenderer C++ interface //////////////////////////////////////////////////// -export void *uniform AORenderer_create(void *uniform cppE) +export void *uniform AORenderer_create() { uniform AORenderer *uniform self = uniform new uniform AORenderer; - Renderer_Constructor(&self->super, cppE); + Renderer_Constructor(&self->super); self->super.renderSample = AORenderer_renderSample; return self; } diff --git a/ospray/render/debug/DebugRenderer.cpp b/ospray/render/debug/DebugRenderer.cpp index 28aa5370b5..a66ba8efb5 100644 --- a/ospray/render/debug/DebugRenderer.cpp +++ b/ospray/render/debug/DebugRenderer.cpp @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 // ospray @@ -49,7 +49,7 @@ static DebugRendererType typeFromString(const std::string &name) DebugRenderer::DebugRenderer() { - ispcEquivalent = ispc::DebugRenderer_create(this); + ispcEquivalent = ispc::DebugRenderer_create(); } std::string DebugRenderer::toString() const diff --git a/ospray/render/debug/DebugRenderer.ispc b/ospray/render/debug/DebugRenderer.ispc index 7b7c735cf2..b7e039df5a 100644 --- a/ospray/render/debug/DebugRenderer.ispc +++ b/ospray/render/debug/DebugRenderer.ispc @@ -28,7 +28,7 @@ bool hitBackground( float eyeLight(varying ScreenSample &sample) { - return 0.2f + 0.8f * dot(normalize(sample.ray.Ng), neg(sample.ray.dir)); + return 0.2f + 0.8f * abs(dot(normalize(sample.ray.Ng), sample.ray.dir)); } /* a simple test-frame renderer that doesn't even trace a ray, just @@ -332,10 +332,10 @@ void DebugRenderer_volume(Renderer *uniform self, // DebugRenderer C++ interface //////////////////////////////////////////////// -export void *uniform DebugRenderer_create(void *uniform cppE) +export void *uniform DebugRenderer_create() { Renderer *uniform self = uniform new Renderer; - Renderer_Constructor(self, cppE); + Renderer_Constructor(self); self->renderSample = DebugRenderer_testFrame; return self; } diff --git a/ospray/render/pathtracer/GeometryLight.ispc b/ospray/render/pathtracer/GeometryLight.ispc index 85c062ac6d..cdf8125efa 100644 --- a/ospray/render/pathtracer/GeometryLight.ispc +++ b/ospray/render/pathtracer/GeometryLight.ispc @@ -21,15 +21,13 @@ vec3f evaluateGeometryLights(const PathContext &pathContext, vec3f L = make_vec3f(0.f); PathTraceMaterial *material = (PathTraceMaterial *)pathVertex.dg.material; foreach_unique (m in material) { - if (m != NULL - && reduce_max(m->emission) > 0.f) { + if (m != NULL && reduce_max(m->emission) > 0.f) { // at the moment we only support uniform light selection // therfore we can evaluate the selection PDF directly float lightSelectionPDF = 0.0f; - if(pathContext.numLights > 0) - { + if (pathContext.numLights > 0) { lightSelectionPDF = - (1.0f / (float)pathContext.numLights) * pathContext.numLightSamples; + (1.0f / (float)pathContext.numLights) * pathContext.numLightSamples; } // convert pdf wrt. area to pdf wrt. solid angle const float cosd = dot(pathVertex.dg.Ng, ray.dir); @@ -53,7 +51,6 @@ struct GeometryLight Light super; // inherited light fields GeometricModel *model; // underlying geometry - Instance *instance; int32 numPrimitives; // number of emissive primitives int32 *primIDs; // IDs of emissive primitives to sample float *distribution; // pdf over prims proportional to (world-space) area @@ -82,14 +79,15 @@ Light_SampleRes GeometryLight_sample(const Light *uniform super, // sample position on primitive // TODO maybe should already be done wrt. solid angle SampleAreaRes as; - if (self->instance->motionBlur) + const Instance *uniform instance = self->super.instance; + assert(instance); + if (instance->motionBlur) foreach_unique (utime in time) { - const uniform affine3f xfm = Instance_getTransform(self->instance, utime); + const uniform affine3f xfm = Instance_getTransform(instance, utime); as = geo->sampleArea(geo, primID, xfm, rcp(xfm), ns); } else { - as = geo->sampleArea( - geo, primID, self->instance->xfm, self->instance->rcp_xfm, ns); + as = geo->sampleArea(geo, primID, instance->xfm, instance->rcp_xfm, ns); } // note that sample.pdf/primitives * sampleArea(worldspace).pdf == self->pdf @@ -144,8 +142,8 @@ export void *uniform GeometryLight_create( Light_Constructor(&self->super); self->super.sample = GeometryLight_sample; self->super.eval = NULL; // geometry lights are hit and explicitly handled + self->super.instance = instance; self->model = model; - self->instance = instance; // create the list of emissive primitive IDs self->primIDs = uniform new uniform int32[geo->numPrimitives]; diff --git a/ospray/render/pathtracer/PathTracer.cpp b/ospray/render/pathtracer/PathTracer.cpp index 3df16a1d15..1a2b17a9fa 100644 --- a/ospray/render/pathtracer/PathTracer.cpp +++ b/ospray/render/pathtracer/PathTracer.cpp @@ -9,9 +9,9 @@ #include "lights/Light.h" // ispc exports #include "common/World_ispc.h" +#include "render/materials/Material_ispc.h" #include "render/pathtracer/GeometryLight_ispc.h" #include "render/pathtracer/PathTracer_ispc.h" -#include "render/materials/Material_ispc.h" // std #include @@ -19,7 +19,7 @@ namespace ospray { PathTracer::PathTracer() { - ispcEquivalent = ispc::PathTracer_create(this); + ispcEquivalent = ispc::PathTracer_create(); } std::string PathTracer::toString() const @@ -121,9 +121,27 @@ void *PathTracer::beginFrame(FrameBuffer *, World *world) if (world->lights) { for (auto &&obj : *world->lights) { - lightArray.push_back(obj->getIE()); - if (obj->getSecondIE().has_value()) - lightArray.push_back(obj->getSecondIE().value()); + lightArray.push_back(obj->createIE()); + void *secondIE = obj->createSecondIE(); + if (secondIE) + lightArray.push_back(secondIE); + } + } + + // Iterate through all world instances + if (world->instances) { + for (auto &&inst : *world->instances) { + // Skip instances without lights + if (!inst->group->lights) + continue; + + // Add instance lights to array + for (auto &&obj : *inst->group->lights) { + lightArray.push_back(obj->createIE(inst->getIE())); + void *secondIE = obj->createSecondIE(inst->getIE()); + if (secondIE) + lightArray.push_back(secondIE); + } } } diff --git a/ospray/render/pathtracer/PathTracer.ispc b/ospray/render/pathtracer/PathTracer.ispc index caeb5b7ab8..354d7f0967 100644 --- a/ospray/render/pathtracer/PathTracer.ispc +++ b/ospray/render/pathtracer/PathTracer.ispc @@ -7,9 +7,9 @@ #include "PathTracerDefines.ih" #include "PathTracerUtil.ih" +#include "lights/Light.ih" #include "render/bsdfs/BSDF.ih" #include "render/bsdfs/MicrofacetAlbedoTables.ih" -#include "lights/Light.ih" #include "render/materials/Material.ih" #include "render/materials/Medium.ih" #include "volumes/VolumeSampler.ih" @@ -217,10 +217,10 @@ export void PathTracer_set(void *uniform _self, self->shadowCatcherPlane = make_vec4f(normal * rl, shadowCatcherPlane.w * rl); } -export void *uniform PathTracer_create(void *uniform cppE) +export void *uniform PathTracer_create() { uniform PathTracer *uniform self = uniform new uniform PathTracer; - Renderer_Constructor(&self->super, cppE); + Renderer_Constructor(&self->super); self->super.renderTile = PathTracer_renderTile; PathTracer_set(self, 5, inf, make_vec4f(0.f), 1, false); @@ -230,4 +230,3 @@ export void *uniform PathTracer_create(void *uniform cppE) return self; } - diff --git a/ospray/render/pathtracer/ShadowCatcher.ispc b/ospray/render/pathtracer/ShadowCatcher.ispc index f5d4750224..12db5efd26 100644 --- a/ospray/render/pathtracer/ShadowCatcher.ispc +++ b/ospray/render/pathtracer/ShadowCatcher.ispc @@ -43,7 +43,6 @@ bool shadowCatcher(const PathContext &pathContext, vec3f shaded = make_vec3f(0.f); // illumination including shadows for (uniform int i = 0; i < pathContext.numLights; i++) { const Light *uniform light = pathContext.world->pathtracerData.lights[i]; - const vec2f s = LDSampler_getFloat2( pathContext.ldSampler, pathState.sampleDim + 4 + i * 2); Light_SampleRes ls = diff --git a/ospray/render/pathtracer/VirtualLight.ispc b/ospray/render/pathtracer/VirtualLight.ispc index cb193ab83d..0389084de1 100644 --- a/ospray/render/pathtracer/VirtualLight.ispc +++ b/ospray/render/pathtracer/VirtualLight.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "render/pathtracer/PathStructs.ih" @@ -44,6 +44,8 @@ vec3f evaluateVirtualLights(const PathContext &pathContext, box1f intervalLightDist = getMinMaxDistForVirtualLights( pathContext, pathState, lastVertex, pathVertex, ray); + const uniform float selectionPDF = rcp((uniform float)pathContext.numLights + - pathContext.world->pathtracerData.numGeoLights); for (uniform int i = pathContext.world->pathtracerData.numGeoLights; i < pathContext.numLights; i++) { @@ -57,7 +59,8 @@ vec3f evaluateVirtualLights(const PathContext &pathContext, lastVertex.dg, ray.dir, intervalLightDist.lower, - intervalLightDist.upper); + intervalLightDist.upper, + pathState.time); if (reduce_max(le.radiance) > 0.0f) { Ray shadowRay; setRay(shadowRay, @@ -81,7 +84,7 @@ vec3f evaluateVirtualLights(const PathContext &pathContext, + pathState.throughput * le.radiance * misHeuristic(pathState, lastVertex.pdf_w * T, - light->selectionPDF * pathContext.numLightSamples * le.pdf); + selectionPDF * pathContext.numLightSamples * le.pdf); } } } diff --git a/ospray/render/scivis/SciVis.cpp b/ospray/render/scivis/SciVis.cpp index 9cbedebc77..9a770a1c65 100644 --- a/ospray/render/scivis/SciVis.cpp +++ b/ospray/render/scivis/SciVis.cpp @@ -12,9 +12,65 @@ namespace ospray { +namespace { + +void addVisibleOnlyToArray( + std::vector &lightIEs, uint32_t &visibleOnly, void *lightIE) +{ + if (visibleOnly == lightIEs.size()) + lightIEs.push_back(lightIE); + else { + lightIEs.push_back(lightIEs[visibleOnly]); + lightIEs[visibleOnly] = lightIE; + } + visibleOnly++; +} + +vec3f addLightsToArray(std::vector &lightIEs, + uint32_t &visibleOnly, + Ref> &lights, + const void *instanceIE) +{ + vec3f aoColor = vec3f(0.f); + for (auto &&light : *lights) { + // create ISPC equivalent for the light + void *lightIE = light->createIE(instanceIE); + + // just extract color from ambient lights + const auto ambient = dynamic_cast(light); + if (ambient) { + addVisibleOnlyToArray(lightIEs, visibleOnly, lightIE); + aoColor += ambient->radiance; + continue; + } + + // no illumination from HDRI lights + const auto hdri = dynamic_cast(light); + if (hdri) { + addVisibleOnlyToArray(lightIEs, visibleOnly, lightIE); + continue; + } + + // sun-sky: only sun illuminates + const auto sunsky = dynamic_cast(light); + if (sunsky) { + // just sky visible + addVisibleOnlyToArray(lightIEs, visibleOnly, lightIE); + lightIEs.push_back(light->createSecondIE(instanceIE)); // sun + continue; + } + + // handle the remaining types of lights + lightIEs.push_back(lightIE); + } + return aoColor; +} + +} // namespace + SciVis::SciVis() { - ispcEquivalent = ispc::SciVis_create(this); + ispcEquivalent = ispc::SciVis_create(); } std::string SciVis::toString() const @@ -26,10 +82,9 @@ void SciVis::commit() { Renderer::commit(); - visibleLights = getParam("visibleLights", false); - ispc::SciVis_set(getIE(), getParam("shadows", false), + getParam("visibleLights", false), getParam("aoSamples", 0), getParam("aoDistance", getParam("aoRadius", 1e20f)), getParam("volumeSamplingRate", 1.f)); @@ -40,62 +95,38 @@ void *SciVis::beginFrame(FrameBuffer *, World *world) if (!world) return nullptr; - const bool visibleLightListValid = visibleLights == scannedVisibleLightList; - - if (world->scivisDataValid && visibleLightListValid) + if (world->scivisDataValid) return nullptr; std::vector lightArray; - std::vector lightVisibleArray; vec3f aoColor = vec3f(0.f); - - if (world->lights) { - for (auto &&light : *world->lights) { - // extract color from ambient lights and remove them - const auto ambient = dynamic_cast(light); - if (ambient) { - aoColor += ambient->radiance; - if (visibleLights) - lightVisibleArray.push_back(light->getIE()); - continue; - } - - // hdri lights are only (potentially) visible, no illumination - const auto hdri = dynamic_cast(light); - if (hdri) { - if (visibleLights) - lightVisibleArray.push_back(light->getIE()); - continue; - } - - // sun-sky: only sun illuminates, sky only (potentially) in background - const auto sunsky = dynamic_cast(light); - if (sunsky) { - lightArray.push_back(light->getSecondIE().value()); // sun - if (visibleLights) { - lightVisibleArray.push_back(light->getIE()); // sky - lightVisibleArray.push_back(light->getSecondIE().value()); // sun - } + uint32_t visibleOnly = 0; + + // Add lights not assigned to any instance + if (world->lights) + aoColor += + addLightsToArray(lightArray, visibleOnly, world->lights, nullptr); + + // Iterate through all world instances + if (world->instances) { + for (auto &&inst : *world->instances) { + // Skip instances without lights + if (!inst->group->lights) continue; - } - // handle the remaining types of lights - lightArray.push_back(light->getIE()); - if (visibleLights) - lightVisibleArray.push_back(light->getIE()); + // Add instance lights to array + aoColor += addLightsToArray( + lightArray, visibleOnly, inst->group->lights, inst->getIE()); } } ispc::World_setSciVisData(world->getIE(), (ispc::vec3f &)aoColor, - lightArray.empty() ? nullptr : &lightArray[0], + lightArray.empty() ? nullptr : lightArray.data(), lightArray.size(), - lightVisibleArray.empty() ? nullptr : &lightVisibleArray[0], - lightVisibleArray.size()); + visibleOnly); world->scivisDataValid = true; - scannedVisibleLightList = visibleLights; - return nullptr; } diff --git a/ospray/render/scivis/SciVis.h b/ospray/render/scivis/SciVis.h index 141eecfda6..ea25135dad 100644 --- a/ospray/render/scivis/SciVis.h +++ b/ospray/render/scivis/SciVis.h @@ -12,10 +12,6 @@ struct SciVis : public Renderer std::string toString() const override; void commit() override; void *beginFrame(FrameBuffer *, World *) override; - - private: - bool visibleLights{false}; - bool scannedVisibleLightList{true}; }; } // namespace ospray diff --git a/ospray/render/scivis/SciVis.ih b/ospray/render/scivis/SciVis.ih index 9d80633268..e3e3a7b2b6 100644 --- a/ospray/render/scivis/SciVis.ih +++ b/ospray/render/scivis/SciVis.ih @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #pragma once @@ -11,6 +11,7 @@ struct SciVis { Renderer super; bool shadowsEnabled; + bool visibleLights; int aoSamples; float aoRadius; float volumeSamplingRate; diff --git a/ospray/render/scivis/SciVis.ispc b/ospray/render/scivis/SciVis.ispc index 8782413a75..62d38d2b00 100644 --- a/ospray/render/scivis/SciVis.ispc +++ b/ospray/render/scivis/SciVis.ispc @@ -75,8 +75,10 @@ void SciVis_renderSample(Renderer *uniform _self, // Add contribution from visible lights, P is used by light // evaluation DifferentialGeometry dg; - dg.P = ray.org; - outColor = outColor + outTransmission * evaluateLights(world, dg, ray); + if (self->visibleLights) { + dg.P = ray.org; + outColor = outColor + outTransmission * evaluateLights(world, dg, ray); + } // If any geometry has been hit const bool hadHit = hadHit(ray); @@ -152,16 +154,17 @@ void SciVis_renderSample(Renderer *uniform _self, // SciVis C++ interface ///////////////////////////////////////////////////// -export void *uniform SciVis_create(void *uniform cppE) +export void *uniform SciVis_create() { uniform SciVis *uniform self = uniform new uniform SciVis; - Renderer_Constructor(&self->super, cppE); + Renderer_Constructor(&self->super); self->super.renderSample = SciVis_renderSample; return self; } export void SciVis_set(void *uniform _self, uniform bool shadowsEnabled, + uniform bool visibleLights, uniform int aoSamples, uniform float aoRadius, uniform float volumeSamplingRate) @@ -169,6 +172,7 @@ export void SciVis_set(void *uniform _self, uniform SciVis *uniform self = (uniform SciVis * uniform) _self; self->shadowsEnabled = shadowsEnabled; + self->visibleLights = visibleLights; self->aoSamples = aoSamples; self->aoRadius = aoRadius; diff --git a/ospray/render/scivis/surfaces.ispc b/ospray/render/scivis/surfaces.ispc index d058ca9841..d93bac9a9c 100644 --- a/ospray/render/scivis/surfaces.ispc +++ b/ospray/render/scivis/surfaces.ispc @@ -22,8 +22,10 @@ vec3f directIllumination(const uniform SciVis *uniform self, return color; // calculate shading for all lights - for (uniform int i = 0; i < world->scivisData.numLights; i++) { - const uniform Light *uniform l = world->scivisData.lights[i]; + for (uniform int i = world->scivisData.numLightsVisibleOnly; + i < world->scivisData.numLights; + i++) { + const Light *uniform l = world->scivisData.lights[i]; const vec2f s = make_vec2f(0.0f); // sample center of area lights const Light_SampleRes light = l->sample(l, dg, s); @@ -109,15 +111,11 @@ SSI computeShading(const SciVis *uniform self, vec3f evaluateLights( const World *uniform world, const DifferentialGeometry &dg, const Ray &ray) { - // Exit if no lights - vec3f color = make_vec3f(0.f); - if (!world->scivisData.lightsVisible) - return color; - // Iterate through all lights - for (uniform int i = 0; i < world->scivisData.numLightsVisible; i++) { + vec3f color = make_vec3f(0.f); + for (uniform int i = 0; i < world->scivisData.numLights; i++) { // Skip lights with disabled visibilty via parameter - const uniform Light *uniform l = world->scivisData.lightsVisible[i]; + const Light *uniform l = world->scivisData.lights[i]; if (!l->isVisible) continue; diff --git a/ospray/render/scivis/volumes.ispc b/ospray/render/scivis/volumes.ispc index 2416ef55e4..b7e1f5a0be 100644 --- a/ospray/render/scivis/volumes.ispc +++ b/ospray/render/scivis/volumes.ispc @@ -104,7 +104,7 @@ static void sampleVolume(SciVisRenderContext &rc, dg.material = NULL; dg.epsilon = dt / 2.f; // transform to world coords - dg.Ns = dg.Ng = normalize(xfmVector(transposed(vi.instance->xfm.l), ns)); + dg.Ns = dg.Ng = normalize(xfmVector(transposed(vi.instance->rcp_xfm.l), ns)); dg.P = ray.org + vc.distance * ray.dir; SSI shading = computeShading( rc.renderer, rc.fb, rc.world, dg, rc.sample, rc.ldSampler, ray.dir); diff --git a/ospray/volume/Volume.cpp b/ospray/volume/Volume.cpp index da6242e444..1920009a9c 100644 --- a/ospray/volume/Volume.cpp +++ b/ospray/volume/Volume.cpp @@ -24,10 +24,10 @@ Volume::Volume(const std::string &type) : vklType(type) && (vklVdbLevelNumVoxels(0) != 262144 || vklVdbLevelNumVoxels(1) != 32768 || vklVdbLevelNumVoxels(2) != 4096 || vklVdbLevelNumVoxels(3) != 512 || vklVdbLevelNumVoxels(4) != 0)) - throw std::runtime_error( - toString() + " Open VKL has non-default configuration for VDB volumes."); + throw std::runtime_error(toString() + + " Open VKL has non-default configuration for VDB volumes."); - ispcEquivalent = ispc::Volume_createInstance_vklVolume(this); + ispcEquivalent = ispc::Volume_createInstance_vklVolume(); managedObjectType = OSP_VOLUME; } @@ -160,8 +160,7 @@ void Volume::handleParams() throw std::runtime_error( toString() + " VDB leaf node data must have size n^3."); } - format.push_back( - isTile ? VKL_FORMAT_TILE : VKL_FORMAT_DENSE_ZYX); + format.push_back(isTile ? VKL_FORMAT_TILE : VKL_FORMAT_DENSE_ZYX); } VKLData vklData = vklNewData(vklDevice, format.size(), VKL_UINT, format.data()); diff --git a/ospray/volume/Volume.ih b/ospray/volume/Volume.ih index 0340621e10..69670521ca 100644 --- a/ospray/volume/Volume.ih +++ b/ospray/volume/Volume.ih @@ -18,9 +18,6 @@ struct TransferFunction; //! struct Volume { - /*! pointer to the c++-equivalent class of this entity */ - void *cppEquivalent; - int32 volumeID; VKLVolume vklVolume; @@ -42,7 +39,7 @@ struct Volume box3f boundingBox; }; -void Volume_Constructor(Volume *uniform volume, void *uniform cppEquivalent); +void Volume_Constructor(Volume *uniform volume); // Helper functions /////////////////////////////////////////////////////////// @@ -57,9 +54,12 @@ inline vec3f Volume_getGradient(const Volume *uniform volume, const vec3f &P) vklComputeGradientV(volume->vklSampler, &((const vkl_vec3f &)P)); // TODO: remove it once VKL no longer returns sporadic NaNs - if (isnan(result.x)) result.x = 1.f; - if (isnan(result.y)) result.y = 1.f; - if (isnan(result.z)) result.z = 1.f; + if (isnan(result.x)) + result.x = 1.f; + if (isnan(result.y)) + result.y = 1.f; + if (isnan(result.z)) + result.z = 1.f; return *((varying vec3f *)&result); } diff --git a/ospray/volume/Volume.ispc b/ospray/volume/Volume.ispc index 79cb9f5eb6..7f90aabd98 100644 --- a/ospray/volume/Volume.ispc +++ b/ospray/volume/Volume.ispc @@ -1,4 +1,4 @@ -// Copyright 2009-2020 Intel Corporation +// Copyright 2009-2021 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "common/Intersect.ih" @@ -65,9 +65,8 @@ unmasked void Volume_intersect_kernel( } } -void Volume_Constructor(Volume *uniform self, void *uniform cppEquivalent) +void Volume_Constructor(Volume *uniform self) { - self->cppEquivalent = cppEquivalent; self->boundingBox = make_box3f(make_vec3f(0.f), make_vec3f(1.f)); self->volumeID = -1; self->vklVolume = NULL; @@ -103,11 +102,10 @@ export void Volume_set_geomID(void *uniform _self, uniform int32 geomID) self->volumeID = geomID; } -export void *uniform Volume_createInstance_vklVolume( - void *uniform cppEquivalent) +export void *uniform Volume_createInstance_vklVolume() { Volume *uniform self = uniform new Volume; - Volume_Constructor(self, cppEquivalent); + Volume_Constructor(self); return self; } diff --git a/ospray/volume/VolumetricModel.cpp b/ospray/volume/VolumetricModel.cpp index 20f2a2b61f..119257295c 100644 --- a/ospray/volume/VolumetricModel.cpp +++ b/ospray/volume/VolumetricModel.cpp @@ -16,7 +16,7 @@ VolumetricModel::VolumetricModel(Volume *_volume) { managedObjectType = OSP_VOLUMETRIC_MODEL; volumeAPI = _volume; - this->ispcEquivalent = ispc::VolumetricModel_create(this); + this->ispcEquivalent = ispc::VolumetricModel_create(); } VolumetricModel::~VolumetricModel() diff --git a/ospray/volume/VolumetricModel.ispc b/ospray/volume/VolumetricModel.ispc index 4e99edb2a9..9deb6ca66c 100644 --- a/ospray/volume/VolumetricModel.ispc +++ b/ospray/volume/VolumetricModel.ispc @@ -7,7 +7,7 @@ #include "rkcommon/math/box.ih" #include "rkcommon/math/vec.ih" -export void *uniform VolumetricModel_create(void *uniform cppE) +export void *uniform VolumetricModel_create() { VolumetricModel *uniform self = uniform new VolumetricModel; return self; diff --git a/scripts/superbuild/CMakeLists.txt b/scripts/superbuild/CMakeLists.txt index 36252739c6..43e95ab719 100644 --- a/scripts/superbuild/CMakeLists.txt +++ b/scripts/superbuild/CMakeLists.txt @@ -14,7 +14,18 @@ if(NOT CMAKE_INSTALL_PREFIX) endif() if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the build type." FORCE) +endif() +set(CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo") +if (WIN32) + if (NOT OSPRAY_DEFAULT_CMAKE_CONFIGURATION_TYPES_SET) + set(CMAKE_CONFIGURATION_TYPES "${CONFIGURATION_TYPES}" + CACHE STRING "List of generated configurations." FORCE) + set(OSPRAY_DEFAULT_CMAKE_CONFIGURATION_TYPES_SET ON + CACHE INTERNAL "Default CMake configuration types set.") + endif() +else() + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CONFIGURATION_TYPES}) endif() if (NOT DEPENDENCIES_BUILD_TYPE) set(DEPENDENCIES_BUILD_TYPE Release) @@ -72,27 +83,27 @@ else() mark_as_advanced(FORCE ISPC_VERSION) endif() -set(RKCOMMON_VERSION "1.7.0" CACHE STRING "Which version of rkcommon to build?") -if (RKCOMMON_VERSION STREQUAL "1.7.0") - set(RKCOMMON_HASH "b2eabd1dc56fd9de7cae320711ae07696385dc3151a56b63562396d0f5e2708e") +set(RKCOMMON_VERSION "1.8.0" CACHE STRING "Which version of rkcommon to build?") +if (RKCOMMON_VERSION STREQUAL "1.8.0") + set(RKCOMMON_HASH "d9593de25a9b705d7d56f53d655c71901a25be21d88aa493d39d2d6e61ed7393") endif() option(DOWNLOAD_TBB "Download TBB or use the one found in the system environment?" ON) if (DOWNLOAD_TBB) - set(TBB_VERSION "2021.3.0" CACHE STRING "Which version of TBB to download?") + set(TBB_VERSION "2021.4.0" CACHE STRING "Which version of TBB to download?") mark_as_advanced(CLEAR TBB_VERSION) option(BUILD_TBB_FROM_SOURCE "Build TBB from source or use pre-built version?" OFF) mark_as_advanced(CLEAR BUILD_TBB_FROM_SOURCE) - if (TBB_VERSION STREQUAL "2021.3.0") + if (TBB_VERSION STREQUAL "2021.4.0") if (BUILD_TBB_FROM_SOURCE) - set(TBB_HASH "aadd36731bdc38702868303a8d08a7e34c5beb54031c99976533e2ca18d4e9ed") + set(TBB_HASH "08ade531be2e4e904eb6bec8e01da51eb3b0e4e86738128eb2722b95e3fcb5e6") else() if (APPLE) - set(TBB_HASH "1356e744c29763ee0a6de06647954eb076798c0b7a5b3c1008108d1d76cd42a5") + set(TBB_HASH "519d599939c41808d6b9170253b4c993b40d481f2c56b1a3cf390aea37ddb355") elseif (WIN32) - set(TBB_HASH "90e2055cd4be55f79eedd3d50b2010bf05d1739309c4cdd219192d129e931093") + set(TBB_HASH "3868c557739a7a5b74c985571648c066167fd7a0a8c63bdac00a6cfeeb58037f") else() - set(TBB_HASH "3b2290f3db5521901d43490a5e92a414413a8fd2feac8b4bf763dbc04ba28f63") + set(TBB_HASH "f1d26b9f3741e5d573050eef2902fcd739d2913c990f4c879a310e543fc5ffd5") endif() endif() endif() @@ -102,39 +113,39 @@ else() endif() option(BUILD_EMBREE_FROM_SOURCE "Build Embree or use pre-built version?" ON) -set(EMBREE_VERSION "3.13.1" CACHE STRING "Which version of Embree to build?") -if (EMBREE_VERSION STREQUAL "3.13.1") +set(EMBREE_VERSION "3.13.2" CACHE STRING "Which version of Embree to build?") +if (EMBREE_VERSION STREQUAL "3.13.2") if (BUILD_EMBREE_FROM_SOURCE) - set(EMBREE_HASH "51c7fd6cbef79fd49b5a7fd2a1150922a369d183ab6ce5a6845cc73d2308b33d") + set(EMBREE_HASH "eaa7a8ecd78594fb9eed75b2abbabd30dd68afb49556c250799daaeec016237c") else() if (APPLE) - set(EMBREE_HASH "1bac7a2a63798a3d04e009d93de06f39875c48c86333f8435db8ea052db2e8ea") + set(EMBREE_HASH "6e9442e516cd54c2e7f6454c90fb8cda5721d76a14d29880ffa387820a486762") elseif (WIN32) - set(EMBREE_HASH "5590ec5d4971d2c022cbb1d950f3a3b9666ec193c08b42eecf7decf5b5fd3833") + set(EMBREE_HASH "76570583a3d3e78f74b3cde2b0bbff8b0cc527959cc68b9e501b295e3aa7a960") else() - set(EMBREE_HASH "7ad9ae04124acad4c4746a9d80d54b457cf078e381383bbb482c3e25e007c70b") + set(EMBREE_HASH "8142c1fa0e8e89e279581e873f558b008a3d49b9b1e0091393e50377bcc52639") endif() endif() endif() -set(OPENVKL_VERSION "1.0.1" CACHE STRING "Which version of OpenVKL to build?") -if (OPENVKL_VERSION STREQUAL "1.0.1") - set(OPENVKL_HASH "dc37113adb7de12e503202633e54854b88dd612c3f914c1b9a5ae195c4c6c1be") +set(OPENVKL_VERSION "1.1.0" CACHE STRING "Which version of OpenVKL to build?") +if (OPENVKL_VERSION STREQUAL "1.1.0") + set(OPENVKL_HASH "2fd751f5eaa37342bd4574d3fdc0cf82e36b67646442a71c3ebe3aa859ccbc13") endif() option(BUILD_OIDN "Build OpenImageDenoise as a part of the superbuild." OFF) if (BUILD_OIDN) - set(OIDN_VERSION "1.4.1" CACHE STRING "Which version of OpenImageDenoise to build?") + set(OIDN_VERSION "1.4.2" CACHE STRING "Which version of OpenImageDenoise to build?") mark_as_advanced(CLEAR OIDN_VERSION) option(BUILD_OIDN_FROM_SOURCE "Build OpenImageDenoise or use pre-built version?" OFF) mark_as_advanced(CLEAR BUILD_OIDN_FROM_SOURCE) - if (OIDN_VERSION STREQUAL "1.4.1") + if (OIDN_VERSION STREQUAL "1.4.2") if (APPLE) - set(OIDN_HASH "0ac6b2e16ff5f1b7ff75f19e5889f291bb36d66b84446bee06ff169cfe19f265") + set(OIDN_HASH "176df94914d3bf920987f71650de05d6335f058fd631d2a5caa0e4e65f8e4fab") elseif (WIN32) - set(OIDN_HASH "4ea0492de4fc47951ab5fc53b4e3433f39677d3fbfc1541eabc4ccee82bfc4d1") + set(OIDN_HASH "5d688d60b2abb3bc2aa19a357ef2347747635c08b3fc7fb95e0abee9a2202e70") else() - set(OIDN_HASH "efdf8fafb47017d7b1b321cbc88cb1bfcbdbe2746be57ed4a2ae90431fc9eb3a") + set(OIDN_HASH "2d0eb873b79935166321df7197659e09ad5fc8a3aca3865793d12bb2b58f608f") endif() endif() else() diff --git a/scripts/tests/run_tests.ps1 b/scripts/tests/run_tests.ps1 index 32e851c81f..ea1a2ce3b9 100755 --- a/scripts/tests/run_tests.ps1 +++ b/scripts/tests/run_tests.ps1 @@ -42,6 +42,14 @@ if ( $testMPI ) { if ( $exitCode) { exit $exitCode } + + # TODO: reenable tests failing with MSVC15 + md failed-mpi-data-parallel + #mpiexec.exe -n 2 ospMPIDistribTestSuite.exe --gtest_output=xml:tests-mpi.xml --baseline-dir=regression_test_baseline\ --failed-dir=failed-mpi-data-parallel + $exitCode = $LastExitCode + if ( $exitCode) { + exit $exitCode + } } md failed diff --git a/scripts/tests/run_tests.sh b/scripts/tests/run_tests.sh index d1da509883..048b7ff840 100755 --- a/scripts/tests/run_tests.sh +++ b/scripts/tests/run_tests.sh @@ -56,7 +56,10 @@ fi if [ $TEST_MPI ]; then mkdir failed-mpi - mpiexec $MPI_ROOT_CONFIG ospTestSuite --gtest_output=xml:tests-mpi.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-mpi --osp:load-modules=mpi --osp:device=mpiOffload : $MPI_WORKER_CONFIG ospray_mpi_worker + mpiexec $MPI_ROOT_CONFIG ospTestSuite --gtest_output=xml:tests-mpi.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-mpi --osp:load-modules=mpi --osp:device=mpiOffload : $MPI_WORKER_CONFIG ospray_mpi_worker || exit 2 + + mkdir failed-mpi-data-parallel + mpiexec $MPI_ROOT_CONFIG ospMPIDistribTestSuite --gtest_output=xml:tests-mpi.xml --baseline-dir=regression_test_baseline/ --failed-dir=failed-mpi-data-parallel || exit 2 fi exit $? diff --git a/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_0.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_0.png.md5 new file mode 100644 index 0000000000..8262f30302 --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_0.png.md5 @@ -0,0 +1 @@ +73ed3d47eeac3a9b6fc673060c1c5328 diff --git a/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_1.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_1.png.md5 new file mode 100644 index 0000000000..214624f549 --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_1.png.md5 @@ -0,0 +1 @@ +4a7ebb5f6043f46912d9b1c4f35499bf diff --git a/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_2.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_2.png.md5 new file mode 100644 index 0000000000..b1c815abbb --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_2.png.md5 @@ -0,0 +1 @@ +3ea087abfcc25b0ae4c7be49462e4c78 diff --git a/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_3.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_3.png.md5 new file mode 100644 index 0000000000..a826dde4a2 --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_LightIntensityQuantity_parameter_3.png.md5 @@ -0,0 +1 @@ +e4ed1ed1f60faca8502105cbe2291a95 diff --git a/test_image_data/baseline/AVX2/CylinderLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..261446b0d6 --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +dac74a13cc7f155a14b31ad33ec9b3c4 diff --git a/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_0.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_0.png.md5 new file mode 100644 index 0000000000..bec9d5919e --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_0.png.md5 @@ -0,0 +1 @@ +11b1e39e738a027d748ed001602cf13d diff --git a/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_1.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_1.png.md5 new file mode 100644 index 0000000000..0a93d699c7 --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_1.png.md5 @@ -0,0 +1 @@ +84a7c4de39de086a654eda24ea5a141d diff --git a/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_2.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_2.png.md5 new file mode 100644 index 0000000000..8a78585b61 --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_2.png.md5 @@ -0,0 +1 @@ +0e5e30af1a3e4c3e352e2af2996697be diff --git a/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_3.png.md5 b/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_3.png.md5 new file mode 100644 index 0000000000..c6735db756 --- /dev/null +++ b/test_image_data/baseline/AVX2/CylinderLight_Light_parameter_3.png.md5 @@ -0,0 +1 @@ +a600e9c329322c20bd93995c4cf2ce9e diff --git a/test_image_data/baseline/AVX2/DistantLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX2/DistantLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..84b36bbea5 --- /dev/null +++ b/test_image_data/baseline/AVX2/DistantLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +323173a42d4f374d660cffaf5ec2df44 diff --git a/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_24.png.md5 b/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_24.png.md5 new file mode 100644 index 0000000000..7f4be74f02 --- /dev/null +++ b/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_24.png.md5 @@ -0,0 +1 @@ +ca864845643d098c79e7df59405ebc91 diff --git a/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_25.png.md5 b/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_25.png.md5 new file mode 100644 index 0000000000..f42b9b755b --- /dev/null +++ b/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_25.png.md5 @@ -0,0 +1 @@ +24108e99275920eb6abc2b4ca7f9b3f5 diff --git a/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_26.png.md5 b/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_26.png.md5 new file mode 100644 index 0000000000..3b172faee6 --- /dev/null +++ b/test_image_data/baseline/AVX2/FromOsprayTesting_TestScenesGeometry_test_scenes_26.png.md5 @@ -0,0 +1 @@ +c97734d3966425576e1c42efd57e8f95 diff --git a/test_image_data/baseline/AVX2/GeometricLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX2/GeometricLight_LightMotionBlur_parameter_0.png.md5 index 7ade94c51b..c15e554e3d 100644 --- a/test_image_data/baseline/AVX2/GeometricLight_LightMotionBlur_parameter_0.png.md5 +++ b/test_image_data/baseline/AVX2/GeometricLight_LightMotionBlur_parameter_0.png.md5 @@ -1 +1 @@ -135f6cc485cae11bf1babbb0d7140a51 +d890634b6f26ef2c69b8201c300785ec diff --git a/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_0.png.md5 b/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_0.png.md5 index ebacfc41b3..4828ec7471 100644 --- a/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_0.png.md5 +++ b/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_0.png.md5 @@ -1 +1 @@ -6da1587076f20b335b8a1c214970f13f +e3dc72cf23fd9f39a0a341016a5d4b6a diff --git a/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_1.png.md5 b/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_1.png.md5 index ebacfc41b3..4828ec7471 100644 --- a/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_1.png.md5 +++ b/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_1.png.md5 @@ -1 +1 @@ -6da1587076f20b335b8a1c214970f13f +e3dc72cf23fd9f39a0a341016a5d4b6a diff --git a/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_2.png.md5 b/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_2.png.md5 index c982fd6847..6d3f57d2ed 100644 --- a/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_2.png.md5 +++ b/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_2.png.md5 @@ -1 +1 @@ -d6c651c49940cee05be7e13ddf1e566e +bcf2e967bdc255d6007ec23237e65efd diff --git a/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_3.png.md5 b/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_3.png.md5 index c982fd6847..6d3f57d2ed 100644 --- a/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_3.png.md5 +++ b/test_image_data/baseline/AVX2/GeometricLight_Light_parameter_3.png.md5 @@ -1 +1 @@ -d6c651c49940cee05be7e13ddf1e566e +bcf2e967bdc255d6007ec23237e65efd diff --git a/test_image_data/baseline/AVX2/HDRILight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX2/HDRILight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..aec4efa934 --- /dev/null +++ b/test_image_data/baseline/AVX2/HDRILight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +f99b83596dd4831972f4488014443bfa diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_0.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_0.png.md5 new file mode 100644 index 0000000000..0138de8625 --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_0.png.md5 @@ -0,0 +1 @@ +55f2253843b2d288c21bd73e66b89792 diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_1.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_1.png.md5 new file mode 100644 index 0000000000..81c63e2a3b --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_1.png.md5 @@ -0,0 +1 @@ +2769062866a57a4734f3dd76f3a5865f diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_2.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_2.png.md5 new file mode 100644 index 0000000000..9d4b93b408 --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_2.png.md5 @@ -0,0 +1 @@ +7be3dc49b3592e7acaea42a1ed06734e diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_0.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_0.png.md5 new file mode 100644 index 0000000000..2585384572 --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_0.png.md5 @@ -0,0 +1 @@ +33ff070b3d17de5562f2cceeec947100 diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_1.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_1.png.md5 new file mode 100644 index 0000000000..7492687ce1 --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_1.png.md5 @@ -0,0 +1 @@ +fcf630625ed9a4645b6937030b802c73 diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_2.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_2.png.md5 new file mode 100644 index 0000000000..418d020948 --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_2.png.md5 @@ -0,0 +1 @@ +01b17a8669d5be94696470962fcd1389 diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_3.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_3.png.md5 new file mode 100644 index 0000000000..7a1e87a8da --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_3.png.md5 @@ -0,0 +1 @@ +c76793fe11e0bfdb7f43fd0e8999b63e diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_4.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_4.png.md5 new file mode 100644 index 0000000000..7492687ce1 --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_4.png.md5 @@ -0,0 +1 @@ +fcf630625ed9a4645b6937030b802c73 diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_5.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_5.png.md5 new file mode 100644 index 0000000000..5b4fd37fae --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_5.png.md5 @@ -0,0 +1 @@ +ce646854a5c595b1f7b009c40c256684 diff --git a/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_6.png.md5 b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_6.png.md5 new file mode 100644 index 0000000000..418d020948 --- /dev/null +++ b/test_image_data/baseline/AVX2/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_6.png.md5 @@ -0,0 +1 @@ +01b17a8669d5be94696470962fcd1389 diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_0.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_0.png.md5 new file mode 100644 index 0000000000..876da5b964 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_0.png.md5 @@ -0,0 +1 @@ +2631dd5eee3fd10a7ed5b72bfe9d7d1a diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_1.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_1.png.md5 new file mode 100644 index 0000000000..4ef5745194 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_1.png.md5 @@ -0,0 +1 @@ +d009fd188ab28d94f64be84c77ef13ed diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_2.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_2.png.md5 new file mode 100644 index 0000000000..9df5acfa4b --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_2.png.md5 @@ -0,0 +1 @@ +fba6bbfd4defc357cfc4a4948b4f1d17 diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_3.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_3.png.md5 new file mode 100644 index 0000000000..e2bcf24021 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_3.png.md5 @@ -0,0 +1 @@ +ff0f3a918ddcd3dfbfd34938b8d2398f diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_4.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_4.png.md5 new file mode 100644 index 0000000000..f4af5c9d1a --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_4.png.md5 @@ -0,0 +1 @@ +c54c3343f640605153ec4a890226cbaa diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_5.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_5.png.md5 new file mode 100644 index 0000000000..ecfbbbf642 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_5.png.md5 @@ -0,0 +1 @@ +3a94abf020f55155240075b49f79d1fc diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_6.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_6.png.md5 new file mode 100644 index 0000000000..2ea26b3f93 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_6.png.md5 @@ -0,0 +1 @@ +8ae940d22fcb9d1ad333f613ff460610 diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_7.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_7.png.md5 new file mode 100644 index 0000000000..154226e606 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraRollingShutter_instance_mb_7.png.md5 @@ -0,0 +1 @@ +821be901100abdfc3fae0b9dde745824 diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraStereoRollingShutter_instance_mb_0.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraStereoRollingShutter_instance_mb_0.png.md5 new file mode 100644 index 0000000000..d493ebe3b6 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_CameraStereoRollingShutter_instance_mb_0.png.md5 @@ -0,0 +1 @@ +23f1bfaa226bc123270d63ea041a94f3 diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5 index 513bfc1acf..3ad59da9e6 100644 --- a/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5 +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5 @@ -1 +1 @@ -45208296c4b1b92576af87b23cd7163d +74c6671a307f4994d2798f3cae4929a4 diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5 index 2861336452..b99fb5abf6 100644 --- a/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5 +++ b/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5 @@ -1 +1 @@ -4d6f3f4d075812277d085068031115fa +ec385b39810c7bdfd9bdf3bf6909fdb8 diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_test_mb_0.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_test_mb_0.png.md5 deleted file mode 100644 index b8c317dfd3..0000000000 --- a/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_test_mb_0.png.md5 +++ /dev/null @@ -1 +0,0 @@ -0f3fb585d17a98a68fc8ff92bffa136f diff --git a/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_test_mb_1.png.md5 b/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_test_mb_1.png.md5 deleted file mode 100644 index d6fb2d1a41..0000000000 --- a/test_image_data/baseline/AVX2/MotionBlurBoxes_TestMotionBlur_test_mb_1.png.md5 +++ /dev/null @@ -1 +0,0 @@ -36bcb8fdbcfaa632fea6384f6af8407b diff --git a/test_image_data/baseline/AVX2/MotionCamera_CameraStereoRollingShutter_camera_mb_0.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_CameraStereoRollingShutter_camera_mb_0.png.md5 new file mode 100644 index 0000000000..dc174ec053 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionCamera_CameraStereoRollingShutter_camera_mb_0.png.md5 @@ -0,0 +1 @@ +1ae7ba722d04dbb8c319d8018173fa1d diff --git a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_2.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_2.png.md5 index 3100c8459a..c92c89aceb 100644 --- a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_2.png.md5 +++ b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_2.png.md5 @@ -1 +1 @@ -7140a6437c7ddf9a7939f31bfd2ed11f +6f5072460b8a2d60c4081de05e422347 diff --git a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_3.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_3.png.md5 index 13828d1e4d..3100c8459a 100644 --- a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_3.png.md5 +++ b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_3.png.md5 @@ -1 +1 @@ -67559d0c14af7c4fd2cd392fc29f9b13 +7140a6437c7ddf9a7939f31bfd2ed11f diff --git a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_4.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_4.png.md5 index 9ead00837c..d55c8cb8f3 100644 --- a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_4.png.md5 +++ b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_4.png.md5 @@ -1 +1 @@ -21ca5f70a74e4209e6707f02da1896b8 +a73fc912b5de42ebaa66d13169353591 diff --git a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_5.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_5.png.md5 index 6b98b5d6d1..13828d1e4d 100644 --- a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_5.png.md5 +++ b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_5.png.md5 @@ -1 +1 @@ -2f2a9890c1cb8fd9d72689814e64ea68 +67559d0c14af7c4fd2cd392fc29f9b13 diff --git a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_6.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_6.png.md5 new file mode 100644 index 0000000000..9ead00837c --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_6.png.md5 @@ -0,0 +1 @@ +21ca5f70a74e4209e6707f02da1896b8 diff --git a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_7.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_7.png.md5 new file mode 100644 index 0000000000..ec02477bde --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_7.png.md5 @@ -0,0 +1 @@ +9d42974498897ad5936846ceb6ebafe1 diff --git a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_8.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_8.png.md5 new file mode 100644 index 0000000000..6b98b5d6d1 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_8.png.md5 @@ -0,0 +1 @@ +2f2a9890c1cb8fd9d72689814e64ea68 diff --git a/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_9.png.md5 b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_9.png.md5 new file mode 100644 index 0000000000..a384516192 --- /dev/null +++ b/test_image_data/baseline/AVX2/MotionCamera_Camera_camera_mb_9.png.md5 @@ -0,0 +1 @@ +405361d8e6cde7f8278a2466b101a990 diff --git a/test_image_data/baseline/AVX2/QuadLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX2/QuadLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..6c577085fc --- /dev/null +++ b/test_image_data/baseline/AVX2/QuadLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +c14d9428c60f7f525590d4d84bfabf02 diff --git a/test_image_data/baseline/AVX2/SphereLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX2/SphereLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..3098ee557b --- /dev/null +++ b/test_image_data/baseline/AVX2/SphereLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +eac49e507d0881385bf51e8f65e6dafa diff --git a/test_image_data/baseline/AVX2/SpotLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX2/SpotLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..b29956f846 --- /dev/null +++ b/test_image_data/baseline/AVX2/SpotLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +8a0f558e1f3e271d171bc1a63a5505bd diff --git a/test_image_data/baseline/AVX2/SunSky_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX2/SunSky_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..4ea9e76c79 --- /dev/null +++ b/test_image_data/baseline/AVX2/SunSky_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +8c5be184c4e0b903b37914cd522fe53d diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_0.png.md5 new file mode 100644 index 0000000000..8262f30302 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_0.png.md5 @@ -0,0 +1 @@ +73ed3d47eeac3a9b6fc673060c1c5328 diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_1.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_1.png.md5 new file mode 100644 index 0000000000..214624f549 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_1.png.md5 @@ -0,0 +1 @@ +4a7ebb5f6043f46912d9b1c4f35499bf diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_2.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_2.png.md5 new file mode 100644 index 0000000000..b1c815abbb --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_2.png.md5 @@ -0,0 +1 @@ +3ea087abfcc25b0ae4c7be49462e4c78 diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_3.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_3.png.md5 new file mode 100644 index 0000000000..a826dde4a2 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_LightIntensityQuantity_parameter_3.png.md5 @@ -0,0 +1 @@ +e4ed1ed1f60faca8502105cbe2291a95 diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..261446b0d6 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +dac74a13cc7f155a14b31ad33ec9b3c4 diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_0.png.md5 new file mode 100644 index 0000000000..bec9d5919e --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_0.png.md5 @@ -0,0 +1 @@ +11b1e39e738a027d748ed001602cf13d diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_1.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_1.png.md5 new file mode 100644 index 0000000000..0a93d699c7 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_1.png.md5 @@ -0,0 +1 @@ +84a7c4de39de086a654eda24ea5a141d diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_2.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_2.png.md5 new file mode 100644 index 0000000000..8a78585b61 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_2.png.md5 @@ -0,0 +1 @@ +0e5e30af1a3e4c3e352e2af2996697be diff --git a/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_3.png.md5 b/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_3.png.md5 new file mode 100644 index 0000000000..c6735db756 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/CylinderLight_Light_parameter_3.png.md5 @@ -0,0 +1 @@ +a600e9c329322c20bd93995c4cf2ce9e diff --git a/test_image_data/baseline/AVX512SKX/DistantLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/DistantLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..84b36bbea5 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/DistantLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +323173a42d4f374d660cffaf5ec2df44 diff --git a/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_24.png.md5 b/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_24.png.md5 new file mode 100644 index 0000000000..7f4be74f02 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_24.png.md5 @@ -0,0 +1 @@ +ca864845643d098c79e7df59405ebc91 diff --git a/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_25.png.md5 b/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_25.png.md5 new file mode 100644 index 0000000000..f42b9b755b --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_25.png.md5 @@ -0,0 +1 @@ +24108e99275920eb6abc2b4ca7f9b3f5 diff --git a/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_26.png.md5 b/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_26.png.md5 new file mode 100644 index 0000000000..3b172faee6 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/FromOsprayTesting_TestScenesGeometry_test_scenes_26.png.md5 @@ -0,0 +1 @@ +c97734d3966425576e1c42efd57e8f95 diff --git a/test_image_data/baseline/AVX512SKX/GeometricLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/GeometricLight_LightMotionBlur_parameter_0.png.md5 index 7ade94c51b..c15e554e3d 100644 --- a/test_image_data/baseline/AVX512SKX/GeometricLight_LightMotionBlur_parameter_0.png.md5 +++ b/test_image_data/baseline/AVX512SKX/GeometricLight_LightMotionBlur_parameter_0.png.md5 @@ -1 +1 @@ -135f6cc485cae11bf1babbb0d7140a51 +d890634b6f26ef2c69b8201c300785ec diff --git a/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_0.png.md5 index ebacfc41b3..4828ec7471 100644 --- a/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_0.png.md5 +++ b/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_0.png.md5 @@ -1 +1 @@ -6da1587076f20b335b8a1c214970f13f +e3dc72cf23fd9f39a0a341016a5d4b6a diff --git a/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_1.png.md5 b/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_1.png.md5 index ebacfc41b3..4828ec7471 100644 --- a/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_1.png.md5 +++ b/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_1.png.md5 @@ -1 +1 @@ -6da1587076f20b335b8a1c214970f13f +e3dc72cf23fd9f39a0a341016a5d4b6a diff --git a/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_2.png.md5 b/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_2.png.md5 index c982fd6847..6d3f57d2ed 100644 --- a/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_2.png.md5 +++ b/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_2.png.md5 @@ -1 +1 @@ -d6c651c49940cee05be7e13ddf1e566e +bcf2e967bdc255d6007ec23237e65efd diff --git a/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_3.png.md5 b/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_3.png.md5 index c982fd6847..6d3f57d2ed 100644 --- a/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_3.png.md5 +++ b/test_image_data/baseline/AVX512SKX/GeometricLight_Light_parameter_3.png.md5 @@ -1 +1 @@ -d6c651c49940cee05be7e13ddf1e566e +bcf2e967bdc255d6007ec23237e65efd diff --git a/test_image_data/baseline/AVX512SKX/HDRILight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/HDRILight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..aec4efa934 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/HDRILight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +f99b83596dd4831972f4488014443bfa diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_0.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_0.png.md5 new file mode 100644 index 0000000000..0138de8625 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_0.png.md5 @@ -0,0 +1 @@ +55f2253843b2d288c21bd73e66b89792 diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_1.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_1.png.md5 new file mode 100644 index 0000000000..81c63e2a3b --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_1.png.md5 @@ -0,0 +1 @@ +2769062866a57a4734f3dd76f3a5865f diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_2.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_2.png.md5 new file mode 100644 index 0000000000..9d4b93b408 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesGeometry_test_scenes_2.png.md5 @@ -0,0 +1 @@ +7be3dc49b3592e7acaea42a1ed06734e diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_0.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_0.png.md5 new file mode 100644 index 0000000000..2585384572 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_0.png.md5 @@ -0,0 +1 @@ +33ff070b3d17de5562f2cceeec947100 diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_1.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_1.png.md5 new file mode 100644 index 0000000000..7492687ce1 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_1.png.md5 @@ -0,0 +1 @@ +fcf630625ed9a4645b6937030b802c73 diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_2.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_2.png.md5 new file mode 100644 index 0000000000..418d020948 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_2.png.md5 @@ -0,0 +1 @@ +01b17a8669d5be94696470962fcd1389 diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_3.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_3.png.md5 new file mode 100644 index 0000000000..7a1e87a8da --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_3.png.md5 @@ -0,0 +1 @@ +c76793fe11e0bfdb7f43fd0e8999b63e diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_4.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_4.png.md5 new file mode 100644 index 0000000000..7492687ce1 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_4.png.md5 @@ -0,0 +1 @@ +fcf630625ed9a4645b6937030b802c73 diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_5.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_5.png.md5 new file mode 100644 index 0000000000..5b4fd37fae --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_5.png.md5 @@ -0,0 +1 @@ +ce646854a5c595b1f7b009c40c256684 diff --git a/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_6.png.md5 b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_6.png.md5 new file mode 100644 index 0000000000..418d020948 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MPIFromOsprayTesting_MPIDistribTestScenesVolumes_test_scenes_6.png.md5 @@ -0,0 +1 @@ +01b17a8669d5be94696470962fcd1389 diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_0.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_0.png.md5 new file mode 100644 index 0000000000..876da5b964 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_0.png.md5 @@ -0,0 +1 @@ +2631dd5eee3fd10a7ed5b72bfe9d7d1a diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_1.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_1.png.md5 new file mode 100644 index 0000000000..4ef5745194 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_1.png.md5 @@ -0,0 +1 @@ +d009fd188ab28d94f64be84c77ef13ed diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_2.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_2.png.md5 new file mode 100644 index 0000000000..9df5acfa4b --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_2.png.md5 @@ -0,0 +1 @@ +fba6bbfd4defc357cfc4a4948b4f1d17 diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_3.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_3.png.md5 new file mode 100644 index 0000000000..e2bcf24021 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_3.png.md5 @@ -0,0 +1 @@ +ff0f3a918ddcd3dfbfd34938b8d2398f diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_4.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_4.png.md5 new file mode 100644 index 0000000000..f4af5c9d1a --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_4.png.md5 @@ -0,0 +1 @@ +c54c3343f640605153ec4a890226cbaa diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_5.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_5.png.md5 new file mode 100644 index 0000000000..ecfbbbf642 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_5.png.md5 @@ -0,0 +1 @@ +3a94abf020f55155240075b49f79d1fc diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_6.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_6.png.md5 new file mode 100644 index 0000000000..2ea26b3f93 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_6.png.md5 @@ -0,0 +1 @@ +8ae940d22fcb9d1ad333f613ff460610 diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_7.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_7.png.md5 new file mode 100644 index 0000000000..154226e606 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraRollingShutter_instance_mb_7.png.md5 @@ -0,0 +1 @@ +821be901100abdfc3fae0b9dde745824 diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraStereoRollingShutter_instance_mb_0.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraStereoRollingShutter_instance_mb_0.png.md5 new file mode 100644 index 0000000000..d493ebe3b6 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_CameraStereoRollingShutter_instance_mb_0.png.md5 @@ -0,0 +1 @@ +23f1bfaa226bc123270d63ea041a94f3 diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5 index 513bfc1acf..3ad59da9e6 100644 --- a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5 +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_instance_mb_0.png.md5 @@ -1 +1 @@ -45208296c4b1b92576af87b23cd7163d +74c6671a307f4994d2798f3cae4929a4 diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5 index 2861336452..b99fb5abf6 100644 --- a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5 +++ b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_instance_mb_1.png.md5 @@ -1 +1 @@ -4d6f3f4d075812277d085068031115fa +ec385b39810c7bdfd9bdf3bf6909fdb8 diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_test_mb_0.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_test_mb_0.png.md5 deleted file mode 100644 index b8c317dfd3..0000000000 --- a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_test_mb_0.png.md5 +++ /dev/null @@ -1 +0,0 @@ -0f3fb585d17a98a68fc8ff92bffa136f diff --git a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_test_mb_1.png.md5 b/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_test_mb_1.png.md5 deleted file mode 100644 index d6fb2d1a41..0000000000 --- a/test_image_data/baseline/AVX512SKX/MotionBlurBoxes_TestMotionBlur_test_mb_1.png.md5 +++ /dev/null @@ -1 +0,0 @@ -36bcb8fdbcfaa632fea6384f6af8407b diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_CameraStereoRollingShutter_camera_mb_0.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_CameraStereoRollingShutter_camera_mb_0.png.md5 new file mode 100644 index 0000000000..dc174ec053 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_CameraStereoRollingShutter_camera_mb_0.png.md5 @@ -0,0 +1 @@ +1ae7ba722d04dbb8c319d8018173fa1d diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_2.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_2.png.md5 index 3100c8459a..c92c89aceb 100644 --- a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_2.png.md5 +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_2.png.md5 @@ -1 +1 @@ -7140a6437c7ddf9a7939f31bfd2ed11f +6f5072460b8a2d60c4081de05e422347 diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_3.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_3.png.md5 index 13828d1e4d..3100c8459a 100644 --- a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_3.png.md5 +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_3.png.md5 @@ -1 +1 @@ -67559d0c14af7c4fd2cd392fc29f9b13 +7140a6437c7ddf9a7939f31bfd2ed11f diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_4.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_4.png.md5 index 9ead00837c..d55c8cb8f3 100644 --- a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_4.png.md5 +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_4.png.md5 @@ -1 +1 @@ -21ca5f70a74e4209e6707f02da1896b8 +a73fc912b5de42ebaa66d13169353591 diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_5.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_5.png.md5 index 6b98b5d6d1..13828d1e4d 100644 --- a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_5.png.md5 +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_5.png.md5 @@ -1 +1 @@ -2f2a9890c1cb8fd9d72689814e64ea68 +67559d0c14af7c4fd2cd392fc29f9b13 diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_6.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_6.png.md5 new file mode 100644 index 0000000000..9ead00837c --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_6.png.md5 @@ -0,0 +1 @@ +21ca5f70a74e4209e6707f02da1896b8 diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_7.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_7.png.md5 new file mode 100644 index 0000000000..ec02477bde --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_7.png.md5 @@ -0,0 +1 @@ +9d42974498897ad5936846ceb6ebafe1 diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_8.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_8.png.md5 new file mode 100644 index 0000000000..6b98b5d6d1 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_8.png.md5 @@ -0,0 +1 @@ +2f2a9890c1cb8fd9d72689814e64ea68 diff --git a/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_9.png.md5 b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_9.png.md5 new file mode 100644 index 0000000000..a384516192 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/MotionCamera_Camera_camera_mb_9.png.md5 @@ -0,0 +1 @@ +405361d8e6cde7f8278a2466b101a990 diff --git a/test_image_data/baseline/AVX512SKX/QuadLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/QuadLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..6c577085fc --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/QuadLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +c14d9428c60f7f525590d4d84bfabf02 diff --git a/test_image_data/baseline/AVX512SKX/SphereLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/SphereLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..3098ee557b --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/SphereLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +eac49e507d0881385bf51e8f65e6dafa diff --git a/test_image_data/baseline/AVX512SKX/SpotLight_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/SpotLight_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..b29956f846 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/SpotLight_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +8a0f558e1f3e271d171bc1a63a5505bd diff --git a/test_image_data/baseline/AVX512SKX/SunSky_LightMotionBlur_parameter_0.png.md5 b/test_image_data/baseline/AVX512SKX/SunSky_LightMotionBlur_parameter_0.png.md5 new file mode 100644 index 0000000000..4ea9e76c79 --- /dev/null +++ b/test_image_data/baseline/AVX512SKX/SunSky_LightMotionBlur_parameter_0.png.md5 @@ -0,0 +1 @@ +8c5be184c4e0b903b37914cd522fe53d